CSS布局是指在页面中对元素的排列和定位。通过在HTML中使用CSS使得元素的编排更结构化。
CSS提供了多种布局技术,如:normal flow、flexbox、grid、floats。一般通过元素的display
属性来设置布局。
正常布局流(normal flow):在不进行任何布局控制时,浏览器默认的html布局方式。
block element:出现在一个元素下面的元素被称为块元素。
inline element:出现在一个元素旁边的元素被称为内联元素。
block和inline其实也好理解。就像我们正常的写字一样,一句话里面的每个字的排列就是inline(并排排列),而一段话与一段话之间就是block(上下排列)。
可以看到
元素默认是block,元素默认是inline。
flexbox即时 flexible box layout的简称。
flexbox是一种创建横向或是纵向的一维页面布局方式,被布局的对象既可以横向分布也可以纵向分布。他的特点是:父元素的display设置成flex后,它的直接子元素成为flex items,基于父元素这个盒子(flex container)进行弹性布局。
举例说明下:
<div class="wrapper">
<div>第四章div>
<div>第五章div>
<div>第六章div>
div>
.wrapper{
display: flex;
}
.wrapper > div {
border-radius: 5px;
background-color: rgb(207 232 220);
padding: 10px;
box-shadow: 5px 5px 5px 5px rgba(0, 0, 0, 0.7);
}
父元素div定义了一个wrapper类且display设置为flex,它的子元素div为了方便观察,添加了些样式。
运行的效果如下:
可以看到,父元素div
的display
为flex
,flex-direction
为row
,即按行排列。父元素就好比一个盒子,其子元素可以在这个盒子里面按照相应的属性值进行布局。由于display
不支持继承,所以子元素div
的display
还是默认的block
。
三个子元素div为什么看起来是在垂直方向上填满了,而水平方向上从左到右紧挨着排队而没有将右边的空白也填满呢?
要解释清楚这个问题,还涉及几个概念:主轴(main axis)、交叉轴(cross axis)、align-items。
弹性容器(flex)的主轴和交叉轴是垂直的,而主轴和交叉轴的具体方向是由flex-direction属性决定。
如果flex-direction的值是row
或 row-reverse
,那么主轴就是横向的,交叉轴就是纵向的。
如果flex-direction的值是column
或column-reverse
,那么主轴就是纵向的,交叉轴就是横向的。
align-items
属性控制items在交叉轴上的对齐方式;对于flex,align-items的默认值是strech,即在交叉轴方向上填充(strech)。
若将height:400px添加到wrapper,这种交叉轴方向上的stretch会更加明显。
justify-content
属性控制:在主轴方向上,items之间 以及 items和父元素之间的空间分布。对于flex,justify-content
的默认值是start,start的作用是:从行首开始排列,每行第一个子元素与行首对齐,同时所有后续的子元素与前一个对齐。
若将justify-content
改为space-between
(在每行上均匀分配弹性元素;相邻元素间距离相同;每行第一个元素与行首对齐,每行最后一个元素与行尾对齐。),那么效果就发生变化了。
不仅可以对flex容器进行属性设置,也可以对flex items进行属性设置。比如,flex属性可以设置flex items如何增大或缩小以适应其弹性容器中可用的空间。
grid用于同时在两个维度上把元素 按 行和列 排列整齐。
<div class="wrapper">
<div class="box1">第一章div>
<div class="box2">第二章div>
<div class="box3">第三章div>
<div class="box4">第四章div>
<div class="box5">第五章div>
<div class="box6">第六章div>
div>
.wrapper>div {
border-radius: 5px;
background-color: rgb(207 232 220);
padding: 1em;
}
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 100px 100px 100px;
gap: 10px;
}
grid-template-rows
定义grid container中 行数和每一行的高度,高度可以用px、百分比和fr(fraction of available space)表示。上例中,在grid中定义了3行,每行高度为100px。
grid-template-columns
定义grid container中 列数和每一列的宽度,宽度可以用px、百分比和fr表示。上例中,在grid中定义了2列,没列高度为1fr。
fr
是一种度量单位,用来为每个网格成比例的分配空白空间,适合用于弹性和响应式布局。
gap
表示网格行与列之间的间隔。即可用于flex也可以用于grid。
<div class="wrapper">
<div class="box1">第一章div>
<div class="box2">第二章div>
<div class="box3">第三章div>
div>
.wrapper>div {
border-radius: 5px;
background-color: rgb(207 232 220);
padding: 1em;
border: 1px solid black;
}
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 100px 100px;
gap: 10px;
/* border: 1px solid black; */
}
.box1 {
grid-column: 2 / 4;
grid-row: 1;
}
.box2 {
grid-column: 1;
grid-row: 1 / 3;
}
.box3 {
grid-row: 2;
grid-column: 3;
}
本例是一个2行3列的网格。
grid-column
属性用于设置grid item的显示从第几列开始,到第几列结束;例如,box1从第二列开始显示,到第四列结束。
grid-row
属性用于设置grid item的显示从第几行开始,到第几列结束;例如,box2从第二行开始显示,到第三行结束。
虽然现在新的CSS代码不再使用float布局,但有些老的项目中可能还有float的代码,因此,也得知道floats布局到底是怎么个搞法,以便代码维护。
将设置float的元素从normal flow”去除”,也就是说独立于normal flow中的元素,甭管normal flow中的元素布局位置怎么变,设置float的元素“岿然不动”。
<h1>Float 使用示例h1>
<div class="box">Floatdiv>
<p>央视网消息:透过数据看中国经济。近日,一批经济数据陆续发布,2023年全年收购粮食超4亿吨、
我国寄递业务量超1600亿件、全国油气产量当量创新高……
多项数据显示,我国经济活力持续向好,经济整体将稳定恢复。
2023年全国粮食总产量达13908.2亿斤,比上年增长1.3%,连续9年稳定在1.3万亿斤以上,
粮食市场保持平稳运行,国家储备实力和应急保障能力进一步增强,为经济回升向好和高质量发展,
提供有力支撑。
p>
.box {
background-color: rgb(207 232 220);
border: 2px solid rgb(79 185 227);
padding: 10px;
border-radius: 5px;
float: left;
width: 150px;
height: 150px;
margin-right: 30px;
}
将box是设置为float:left,div将始终靠左,并且与p元素相互独立,然后视觉上有一种p元素中的文字环绕着box的效果。
本文研究了CSS layout的normal flow,flex,grip和float。normal flow就是默认的页面布局,flex是一种一维 (或行或列,main axis)的布局方式,grid是一种二维的网格式布局方式。