CSS基础——布局
布局是css的一个很重要的概念,目的是如何将我们之前已经布置好的盒子拼凑起来,最终展示出来想要的界面,接下来从发展历史的角度讨论一下简单的布局,最后再列举一些常见的布局案例。
1.正常流布局
对页面不做任何的布局控制,这是浏览器原始布局方式,它会完全的按照源码的先后顺序展示,html元素包括块元素以及内联元素两种。
块级元素默认元素会新起一行,一般块级元素可以包含行内元素和其他块级元素。行内元素只占据它对应标签的边框所包含的空间,宽度与内容一致,不能设置width和height,除非设置display=block/inline-block。
正常情况下可以按照默认的方式来搭建页面,减少自造车轮的成本,但是有些时候页面的布局并不是简单的上下结构,还包括左右结构等等,正常的流布局就又些不够用了。
2.table布局
表格主要用于展示数据,但在CSS不太发达的时候,前辈们也会经常使用 表格来完成整个布局,页眉页脚,不同的列和行通过放在在不同表的行和列中进行布局。简单的布局是可以的,但是表布局不太灵活,而且需要很多的标记,所以目前基本不会用table布局。
3.多列布局
多列布局用于将web内容变成多列,就像文本在报纸上的排列那样,可以通过设置容器的column-width设置列
<body>
<style>
.container {
/*每列宽度200px,设置容器宽度后column-width属性会失效*/
column-width:200px;
/*三列,两个属性同时用的话column-width会失效*/
column-count:3;
}
</style>
<div class="container">
<p>
lorem100(这个命令在vscode下输出随机的100个单词)
</p>
</div>
</body>
4.浮动布局
引入float属性是为了让开发人员实现简单的布局,可以设置float:left
和float:right
对页面进行两列/三列布局
<style>
.container1 {
float:left;
width: 200px;
height: 200px;
background: lightcoral;
}
.container2 {
height: 200px;
margin-left: 200px;
margin-right: 200px;
background: pink;
}
.container3 {
float:right;
width: 200px;
height: 200px;
background: lightcoral;
}
.footer {
/*如果不清除,就会出现所有在浮动下面的自身不浮动的内容都将围绕浮动元素进行包装*/
clear: both;
}
</style>
<div class="container1">
</div>
<div class="container3">
</div>
<div class="container2">
hahaha
</div>
<div class="footer">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Doloremque mollitia, ratione qui vitae numquam quas repellendus animi. Molestiae, ratione veniam?</div>
浮动元素因为存在于正常的文档布局流之外,所以他们在父元素中所占的面积的有效高度为0,其次,非浮动元素的外边距不能用于它们和浮动元素之间来创建空间,可以使用一个空白的div,对其使用clear:both
进行浮动的清除
5.position布局
定位允许的是从正常的文档流布局中取出元素,并使它们具有不同的行为
-
position:static
每个元素获取的默认值,意味着将元素放入它在文档布局流中的正常位置上,不改变原始布局 -
position:relative
元素先放置在未添加定位时的位置,在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白),实际上就是相对于上一个元素(或者父元素)为参照物进行布局,其他元素不受影响<style> .box { display: inline-block; width: 100px; height: 100px; background: red; color: white; } #two { position: relative; top: 20px; left: 20px; background: blue; } </style> <div class="box" id="one">One</div> <div class="box" id="two">Two</div> <div class="box" id="three">Three</div> <div class="box" id="four">Four</div>
-
position:absolute
绝对定位元素脱离了文档流,不占据空间(变成阿飘浮在上面或者藏在下面),相对于最近的非static祖先元素定位,如果在body下直接设置absolute,元素还是处于当前位置上,只不过这个元素之后的其他元素可能会把它给覆盖掉 -
position:fixed
绝对定位固定元素是相对于html元素或者最近的定位祖先,固定定位则是相对于浏览器本身,这就意味着我们可以创建置顶或者置顶的元素 -
position:sticky
它是相对位置和固定位置的混合体,它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点(例如,从视口顶部起10像素)为止,此后它就变得固定了(但是sticky的兼容性不是很好,慎用)<style> <div> <dl> <dt>A</dt> <dd>Andrew W.K.</dd> <dd>Apparat</dd> <dd>Arcade Fire</dd> <dd>At The Drive-In</dd> <dd>Aziz Ansari</dd> </dl> <dl> <dt>C</dt> <dd>Chromeo</dd> <dd>Common</dd> <dd>Converge</dd> <dd>Crystal Castles</dd> <dd>Cursive</dd> </dl> <dl> <dt>E</dt> <dd>Explosions In The Sky</dd> </dl> <dl> <dt>T</dt> <dd>Ted Leo & The Pharmacists</dd> <dd>T-Pain</dd> <dd>Thrice</dd> <dd>TV On The Radio</dd> <dd>Two Gallants</dd> </dl> </div> CSS * { box-sizing: border-box; } dl { margin: 0; padding: 24px 0 0 0; } dt { background: #B8C1C8; border-bottom: 1px solid #989EA4; border-top: 1px solid #717D85; color: #FFF; font: bold 18px/21px Helvetica, Arial, sans-serif; margin: 0; padding: 2px 0 0 12px; position: -webkit-sticky; position: sticky; top: -1px; } dd { font: bold 20px/45px Helvetica, Arial, sans-serif; margin: 0; padding: 0 0 0 12px; white-space: nowrap; } dd + dd { border-top: 1px solid #CCC } </style> <div> <dl> <dt>A</dt> <dd>Andrew W.K.</dd> <dd>Apparat</dd> <dd>Arcade Fire</dd> <dd>At The Drive-In</dd> <dd>Aziz Ansari</dd> </dl> <dl> <dt>C</dt> <dd>Chromeo</dd> <dd>Common</dd> <dd>Converge</dd> <dd>Crystal Castles</dd> <dd>Cursive</dd> </dl> <dl> <dt>E</dt> <dd>Explosions In The Sky</dd> </dl> <dl> <dt>T</dt> <dd>Ted Leo & The Pharmacists</dd> <dd>T-Pain</dd> <dd>Thrice</dd> <dd>TV On The Radio</dd> <dd>Two Gallants</dd> </dl> </div>
6.flex布局
弹性盒子是一种用于按行或者按列布局元素的一维布局方法。元素可以膨胀以填充额外空间,也可收缩以适应更小的空间。
打开flex布局,只需要设置display:flex
如图所示,解释几个概念:
- flex容器(flex container)和flex子项(flex item):前者是设置了
display:flex
的父元素(这个元素的子元素都按照flex布局来排列啦),后者就是这个父元素的子元素们 - 主轴(main axis):沿着flex元素放置方向延伸的轴,flex默认是沿x轴布局,但是可以通过
flex-direction:column/row
进行修改 - 交叉轴(cross axis):垂直于主轴的轴,该轴的开始和结束被称为cross start和cross end
常见的flex属性
-
flex-direction:row/column/row-reverse/column-reverse/initial/inherit
:控制弹性盒子的排列方向 -
flex-wrap:nowrap/wrap/wrap-reverse/initial/inherit
:控制子元素整体宽/高超出父元素宽/高时需要拆行 -
flex-flow
:flex-direction + flex-wrap -
flex-grow
:填写一个数字,规定弹性子元素相对于其他子元素进行扩展的量<body> <style> .parent { display:flex; height:300px } .son1 { flex-grow:1; background:pink } .son2 { flex-grow:2; background:yellow; } .son3 { flex-grow:3; background:blue } </style> <!--三个son的宽度比例为1:2:3 --> <div class="parent"> <div class="son1"> </div> <div class="son2"> </div> <div class="son3"> </div> </div> </body>
-
flex-shrink
:填写一个数字,定义子元素在超过父元素大小的缩放比例 -
flex-basis
:规定子元素的初始长度 -
flex
:flex是flex-grow, flex-shrink
和flex-basis
的结合flex-basis是每个子元素的原始宽度,根据原始子元素的宽度和跟父元素的宽度进行比较,来计算子元素的真实宽度,最后展现出来的子元素是按照父元素宽度布局的。
如果子元素宽度和小于父元素宽度,或者没有给子元素设置
flex-basis
,就按照flex-grow
的比例进行元素放大,如果子元素宽度和大于父元素宽度,就按照flex-shrink
的比例进行元素缩小。<!-- 父元素宽度为900px,子元素和为600px,就按flex-grow的比例进行放大 son1的宽度:200 + (900-600)*(1/(1+2+3)); son2的宽度:200 + (900-600)*(2/(1+2+3)); son3的宽度:200 + (900-600)*(3/(1+2+3)); --> <body> <style> .father { display: flex; height:500px; width: 900px; } .son1 { border: 1px solid; background:linear-gradient(pink, #9198e5); flex:1 1 200px; } .son2 { border: 1px solid; background:linear-gradient(pink, #9198e5); flex:2 2 200px; } .son3 { border: 1px solid; background:linear-gradient(pink, #9198e5); flex:3 3 200px; } </style> <div class="father"> <div class="son1"></div> <div class="son2"></div> <div class="son3"></div> </div> </body> <!-- 父元素宽度为600px,子元素和为900px,就按flex-shrink和flex-basis比例缩小每个子元素 son1的宽度:300 - (900-600)*(200/(1*200+2*300+3*400)); son2的宽度:300 - (900-600)*(600/(1*200+2*300+3*400)); son3的宽度:300 - (900-600)*(1200/(1*200+2*300+3*400)); --> <body> <style> .father { display: flex; height:500px; width: 600px; } .son1 { border: 1px solid; background:linear-gradient(pink, #9198e5); flex:1 1 200px; } .son2 { border: 1px solid; background:linear-gradient(pink, #9198e5); flex:2 2 300px; } .son3 { border: 1px solid; background:linear-gradient(pink, #9198e5); flex:3 3 400px; } </style> <div class="father"> <div class="son1"></div> <div class="son2"></div> <div class="son3"></div> </div> </body>
7.grid布局
grid是二维网格布局,实际上就是将网页划分成一个个网格,任意组合,最终作出各种各样的布局
grid-template-columns
:定义每一列的列宽grid-template-rows
:定义每一行的行高grid-row-gap
:行间距grid-column-gap
:列间距grid-gap
:列,行间距grid-template-areas
:设置网格区域grid-auto-flow
:划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格,默认先行后列,如果设置值为column,顺序就为先列后行
http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html