Pixiv:torino
作用:设置盒子是否可见
属性值 | 说明 |
---|---|
visible | 默认,可见 |
hidden | 不可见,但依然占位 |
collapse | 专门用于表格元素,若在其他元素使用则视为hidden 可以删除表格某一行/列,但不会影响布局 |
inherit | 略 |
作用:盒子的定位
属性值 | 说明 |
---|---|
static | 默认,正常情况无定位,不会受top、right、bottom、left影响 |
fixed | 固定定位,即使滚动浏览器依然展现在固定位置 |
relative | 相对其原本正常位置定位 |
absolute | 相对上一级父元素定位 |
initial | 浏览器的默认值,比如文字颜色默认为black,可以通过此来设置 任何属性值可以填此关键字,比如此时position的initial为static |
inherit | 略 |
作用:当使用定位后很可能会发生重叠,此时可以通过z-index属性设定重叠时显示的等级,较低等级的会被较高等级的覆盖
属性值 | 说明 |
---|---|
auto | 默认,显示等级与父元素一致 |
数字 | 设定显示等级 |
inherit | 略 |
作用:当启用相对定位后,会根据其相对的参考位置进行偏移,比如absolute会参考父元素,fixed会参考自身原本位置
注:在设定时水平方向或垂直方向只能设置一个,比如设置了bottom就不能设置top
属性值 | 说明 |
---|---|
auto | 默认 |
长度单位 | 略,会向里偏移,比如设定right实际上是从最右边向里偏移多少,其他类似 |
inherit | 略 |
作用:非常有意思的属性,定义当鼠标指针放置于元素范围内时的光标
根据系统指针的命名,大体分为如下
【【】】
【【】】
【【】】
属性值 | 说明 |
---|---|
url(...) | 自定义光标,只要指定url 在某些网站可以看到有其特殊光标就是这么做的 |
auto | 默认情况,根据浏览器默认值设定 |
default | 正常选择 |
crosshair | 精确选择 |
pointer | 链接选择 |
move | 移动 |
e-resize | 水平调整大小 |
w-resize | 水平调整大小 |
n-resize | 垂直调整大小 |
s-resize | 垂直调整大小 |
ne-resize | 沿对角线调整大小2 |
nw-resize | 沿对角线调整大小1 |
se-resize | 沿对角线调整大小1 |
sw-resize | 沿对角线调整大小2 |
text | 文本选择 |
wait | 忙 |
help | 帮助选择 |
progress | 后台运行 |
none | 无指针 |
not-allowed/no-drop | 不可用 |
还有一些并不在操作系统之中,具体可参考MDN
作用:当position不为绝对定位时可用,周围一切元素都会尽量(如果空间足够)左右移动且围着float元素
注:clear用于清除从此标签开始之前的浮动,但是之前的浮动效果依然保留。也就是说存在一个顺序问题,之前已发生的float效果不会受到影响,但之后可能会因为float产生的效果会发生变化
float属性值 | 说明 |
---|---|
none | 默认,不浮动 |
left | 左浮动 |
right | 右浮动 |
inherit | 略 |
clear属性值 | 说明 |
---|---|
none | 默认,允许两边浮动 |
left | 禁止左浮动 |
right | 禁止右浮动 |
both | 禁止两边浮动 |
inherit | 略 |
要让多个块级元素横向排列,可以通过浮动一次性的解决
浮动的元素会脱离标准流(脱标),会根据父元素在最上面根据float设定来填充(不需要考虑高度且盒子之间无缝隙),若宽度不够会自动换行(包括放大缩小网页导致的宽度变化)
浮动的盒子和标准流的盒子需要看成两块内容,浮动会从当前元素开始影响后续的的所有同级的标准流的盒子(不会影响同级的前面的标准流盒子,也不会影响其他级别的,尽管效果上影响了子级的盒子!!!)
一般情况来说,float所处的级别其他一切元素都会设置成float,虽然听上去更像是一个规范,但确实只要同级没有标准流直接从源头遏制问题的发生
还有一种情况,如果本身要求产生重叠的效果,可以z-index设置重叠的顺序
高度塌陷问题只会出现父元素无法设定的情况
为什么父元素无法设定?比如我写的blog文章长短不一,故此高度也不同,在这种情况下高度是无法确定的,但无法确定的情况下如果直接用了就有问题了
<div class="father"> <div class="son1">1</div> <div class="son2">2</div> </div> <div class="other"></div> <style> .father { background-color: black; width: 700px; margin-bottom: 20px; /* 无法确定father高度需要根据子元素确定 */ } .son1, .son2 { float: left; background-color: grey; width: 300px; height: 200px; margin: 10px; } .other { background-color: brown; width: 100%; height: 50px; margin-top: 10px; } </style>
比如上述代码,可以清楚地看到other盒子跑上来了,因为father盒子没确定高度的情况下,float不占位导致father盒子高度为0。
在解决这个方法前需要先了解BFC(Block Formatting Context)块格式化上下文的概念。高度塌陷以及之前所述的margin合并本质上是BFC的问题
在正常情况下如果一个元素只有浮动元素,由于没有标准流的存在,实际的内容高度为0。设定高度只是在形式上解决问题,并不能改变其下内容因为都是浮动元素高度为0的事实
BFC是block类型盒子布局中发生的区域,也是浮动元素与其他元素交互的区域
float不会影响其他BFC元素的布局,因此可以说明高度塌陷问题的产生来源。父元素不指定height高度的情况下为auto,即与子元素的height有关,但float不会影响BFC元素。因此在内部可以认为根本没有元素,所以auto自然会设定为0px。
在之前提出clear后解决方法便已经有了,只要让浮动效果依然保留,清除后续对父元素产生的影响即可
<div class="father"> <div class="son1">1</div> <div class="son2">2</div> <div style="clear: both;"></div> <!-- 清除此级所有float 但之前的float效果依然保留 因此视觉效果上解决了问题--> <!-- <p style="float: right;">123456</p> 再添加浮动的标签会发现依然出现高度塌陷问题 由此证明了clear只会清除之前的float--> </div> <div class="other"></div>
还有一种解决方法是针对于父元素的,只要父元素其下所有浮动元素也能像正常元素一样被计算在内即可。即要让父元素赋予BFC让其下所有子元素也是BFC的
我在下面说明了所有BFC产生的情况,我认为最好的方案是inside设置为flow-root产生一个没有任何效果的BFC,还有些诸如设定overflow等本质上都是用于生成BFC从而对其子元素产生布局影响
.father { background-color: black; width: 700px; margin-bottom: 20px; display: flow-root; /*用于产生无效果的BFC 哪怕之后改成flex、grid依然具有BFC*/ }
这里所述都是BFC本身对其下子元素产生的影响
■html根元素便是一个BFC
■float不为none
■position设为absolute、fixed
■display的inside值设为flow-root或是其他如table、column等
■display定为flex模型或grid模型
■overlow不为visible
■contain设为layout、content、paint
<style> /*这里说明float生成BFC对其下float的影响*/ /*结果显示float产生BFC从而不会出现高度塌陷的问题*/ .father { background-color: black; width: 80px; float: left; /*具有float高度没有说明的父元素*/ } .son { background-color: grey; float: left; height: 20px; width: 20px; } </style> <div class="father"> <div class="son">1</div> <div class="son">2</div> <div class="son">3</div> </div>
外边距塌陷问题本质来源于父元素没触发BFC,那么加个flow-root试试?
加BFC是让子元素产生独立的空间,让父元素的空间与子元素空间错开
<style> * { margin: 0px; padding: 0px; } .father { background-color: aqua; width: 500px; height: 300px; /* display: flow-root; */ } .first { width: 400px; height: 200px; /* margin-bottom: 50px; */ background: purple; } .second { width: 400px; height: 200px; /* margin-top: 100px; */ background: green; } </style> <body> <div class="father"> <div class="first"></div> </div> <div class="father"> <div class="second"></div> </div> </body>
代码和上面一样,假设不解决外边距塌陷问题,如何解决外边距合并问题?
本质上也是加上BFC,嵌套一个空的只有BFC效果的父元素, 让子元素之间的空间是错开的,从而达到之间的外边距是错开的不会进行合并。
但我不推荐这样做,不如作为特性不去解决这个问题
<style> * { margin: 0px; padding: 0px; } .father { /* display: flow-root; */ /* 套一个空的BFC */ } .first { width: 400px; height: 200px; margin-bottom: 50px; background: purple; } .second { width: 400px; height: 200px; margin-top: 100px; background: green; } </style> <body> <div class="father"> <div class="first"></div> </div> <div class="father"> <div class="second"></div> </div> </body>
盒子模型中还有一个属性,display但因为稍复杂因此单独拎出来说明
display分为六类:outside、inside、listitem、internal、box、legacy
指定外部显示方式,即流式布局的方式
属性值 | 说明 |
---|---|
block | 块级元素 |
inline | 行内元素 |
指定内部显示方式,即如何影响其他元素的布局而不是针对自身元素的布局
属性值 | 说明 |
---|---|
table | 可以理解为定义了一个table块级框 |
flow-root | 创建BFC |
flex | 后续会着重说明 |
grid | 后续会着重说明 |
属性值只有listitem,可以简单理解为就是变成列表项的形式
internal是针对于inside中复杂的情况,如table(ruby在此不做说明)
属性值 | 说明 |
---|---|
table-row-group | 参考tbody |
table-header-group | 参考thead |
table-footer-group | 参考tfoot |
table-row | 参考tr |
table-ceil | 参考td |
table-column-group | 参考colgroup |
table-column | 参考col |
table-caption | 参考caption |
用于定义如何不显示的问题
属性值 | 说明 |
---|---|
none | 包括其子元素均不显示 |
contents | 只有此元素不显示,其下的子元素依然可以显示 |
对于display来说可以采用二值语法,即某一个盒子可以同时设置outside和inside
此外legacy采用了语法糖的形式可以使用单个属性值代替二值语法(因为有相当多的浏览器不支持二值语法),在考虑display时应当更加详细的考虑需要哪一个outside需要哪一个inside
legacy属性值 | 等价效果 |
---|---|
block | block flow |
flow-root | block flow-root |
inline | inline flow |
inline-block | inline flow-root |
flex | block flex |
inline-flex | inline flex |
grid | block grid |
inline-grid | inline grid |
这里简单说明inline-block,比如这里展示效果就是外部inline,内部由于flow-root会影响浮动的参考
<style> .container { margin: 10px; width: 200px; height: 200px; background-color: grey; display: inline-block; /*等价于inline flow-root*/ } .item { background-color: bisque; margin: 10px; float: left; } </style> <body> <div class="container"> <div class="item">Floated</div> <p>Text following the float.</p> </div> <div class="container"> <div class="item">Floated</div> <p>Text following the float.</p> </div> <div class="container"> <div class="item">Floated</div> <p>Text following the float.</p> </div> </body>
二值语法的兼容性
所以推荐legacy
【【】】
流式布局、浮动布局、定位布局是最基础的三种布局方式,但CSS还提供其他布局方式,首先是Flex也是特别常用的布局方式。因为经常会遇到匀称对齐的布局要求,不管是flex还是grid都是为了对齐。
在display的inside属性中有一felx属性值,这便是弹性盒子,在设定好display: flex;后可以使用felx相关的属性
Flexible Box模型是CSS提供的一种一维布局模型,其在空间分布、对齐能力上极为出色。之所以是一维布局因为只能处理一行或一列,还有另外一种Grid则是二维布局模型,可以同时处理行列
此外flex特别重要的一点是伸缩性,简单来说就是会根据不同的盒子大小来自动伸缩元素大小
主轴通过felx-direction定义,是最基本的属性
flex-direction属性值 | 说明 |
---|---|
row | 默认,水平左到右 |
row-reverse | 水平右到左 |
column | 垂直上到下 |
column-reverse | 垂直下到上 |
选择row则会是水平类似于inline的方式布局,column则是垂直类似于block的方式布局。若附带reverse则可以逆向排列
所谓交叉轴则是指垂直于主轴的方向,交叉轴不再分有没有reverse因为不需要
<style> div { display: flex; /*创建flex容器*/ flex-direction: column-reverse; /*如设定了此,则所有元素会从下到上排列*/ } </style> <div id="main"> <div style="background-color:coral;">A</div> <div style="background-color:lightblue;">B</div> <div style="background-color:khaki;">C</div> <div style="background-color:pink;">D</div> <div style="background-color:lightgrey;">E</div> <div style="background-color:lightgreen;">F</div> </div>
display设定为flex,则此区域称为【flex容器】
flex容器中的直系子元素则称为【flex元素】
交叉轴体现在另外一个属性flex-wrap,用于指定是否会换行,换行会根据交叉轴方向换行。如果不换行,即可能在主轴一维发生溢出
但设置为nowrap也是也可能发生溢出的。如果换行发生很多次超出了交叉轴一维的长度,也会溢出
注:溢出的处理参考overflow,flex-wrap只能保证主轴不会溢出(若容器主轴上的长度小于元素在主轴上的长度依然会溢出)
flex-wrap属性值 | 说明 |
---|---|
nowrap | 默认,不换行 |
wrap | 换行 |
当然还提供了复合属性flex-flow用于同时设定flex-direction和flex-wrap
<style> div { display: flex; width: 100px; height: 100px; flex-flow: column-reverse wrap; /*保证主轴方向不会溢出*/ /*无法保证交叉轴方向不溢出,如本例水平方向会溢出*/ } div div{ width: 30px; height: 30px; } </style> <div id="main"> <div style="background-color:coral;">A</div> <div style="background-color:lightblue;">B</div> <div style="background-color:khaki;">C</div> <div style="background-color:pink;">D</div> <div style="background-color:lightgrey;">E</div> <div style="background-color:lightgreen;">F</div> <div style="background-color:coral;">A</div> <div style="background-color:lightblue;">B</div> <div style="background-color:khaki;">C</div> <div style="background-color:pink;">D</div> <div style="background-color:lightgrey;">E</div> <div style="background-color:lightgreen;">F</div> <div style="background-color:coral;">A</div> <div style="background-color:lightblue;">B</div> <div style="background-color:khaki;">C</div> <div style="background-color:pink;">D</div> <div style="background-color:lightgrey;">E</div> <div style="background-color:lightgreen;">F</div> <div style="background-color:coral;">A</div> <div style="background-color:lightblue;">B</div> <div style="background-color:khaki;">C</div> <div style="background-color:pink;">D</div> <div style="background-color:lightgrey;">E</div> <div style="background-color:lightgreen;">F</div> </div>
flex-direction、flex-wrap只是宏观地控制维度上的顺序,但并不能具体地控制绘制顺序
<style> .box { display: flex; flex-direction: row; } .box :nth-child(5) { order: 1; } .box :nth-child(3) { order: 1; } .box :nth-child(1) { order: 2; } .box :nth-child(2) { order: 3; } .box :nth-child(4) { order: 3; } </style> <div class="box"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </div>
如此例会优先绘制order=1的,与CSS代码顺序无关,只看HTML元素的顺序,即先绘制3再绘制5。然后绘制order=2的,即绘制1,然后再绘制2、4
在某些情况下可以根据需求来强调某一flex元素
order处理的是逻辑顺序,而flex-direction处理的是视觉顺序。虽然在部分情况下两者处理的顺序是重叠的即用两种方法都能处理,但仍有一部分情况逻辑顺序与视觉顺序是分离的,此时order就有必要使用了
在flex设定好主轴方向后,比如row那么起始点start就在左侧,终点end在右侧。column-reverse起始点在下侧,终点在上侧
可以通过justify-content设置主轴方向的排列,align-content设置垂直方向的排列
justify-content/align-content属性值 | 说明 |
---|---|
flex-start | justify-conteng默认,位于容器起始点 |
flex-end | 位于容器终点 |
center | 位于中央 |
space-between | 对齐,元素之间留白,两侧无留白 |
space-around | 对齐,元素之间,两侧均留白 |
stretch | align-content特有的默认的属性值,交叉轴上元素会自动拉伸以适应flex容器 |
对于flex-start、flex-end、center盒子之间是紧密邻接的,如果设定space-xxx会根据实际窗口大小进行对齐,其中between会某一轴两侧的元素会紧贴,而around会留白
通过这两条属性可以快速地完成元素对齐,而不是设定float和margin来确定对齐方式
然后考虑容器中的元素,最基本的有三个属性对元素进行具体地设定
【元素空间】是指元素占用的width、height大小,所有元素空间以外的在flex容器中的空间称为【可用空间】
在设定对齐时留白部分会根据可用空间自动设定
其中flex-basis用于设定主轴的占据的空间大小
flex-basis属性值 | 说明 |
---|---|
auto | 默认,根据容器自动生成(一般是铺满) |
长度单位 | 略 |
设定了元素空间后,还有一个方面可用空间。flex-grow、flex-shrink用于设定如何使用可用空间,尤其是主轴长度不定(在下面章节会说明这种情况)时即可用空间不定时如何处理。
flex-grow说明了在可用空间存在的情况下,如何按比例伸长分配主轴上的空间
flex-shrink说明了在没有可用空间即容器没有足够空间容纳下元素的情况下,即溢出时如何收缩以保证不会溢出
这两个属性均是按照flex-basis按比例伸缩
比如要设定元素大小在主轴上是2:1:1的,在有可用空间的情况可以设定flex-grow分别为2:1:1,在无可用空间的情况可以设定flex-shrink分别为1:1.5:1.5
flex-grow/flex-shrink属性值 | 说明 |
---|---|
长度单位 | 默认0即不伸缩,略 |
此外可以使用flex复合属性进行设置,顺序为flex-grow→flex-shrink→flex-basis
flex属性值 | 说明 |
---|---|
none | 默认,0 0 auto |
auto | 1 1 auto |
x y z | 略 |
flex属性体现了flex模型的伸缩特点,可以根据具体不同的情况来进行保持,比如电脑浏览器屏幕和实际屏幕宽度就不同,这时候可以使用flex来自适应屏幕大小
此外还比如隐藏一些flex元素,浏览器会因此而重新排列以保证其布局的结构
align-content设定的是总体的关于交叉轴的排列方式,此外还有两个设置交叉轴的排列方式的属性
align-items设定的是交叉轴的排列方式,与align-content的区别是align-content针对是总体的排列,而align-items针对的是多个不同交叉轴的排列
在具体处理上也稍有不同,比如元素在交叉轴上的长度并不一定相等。align-content会视为同一高度,而align-items则不会
align-self则会具体的详细到哪一个flex元素,align-self可以覆盖align-items
通过这些可以为布局提供更高的灵活性
align-items/align-self属性值 | 说明 |
---|---|
auto | 默认,继承父元素,若父元素未指定则为stretch |
stretch | 拉伸自适应flex容器 |
center | 略 |
flex-start | 略 |
flex-end | 略 |
baseline | 位于容器基线上 |
Grid类似于html的表格,能够按行/列对齐元素,但网格比表格要更加简单
Flex可以完成的Grid当然也能完成,可以解决大部分的布局问题。功能丰富也意味着更加复杂,学习起来要更麻烦
案例——可以查看这个网站上关于grid布局的案例,可以实现很多以往布局包括flex很难实现的不可思议的效果
小游戏——像另外一个玩选择器游戏的网站通过游戏来学习grid
A Complete Guide to Grid
CSS Grid Starter Layouts
Getting Started with CSS Grid
网格(Grid)
网格轴(Grid Axis):网格是二维布局方法,分为横轴和纵轴
网格单元格(Grid Cell):是网格的最小单元
【【】】
网格线(Grid Lines):区分网格的辅助线
【【】】
网格轨道(Grid Tracks):是指相邻网格线之间的空间
【【】】
网格行(Grid Row):网格的水平轨道
网格列(Grid Column):网格的垂直轨道
网格区域(Grid Areas):由网格单元格构成的矩形区域
【【】】
网格间距(Gutters):网格轨道之间的间距
在此灵活运用网格之前,需要创建网格
CSS提供了这些属性创建
grid-template-rows、grid-template-columns
用来创建轨道和网格线
其中参数数量是不限定的,有几个数量就代表创建几行几列,比如下面的例子创建了4行3列的网格
div{ display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr 1fr; /*fr是CSS的长度单位,grid经常用到*/ }
在创建网格轨道的同时也同时创建了网格线,网格线可以用F12看到。如此例创建了5个水平4个垂直的网格线,网格线默认是从1开始的
属性值 | 说明 |
---|---|
none | 默认,由隐式属性grid-auto-rows/columns生成 |
长度单位 | 略 备注:fr是flex类型的长度单位即具有伸缩性 |
【【】】
根据上图可以看到网格线
/*@font-face { font-family: font1; src: url("华康少女文字 - Kelvin.ttf"); }* {font: 18px font1;}*/ #grid { display: grid; width: 100%; height: 300px; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr 1fr 1fr; /*生成4行2列的网格*/ } .c1 { background: red; } .c2 { background: palegreen; } .c3 { background: skyblue; } .c4 { background: plum; }
上述属性除了基本的创建网格轨道、网格线还可以对网格轨道进行命名
1.不同轨道的名字是可以相同的,没有硬性规定
2.同一轨道可以有多个名字
3.对于重复部分,可以简单用repeat()函数
#grid { display: grid; width: 100%; height: 300px; grid-template-columns: repeat(2,1fr [c]); /*创建2条名字都是c的轨道*/ grid-template-rows: [r1 r2] 1fr [r2] 1fr [r3] 1fr [r4] 1fr; /*第一条轨道名字有r1和r2*/ }
通过grid-template-areas和grid-area可以创建网格区域,用于合并多个单元格以完成更加灵活的布局
需要先使用grid-area设定网格区域
然后使用grid-template-areas设定布局方式
其中grid-template-areas用一组字符串来表示结构,其中在某一字符串上的元素必须相连,否则会出bug
可以用.
表示空的单元格即无内容
<style> .grid { display: grid; grid-template-columns: 1fr 2fr 1fr; grid-template-rows: repeat(3, 1fr); grid-template-areas: "a1 a1 a1" "a2 a3 a4" "a5 a5 a5"; /*可以尝试这一组"a1 a1 ." ". . a5" "a2 a3 a4"*/ /*这种布局像填表游戏一样,但效果确是非常强大的*/ grid-gap: 1em; } header, aside, article, footer { background: grey; height: 100px; text-align: center; } header { grid-area: a1; } .sidebar-left { grid-area: a2; } article { grid-area: a3; } .sidebar-right { grid-area: a4; } footer { grid-area: a5; } </style> <div class="grid"> <header>Header</header> <aside class="sidebar-left">Left Sidebar</aside> <article>Article</article> <aside class="sidebar-right">Right Sidebar</aside> <footer>Footer</footer> </div>
复合属性,顺序:
grid-template-rows→grid-template-columns
其中子属性之间用/
隔开,如
.grid { display: grid; grid-template 1fr 2fr 1fr / repeat(3,1fr); }
此外网格与网格之间可以设置间距
总共有两个属性:
row-gap、column-gap
grid-row-gap、grid-column-gap
带有grid前缀的功能一样,但为了保证兼容性有时可能仍然需要带前缀的
row-gap: 10px; /*设置网格水平方向上间距10px*/ column-gap: 50px; /*设置网格垂直方向上间距50px*/
备注:需要注意的是不会在外边缘创建,只会定义内部的间隙(参考flex中space-between和space-around的区别)
复合属性,顺序:
row-gap、column-gap
备注:grid
w3cschool
MDN CSS
HTML.net CSS
CSS specifishity
grid布局案例
grid小游戏
A Complete Guide to Grid
CSS Grid Starter Layouts
Getting Started with CSS Grid