css布局解决方案
gitee仓库地址
水平居中布局
1. text-algin:center
使用场景
只适用于文本/行内元素/行内块级元素的水平居中
原理
text-align只控制行内内容(文字、行内元素、行内块级元素)如何相对他的块父元素对齐
优点与缺点
- 优点:简单快捷,容易理解,兼容性非常好
- 缺点:只对行内内容有效;属性会继承影响到后代行内内容;如果子元素宽度大于父元素宽度则无效,只有后代行内内容中宽度小于设置text-align属性的元素宽度的时候,才会水平居中
2. margin:0 auto
原理
W3C规范介绍: https://www.w3.org/TR/CSS21/visudet.html#Computing_widths_and_margins
在margin有节余的同时如果左右margin设置了auto,将会均分剩余空间。另外,如果上下的margin设置了auto,其计算值为0
优点和缺点
- 优点:简单;兼容性好
- 缺点:必须定宽,并且值不能为auto;宽度要小于父元素,否则无效
3. inline-block+text-align属性配合使用
<!-- 定义父级元素 -->
<div class="parent">
<!-- 定义子集元素 -->
<div class="child"></div>
</div>
.parent{
width: 100%;
height: 200px;
background: #ccc;
text-align: center;
}
.child{
width: 200px;
height: 200px;
background: #c9394a;
display: inline-block;
}
原理
text-align只控制行内内容(文字、行内元素、行内块级元素)如何相对他的块父元素对齐。而子元素设置成内联块级元素
display有3个属性
-
block:块级元素
-
inline:内联元素(text-align属性有效),之所以不直接设置成内联元素是因为,内联元素有一个问题,就是当我们把一个某一个元素设置成inline内联元素的时候,css中的width和height属性是无效的
-
inline-block:行内块级元素(整合了块级和内联元素的特点)
而块级元素的特点是width和height属性是有效的
优点和缺点
优点:浏览器兼容性比较好
缺点:text-align属性具有继承性,导致子级元素的文本也是居中显示的。但是可以给子级元素重新设置text-align对齐属性,会覆盖父级中的text-align属性值
4. table配合margin属性使用
<div class="parent">
<div class="child">
居中布局
</div>
</div>
.parent{
width: 100%;
height: 200px;
background: #ccc;
}
.child{
width: 200px;
height: 200px;
background: #c9394a;
display: table;
margin: 0 auto;
}
原理
margin属性是核心,margin:0 auto的第二个值为auto,而auto表示根据浏览器自动分配(左右等分外边距)
而display设置成table和block都是可以水平居中的,而且div元素默认为block块级元素的,所以给display设置成table或者block都是可以生效的
这种方法与纯margin:0 auto实现居中,效果是一样的
优点和缺点
优点:只需要对子集元素进行设置就可以实现水平居中效果,不需要为父级元素设置任何的特殊样式
缺点:如果子集元素脱离文档流,会导致margin属性的的值无效
脱离文档流的方式
- 将元素设置为浮动,无论是左浮动,还是右浮动
- 将元素设置为绝对定位absolute
- 将元素设置为固定定位fixed
margin属性值一旦无效之后,这种方法就不能实现水平居中了
5. absolute+transform属性的translateX
<!-- 定义父级元素 -->
<div class="parent">
<!-- 定义子级元素 -->
<div class="child">
</div>
.parent{
width: 500px;
height: 200px;
background: #ccc;
/* 在父级元素中开启定位,设置成relative absolute fixed任意一个值都是可以的,只要开启定位就行,只有position的默认值static是不开启定位的 */
position: relative;
}
.child{
width: 200px;
height: 200px;
background: #c9394a;
/*当把当前元素设置为绝对定位只有,有两种情况:;
*1.如果父级元素没有开启定位的话,当前元素是相对于页面定位的
*2.如果父级元素开启了定位的话,当前元素是相对于父级元素定位的
*/
position: absolute;
left: 50%;
/*如果值设置top:50%,作为子级元素,在父元素中是不居中对齐的。原因是因为,现在的实际效果是自己元素的左边在水平方向上居中的位置,左边是50%,右边也是50%(不过右边的50%是包含子集宽度的),所有需要向左回退1/2的自身宽度
*/
/* transform: translateX(-100px) ; */
/* 向右移动的话,就是正值 */
/* 但是这样有一个问题,translateX里的值是根据子级元素的宽实现的,子级元素的宽度一旦改变,translateX里的值也要相对应的改变,改成50%之后,就会自动变化了 */
transform: translateX(-50%) ;
}
原理
在子元素中设置position:absolute
相对定位,然后在父级元素中开启定位,设置成relative absolute fixed任意一个值都是可以的,只要开启定位就行,只有position的默认值static是不开启定位的。
当把当前元素设置为绝对定位只有,有两种情况:
- 如果父级元素没有开启定位的话,当前元素是相对于整个页面定位,即在整个页面中水平居中
- 如果父级元素开启了定位的话,当前元素是相对于父级元素定位的,即在父级元素中水平居中
如果值设置top:50%,作为子级元素,在父元素中是不居中对齐的。原因是因为,现在的实际效果是自己元素的左边在水平方向上居中的位置,左边是50%,右边也是50%(不过右边的50%是包含子集宽度的),所有需要向左回退1/2的自身宽度,向右移动的话,就是正值
但是这样有一个问题,translateX里的值是根据子级元素的宽实现的,子级元素的宽度一旦改变,translateX里的值也要相对应的改变,将改成translateX里的值改成百分比之后,即-50%之后,就会自动变化了
优点和缺点
优点:无无论父级元素是否脱离文档流,不影响子级元素水平居中效果,关键在于为子级元素设置了绝对定位
缺点:transform属性是CSS3中的新增属性,对浏览器(特别是老浏览器、IE9+)兼容性不好
6.flex横轴
理解Flexbox:你需要知道的一切
https://www.w3cplus.com/css3/understanding-flexbox-everything-you-need-to-know.html
深入理解 flex 布局以及计算
https://www.w3cplus.com/css3/flexbox-layout-and-calculation.html?from=groupmessage
设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式
<div class="parent">
<div class="son"></div>
</div>
.parent{
width: 500px;
height: 500px;
background: aqua;
display: flex;
justify-content: center; /* 水平居中 */
/* align-items: center; */ /* 垂直居中 */
}
.son{
width: 100px;
height: 100px;
background: #c60025;
}
优点和缺点
优点:功能强大;简单方便;容易理解
缺点:PC端兼容性不好
7. 图片水平居中
图片本身属于行内块级元素,给它设置display:bock转为块级元素,即可用margin:0 auto实现水平居中
垂直居中布局
1. line-height等于height
使用场景
单行文本/行内元素/行内块级元素
原理
line-height的最终表现是通过inline box实现的,而无论inline box所占据的高度是多少(无论比文字大还是比文字小),其占据的空间都是与文字内容公用水平中垂线的。
元素分类参考 https://www.cnblogs.com/zmshare/p/6648038.html
<div class="box1">
单行文本垂直居中
</div>
<div class="box2">
<span>单个行内元素</span>
</div>
<div class="box3">
<button>单个行内块级元素垂直居中</button>
</div>
.box1,.box2,.box3{
width: 200px;
height: 100px;
line-height: 100px;
}
.box1{
background: aqua;
}
.box2{
background: #e49002;
}
.box3{
background: #c60023;
}
优点和缺点
优点:简单;兼容性好
缺点:只能用于单行行内内容,要知道高度的值
多行文本/行内元素/行内块级元素
<div class="box1">
压缩木压缩方向的垂直方向上的干缩率,弦向压缩最小,径向压缩最大,非标准向居中。
Shrinking efficiency in vertical direction of compressed direction was the smallest in tangential, the biggest in radial, and middle in non standard compression.
</div>
<div class="box2">
<span>第1个行内元素</span>
<span>第2个行内元素</span>
</div>
<div class="box3">
<button >第1个行内块级元素</button>
<button >第2个行内块级元素</button>
<button >第3个行内块级元素</button>
</div>
.box1{
width: 500px;
height: 50px;
line-height: 25px;
background: aqua;
}
.box2{
width: 160px;
height: 90px;
line-height: 45px;
background: #e49002;
}
.box3{
width: 250px;
height: 330px;
line-height: 110px;
background: #c60023;
}.box1,.box2,.box3{
width: 1000px;
height: 300px;
line-height: 300px;
}
.box1{
background: aqua;
}
.box2{
background: #e49002;
}
.box3{
background: #c60023;
}
原理
元素在页面呈现为n行,则line-height的值为height/n
优点和缺点
优点:简单;兼容性好
缺点:只能用于行内内容;需要知道高度和最终呈现多少行来计算(元素在页面呈现为n行,则line-height的值为height/n)出line-height的值,建议用span包裹多行文本,设置display:inline-block转换成图片的方式解决
2. vertical-align配合line-height实现图片垂直居中
<div class="parent">
<img class="pic" src="https://pic.cnblogs.com/avatar/1977105/20200319121651.png" />
</div>
.parent{
width: 500px;
height: 500px;
background: aqua;
line-height: 500px;
font-size: 0;
/* 不设置font-size为0,设置text-align:center做水平居中也可以 */
}
img{
vertical-align: middle;
}
原理
vertical-align和line-height的基友关系
去除inline-block元素间间距的N种方法
https://www.zhangxinxu.com/wordpress/2012/04/inline-block-space-remove-%e5%8e%bb%e9%99%a4%e9%97%b4%e8%b7%9d/
优缺点
优点:简单;兼容性好
缺点:需要添加font-size: 0; 才可以完全的垂直居中;不过更主要的是需要在图片标签结束处留下空格后者换行:
参考资料:https://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-height/
<div><img src="mm1.jpg"><!-- 这里要折行或空格 -->
</div>
3.table-cell配合vertical-middle实现垂直居中
<div class="parent">
<div class="child">
若梦
</div>
</div>
.parent{
width: 200px;
height: 600px;
background: aqua;
display: table-cell;
vertical-align: middle;
}
.child{
width: 100px;
height: 100px;
background: #c600c6;
}
原理
display属性:
table:设置当前元素为<table>
元素
table-cell:设置当前元素为<td>
元素(单元格)
vertical-align属性:用于设置文本内容的垂直方向对齐方式
top:顶部对齐
middle:居中对齐
bottom:底部对齐
作为子集元素的div,就相当于是单元格内容,再垂直居中,就呈现出垂直居中效果了
优点和缺点
优点:浏览器兼容性好,所使用的的table-cell和 vertical-align都是属于css2版本的内容,而css2版本对浏览器的兼容性好
缺点: vertical-align属性具有继承性,导致父级元素的文本也是居中显示的效果,这种方案不适合父级元素中包含除子级元素以外的文本内容的情况。设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素
4. absolute配合transform属性的translateY
<div class="parent">
<div class="child"></div>
</div>
.parent{
width: 400px; /*定宽*/
height: 400px;
background: aqua;
position: relative; /*父相*/
/* 在父级元素中开启定位,设置成relative absolute fixed任意一个值都是可以的,只要开启定位就行,只有position的默认值static是不开启定位的 */
}
.child{
width: 100px; /*定宽*/
height: 100px;
background: #c60047;
position: absolute; /*子绝*/
top: 50%;
transform: translateY(-50%);
}
优点和缺点
优点:父级元素是否脱离文档流,不影响子级元素垂直居中效果
缺点:transform属性是css3中的新增属性,对老版本的浏览器的支持并不友好
5. flex 纵轴
理解Flexbox:你需要知道的一切
https://www.w3cplus.com/css3/understanding-flexbox-everything-you-need-to-know.html
深入理解 flex 布局以及计算
https://www.w3cplus.com/css3/flexbox-layout-and-calculation.html?from=groupmessage
<div class="parent">
<div class="son"></div>
</div>
.parent{
width: 500px;
height: 500px;
background: aqua;
display: flex;
/* justify-content: center; */ /** 水平居中 */
/* align-items: center; */ /* 垂直居中方法1 */
}
.son{
width: 100px;
height: 100px;
background: #c60025;
/* align-self: center; */ /* 垂直居中方法2 */
margin: auto 0; /* 垂直居中方法3 */
}
优点:功能强大;简单方便;容易理解
缺点:PC端兼容性不好
水平垂直居中布局
1. text-align配合line-height与vertical-align
<div class="parent">
<div class="child"></div>
</div>
.parent{
height: 200px;
line-height: 200px;
background: aqua;
text-align: center;
font-size: 0; /* 消除幽灵空白节点 */
}
.child{
width: 80px;
height: 50px;
background: #c50021;
display: inline-block; /*如果是块级元素需改为行内或行内块级才生效*/
vertical-align: middle;
}
原理
text-align控制块级元素水平居中,line-height与vertical控制垂直居中,font-size为0,消除幽灵空白节点
使用场景
行内元素/行内块级元素/图片
行内元素
代表标签
<a>,<span>,<i>,<em>,<strong>,<label>,<q>,<var>,<cite>,<code>,
<img>,<input>,<select>,<textarea>,<button>
行内块级元素
img|input|select|textarea|button等,也被称为可置换元素(Replaced element)
优点和缺点
优点:简单,兼容
缺点:只对行内内容有效;需要添加font-size: 0;
消除幽灵节点, 才可以完全的垂直居中;
不过需要注意html中parent包裹son之间需要有换行或空格;熟悉line-height
和vertical-align
的基友关系较难
2. table-cell与vertical-align实现垂直,table和margin实现水平
<div class="parent">
<div class="child"></div>
</div>
.parent{
height: 220px;
width: 200px;
background: #e76523;
display: table-cell;
vertical-align: middle;
/*text-align: center;*/ /*如果是行内元素就添加这个*/
}
.child{
width: 50px;
height: 50px;
background: aqua;
display: table; /* display设置成table和block都是可以水平居中的,而且div元素默认为block块级元素的,所以给display设置成table或者block都是可以生效的 */
margin: 0 auto; /*如果是块级元素就添加这个*/
width: 100px;
height: 50px;
}
原理
table-cell与vertical-align实现垂直居中,table和margin实现水平居中
使用场景
如果是行内元素,需要给父级元素加text-align:center
行内元素
<a>,<span>,<i>,<em>,<strong>,<label>,<q>,<var>,<cite>,<code>,
<img>,<input>,<select>,<textarea>,<button>
子元素如果是块级元素,需要给子级元素设置margin:0 auto
块级元素
<div>,<p>,<h1>...<h6>,<ol>,<ul>,<dl>,<table>, <address>,<blockquote>,<form>
优点和缺点
优点:简单;适用于宽度高度未知情况;兼容性好(ie8+)
缺点:vertical-align属性具有继承性,导致父级元素的文本也是居中显示的效果
子级元素设置成display:table,其实对应的是HTML的
设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table;
才生效
table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height
设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素
3.利用button内文字自动居中,改其子元素属性为行内或行内块级
原理
button内的文字等内容,默认是自动水平居中的,只需要将其子元素转化为行内元素或者行内块级元素,即可实现水平垂直居中布局
<button class="parent">
<div class="child"></div>
</button>
.parent{
height:200px;
width: 200px;
background: aqua;
outline: none;
border: none;
}
.child{
height:50px;
width: 50px;
background: #e60023;
display: inline-block; /*button自带text-align: center,改为行内水平居中生效*/
/* button有默认padding值,不影响水平垂直居中布局,不想要,清除其默认样式即可 */
}
优点和缺点
优点:简单方便,充分利用button默认内容水平居中
缺点:只适用于行内内容;需要清除button标签部分默认样式;水平垂直居中兼容性很好,但是ie下点击会有凹陷效果
4. absolute+transform实现水平垂直居中
<div class="parent">
<div class="child"></div>
</div>
.parent{
width: 400px;
height: 400px;
background: #c12023;
position: relative; /*父相 */
/* 在父级元素中开启定位,设置成relative absolute fixed任意一个值都是可以的,只要开启定位就行,只有position的默认值static是不开启定位的
相对对位是不脱离文档流的,而绝对定位和固定定位是脱离文档流的
如果在父级元素中不开启定位,则是相对于整个页面进行定位
如果在父级元素中开启定位,则是相对于父级元素定位
*/
}
.child{
width: 100px;
height: 100px;
background:skyblue;
position: absolute; /* 子绝 */
top: 50%;
left: 50%;
transform:translate(-50%,-50%);
/* 之所以回退-50%,是因为子元素的左上角顶点是相对于上一级居中定位的,子元素的左上角顶点居中,整个元素并不是居中的,所以要回退自身高度的-50% * /
}
优点和缺点
优点:不管是块级还是行内元素都可以实现
优点:CSS3新属性对老版本浏览器兼容性不好
5. 定位与margin无限延伸实现平分
原理
当top、bottom为0时,margin-top&bottom设置auto的话会无限延伸占满空间并且平分,实现水平居中
当left、right为0时,margin-left&right设置auto的话会无限延伸占满空间并且平分,实现垂直居中
谁设置相对定位,其子元素就相对谁定位
<div class="parent">
<div class="child">
</div>
</div>
.parent{
height:200px;
width: 200px;
background: aqua;
position: relative;
/* 父元素设置相对定位,那子元素就相对于父元素定位 */
}
.child{
height:50px;
width: 50px;
background: #e60023;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
position: absolute;
}
优点和缺点
优点:无需关注宽高;兼容性较好(ie8+)
缺点:脱离文档流
6. flex同时横轴和纵轴
<div class="parent">
<div class="child"></div>
</div>
/* height:200px;
width: 200px;
background: aqua;
display: flex;
justify-content: center; */
/* 横轴 让其子元素水平居中 */
/* align-items: center; */
/* 纵轴 让其子元素垂直居中 */
/* .child{
height:50px;
width: 50px;
background: #e60023;
} */
/* 或 */
.parent{
height:200px;
width: 200px;
background: aqua;
display: flex;
}
.child{
height:50px;
width: 50px;
background: #e60023;
margin: auto;
}
/* 或 */
/* .parent{
display: flex;
justify-content: center;
}
.child{
align-self: center;
} */
原理
两列布局
由于屏幕的的大小,自适应的那一列宽度可能是不确定的
左列定宽,右列自适应
1. float配合margin
要点
定宽列设置宽度并float,自适应列margin
<div class="left">左列定宽</div>
<div class="right">右列自适应</div>
.left{
/* 左列定宽 */
width: 300px;
height: 300px;
background: aqua;
/* 设置浮动后,当前元素脱离文档流 */
float: left;
}
.right{
height: 300px;
background-color: #c60023;
/* margin-left让被左列覆盖的宽度,吐出来 */
margin-left: 300px;
/*大于等于.left的宽度即可*/
}
原理
float浮动,让元素脱离文档流,margin-left让被左列覆盖的宽度,吐出来
优点和缺点
优点:实现方式简单
缺点:
-
当右列的自适应区域中含有子级元素的时候,当前布局样式,已经乱套了,子级元素浮动的问题
-
自适应元素的margin-left属性值,需要和定宽元素的width属性值保持一致
-
定宽元素浮动与自适应元素不浮动导致浏览器兼容性不好
-
margin-left的值,和左列的width值高度关联
改良版
当右列的自适应区域中含有子级元素的时候,当前布局样式,已经乱套了
<div class="left">左列定宽</div>
<!-- 为自适应元素定义父级元素 -->
<div class="right-box">
<div class="right">
<div class="inner"></div>
</div>
</div>
.left,.right{
height: 300px;
}
.left {
width: 400px;
background-color: #c9394a;
/* 当前元素脱离文档流 */
float: left;
/* 定位的层级高于浮动,这样左列就可以显示出来了 */
/* position: relative; */
}
/* 自适应,右列的父级元素和左列的是兄弟元素,都是浮动的 */
.right-box {
float: right;
/* 设置为浮动后,导致默认宽度为0,需要重新设置宽度 */
/* 100%表示为父级元素宽度100%,而当前div元素的父级为body,即现这right-box的宽度为页面的100% */
width: 100%;
/* 此时宽度为100%,自己就被挤到下一行了 */
margin-left: -400px;
/* 此时margin-left为-400px,即向左移动,,就会上到第一行,覆盖原来第一行的左列*/
background-color: blue;
}
.right{
/* div默认的宽度为父级元素的100% */
background-color: #cccccc;
margin-left: 400px;
}
.inner{
background-color: green;
height:300px;
clear: both;
}
改良版只解决了浮动与浮动的问题,和子级元素清除浮动的问题。
margin-left: -400px的值与左列的宽度之间高度耦合关联的关系,暂未改良
2. float配合overflow属性
要点
定宽列设置宽度并float,自适应列overflow:hidden
<div class="left">左列定宽</div>
<div class="right">右列自适应</div>
.left {
width: 40px;
background-color: #c60023;
float: left;
}
.right{
background-color: #cccccc;
overflow: hidden;
/*
* overflow除了又溢出时隐藏的作用,
还可开启CSS 的BFC模式 - 当前元素的内部画家与外界完全隔离 实现自适应
*/
}
原理
overflow除了又溢出时隐藏的作用,
还可开启CSS 的BFC模式 - 当前元素的内部画家与外界完全隔离 实现自适应
优点和缺点
优点:简单易用,不用管高度,BFC模式自适应
缺点:
- overflow属性不仅解决了两列布局问题,同时设置了内容溢出的情况
- 浮动脱离文档流,需要手动清除浮动,否则会产生高度塌陷;
- 不支持ie6
3. table单元格自动分配宽度
要点
父元素设置display:table,定宽列设置宽度,自适应列设置table-cell
原理
table单元格没有设置宽度width值的话,自动分配达到自适应效果,也就是50%和50%等分,左列定宽后,就把剩下的所有宽度分配给自适应的元素,最终实现两列布局的效果
<div class="parent">
<div class="left"></div>
<div class="right"></div>
</div>
.parent{
/*c父级元素设置100%c*/
width: 100%;
display: table;
/* 防止撑破 */
table-layout: fixed;
}
.left,.right{
height: 300px;
display: table-cell;
}
.left{
/* 定宽 */
width: 400px;
background-color: #c60233;
}
.right{
background-color: skyblue;
}
优点和缺点
优点:浏览器兼容性好,给定左列宽度,无需管高度,自动分配
缺点:将所有元素的display属性设置为table相关值,收到响应制约,单元格的宽度是自动的,表格默认双边框
4. 绝对定位
要点
子绝父相,定宽列设置宽度,自适应列top和right为0,left为定宽列宽度
<div class="parent">
<div class="left">左列定宽</div>
<div class="right">右列自适应</div>
</div>
.parent{
position: relative; /*子绝父相*/
}
.left {
position: absolute;
top: 0;
left: 0;
background-color: #f00;
width: 100px;
height: 500px;
}
.right {
position: absolute;
top: 0;
left: 100px; /*值大于等于#left的宽度*/
right: 0;
background-color: #0f0;
height: 500px;
}
5. flex均分剩余空间
要点
父元素设置display:flex,定宽列子元素设置宽度,自适应列设置flex值均分剩余空间
<div class="parent">
<div class="left">左列定宽</div>
<div class="right">右列自适应</div>
</div>
.parent{
width: 100%;
height: 500px;
display: flex;
}
.left {
width: 100px;
background-color: #f00;
}
.right {
flex: 1; /*均分了父元素剩余空间*/
background-color: #0f0;
}
6. grid实现
要点
父元素设置grid grid-template-columns: 100px auto;定宽列定宽,自适应列auto
<div class="parent">
<div class="left">左列定宽</div>
<div class="right">右列自适应</div>
</div>
.parent {
width: 100%;
height: 500px;
display: grid;
grid-template-columns: 100px auto; /*设定2列就ok了,auto换成1fr也行*/
}
.left {
background-color: #f00;
}
.right {
background-color: #0f0;
}
左列自适应,右列定宽
1. float配合margin
要点
定宽列设置宽度并float,自适应列overflow:hidden,父元素用padding-left的正值抵消自适应列的margin-left的负值
<div class="left">左列自适应</div>
<div class="right">右列定宽</div>
.parent{
height: 500px;
padding-left: 100px; /*抵消.left的margin-left以达到#parent水平居中*/
}
.left {
width: 100%;
height: 500px;
float: left;
margin-left: -100px; /*正值等于.right的宽度*/
background-color: #f00;
}
.right {
height: 500px;
width: 100px;
float: right;
background-color: #0f0;
}
2. float配合overflow属性
要点
自适应列overflow:hidden,定宽列设置宽度
<div class="parent">
<div class="right">右列定宽</div>
<div class="left">左列自适应</div> <!--顺序要换一下-->
</div>
.left {
overflow: hidden; /*触发bfc*/
height: 500px;
background-color: #f00;
}
.right {
margin-left: 10px; /*margin需要定义在#right中 设置边距*/
float: right;
width: 100px;
height: 500px;
background-color: #0f0;
}
3. table自动分配
要点
父元素设置display: table; 自适应列设置table-cell,定宽列定宽
<div class="parent">
<div class="left"></div>
<div class="right"></div>
</div>
.parent{
/*c父级元素设置100%c*/
width: 100%;
display: table;
/* 防止撑破 */
table-layout: fixed;
}
.left,.right{
height: 300px;
display: table-cell;
}
.left{
background-color: #c60233;
}
.right{
/* 定宽 */
width: 400px;
background-color: skyblue;
}
4. 绝对定位
要点
子绝父相,自适应列设置left值,定宽列设置宽度
<div class="parent">
<div class="left">左列自适应</div>
<div class="right">右列定宽</div>
</div>
.parent{
position: relative; /*子绝父相*/
}
.left {
position: absolute;
top: 0;
left: 0;
right: 100px; /*大于等于#rigth的宽度*/
background-color: #f00;
height: 500px;
}
#right {
position: absolute;
top: 0;
right: 0;
background-color: #0f0;
width: 100px;
height: 500px;
}
5. flex均分剩余空间
要点
父元素设置flex,自适应列设置flex值为1,定宽列设置宽度
<div class="parent">
<div class="left">左列自适应</div>
<div class="right">右列定宽</div>
</div>
.parent{
width: 100%;
display: flex;
}
.left{
height: 100px;
background-color: aqua;
flex: 1;
}
.right{
width: 200px;
height: 100px;
background-color: #c60025;
}
6. grid
要点
父元素设置grid grid-template-columns: 100px auto;自适应列auto 定宽列定宽
<div class="parent">
<div class="left">左列自适应</div>
<div class="right">右列定宽</div>
</div>
.parent {
height: 500px;
display: grid;
grid-template-columns: auto 100px; /*设定2列,auto换成1fr也行*/
}
.left {
background-color: #f00;
}
.right {
background-color: #0f0;
}
三列布局
左侧两个挨着的列定宽,右侧一个列自适应
1. 定宽列float配合自适应列margin
要点
定宽列float并且定宽,自适应列给margin-left值(值为定宽列宽度之和)
<div class="left">左列定宽</div>
<div class="center">中列定宽</div>
<div class="right">右列自适应</div>
.left,.center,.right{
height: 300px;
}
.left{
/* 左列定宽 */
width: 400px;
background-color: #c9394a;
float: left;
}
.center{
/* 中列定宽 */
width: 400px;
background-color: aqua;
float: left;
}
/* 就算再来一列,给该定宽的列浮动,给右侧自适应的列,一个重新计算和后的值,该方案也可用 */
.right{
background-color: pink;
/* 此时的margin-left值Wie左侧两列宽度之和 */
margin-left: 800px;
}
2. 定宽列float配合自适应列overflow
要点
定宽列设置宽度并float,自适应列overflow:hidden
<div class="left">左列定宽</div>
<div class="center">中列定宽</div>
<div class="right">右列自适应</div>
.left,.center,.right{
height: 300px;
}
.left{
/* 左列定宽 */
width: 400px;
background-color: #c9394a;
float: left;
}
.center{
/* 中列定宽 */
width: 400px;
background-color: aqua;
float: left;
}
.right{
background-color: pink;
/* 触发BFC 实现自适应 */
overflow: hidden;
}
优点和缺点
优点:代码简单,容易理解,无需关注定宽的宽度,利用bfc达到自适应效果
缺点:浮动脱离文档流,需要手动清除浮动,否则会产生高度塌陷;不支持ie6
3. table
要点
父元素设置display: table,定宽列设置table-cell和宽度,自适应列设置rtable-cell
<div class="parent">
<div class="left">左列定宽</div>
<div class="center">中列定宽</div>
<div class="right">右列自适应</div>
</div>
.parent {
width: 100%;
display: table;
}
.left,.center,.right{
height: 300px;
}
.left{
/* 左列定宽 */
width: 400px;
background-color: #c9394a;
display: table-cell;
margin: -10px 0; /*抵消上下边间距10的位置影响*/
/*左右两边间距大了一点,子元素改用padding设置盒子间距就没有这个问题*/
border-spacing: 10px; /*关键!!!设置间距*/
}
.center{
/* 中列定宽 */
width: 400px;
background-color: aqua;
display: table-cell;
}
.right{
background-color: pink;
display: table-cell;
}
优点和缺点
优点:代码简单,容易理解,无需关注定宽的宽度,利用单元格自动分配达到自适应效果
缺点:margin失效;设置间隔比较麻烦;不支持ie8
4. flex均分剩余空间
要点
父元素设置flex,定宽类定宽,自适应列设置flex值为1
<div class="parent">
<div class="left">左列定宽</div>
<div class="center">中列定宽</div>
<div class="right">右列自适应</div>
</div>
.parent{
width: 100%;
height: 500px;
display: flex;
}
.left {
width: 100px;
background-color: #f00;
}
.center{
width: 150px;
background-color: skyblue;
}
.right {
flex: 1; /*均分了父元素剩余空间*/
background-color: #0f0;
}
5. grid
要点
父元素设置display: grid ,父元素设置 grid-template-columns: 100px 200px auto;给定宽列定宽
<div class="parent">
<div class="left">左列定宽</div>
<div class="center">中列定宽</div>
<div class="right">右列自适应</div>
</div>
.parent{
display: grid;
grid-template-columns: 100px 200px auto; /*设置3列,固定第一第二列的宽度,第三列auto或者1fr*/
}
.left,.center,.right{
height: 300px;
}
.left{
background-color: #c9394a;
}
.center{
background-color: aqua;
}
.right{
background-color: pink;
}
两侧的2列定宽,中间一列自适应
1. float配合margin或者overflow圣杯布局
因布局效果类似圣杯而得名,核心在于中间的主体部分自适应
<div class="left">左列定宽</div>
<div class="right">右列定宽</div>
<div class="center">中列自适应</div>
<!-- 把页面的主要部分center放到后面解析,不利于被搜素引擎收录 -->
.left,.center,.right{
height: 300px;
}
/* 两列定宽 左列定宽 中列自适应 右列定宽 */
.left,.right{
width: 300px;
}
.left{
background-color: aqua;
float: left;
}
.center{
background-color: #c60023;
margin-left: 300px;
margin-right: 300px;
/* 或者不要margin-let和margin-right,直接overflow:hidden */
}
.right{
background-color: pink;
float: right;
}
不足
搜索引擎收录页面是按照HTML的解析顺序,而将页面最重要的center部分放到最后,不利于被搜素引擎收录
改良
<div class="parent">
<!--为了利于搜索引擎抓取 center需要放在前面-->
<div class="center">中间自适应
</div>
<div class="left">左列定宽</div>
<div class="right">右列定宽</div>
</div>
.parent{
height: 300px;
/* margin-left对应的是left这个元素的宽度 */
margin-left: 300px;
/* margin-right对应的是right这个元素的宽度 */
margin-right: 300px;
/* 此时左右就空出了可以放left这一列和right这一列的位置 */
}
.left,.center,.right{
height: 300px;
float: left;
}
/* 左列和右列定宽 */
.left,.right{
width: 300px;
}
.left{
background-color: aqua;
/* 将当前元素从当前行,移动上一行同一个位置 */
margin-left: -100%;
/* 开启定位 相对定位不会脱离文档流 */
position: relative;
/* 向左移动定宽的px */
left: -300px;
}
.center{
/* 为父级元素的100% */
width: 100%;
background-color: #c60023;
}
.right{
background-color: pink;
margin-left: -300px;
position: relative;
/* right为负值表示向右移动,移动的距离是当前元素的宽度 */
right: -300px;
}
2. 双飞翼布局
双飞翼布局是针对圣杯布局的优化解决方案,主要是优化了圣杯布局中,定宽列开启定位的问题
即在自适应元素下再加一个div
<div class="parent">
<!--为了利于搜索引擎抓取 center需要放在前面-->
<div class="center">
<div class="inner"></div>
</div>
<div class="left">左列定宽</div>
<div class="right">右列定宽</div>
</div>
.parent{
height: 300px;
}
.left,.center,.right{
height: 300px;
float: left;
}
/* 左列和右列定宽 */
.left,.right{
width: 300px;
}
.left{
background-color: aqua;
/* 将当前元素从当前行,移动上一行同一个位置 */
margin-left: -100%;
}
.center{
/* 为父级元素的100% */
width: 100%;
background-color: #c60023;
}
.right{
background-color: pink;
margin-left: -300px;
}
.inner{
height: 300px;
background-color: yellow;
/* margin-left对应的是left这个元素的宽度 */
margin-left: 300px;
/* margin-right对应的是right这个元素的宽度 */
margin-right: 300px;
}
3. grid实现
<div class="parent">
<div class="header"></div>
<!--#center需要放在前面-->
<div class="center">中间自适应
<hr>
</div>
<div class="left">左列定宽</div>
<div class="right">右列定宽</div>
<div class="footer"></div>
</div>
.parent {
height: 500px;
display: grid;
grid-template-columns: 100px auto 200px; /*设定3列*/
grid-template-rows: 60px auto 60px; /*设定3行*/
/*设置网格区域分布*/
grid-template-areas:
"header header header"
"leftside main rightside"
"footer footer footer";
}
.header {
grid-area: header; /*指定在哪个网格区域*/
background-color: #ccc;
}
.left {
grid-area: leftside;
background-color: #f00;
opacity: 0.5;
}
.center {
grid-area: main; /*指定在哪个网格区域*/
margin: 0 15px; /*设置间隔*/
border: 1px solid #000;
background-color: #eeff2b;
}
.right {
grid-area: rightside; /*指定在哪个网格区域*/
background-color: #0f0;
opacity: 0.5;
}
.footer {
grid-area: footer; /*指定在哪个网格区域*/
background-color: #ccc;
}
4. table实现
<div class="parent">
<div class="left">左列定宽</div>
<div class="center">中间自适应</div>
<div class="right">右列定宽</div>
</div>
.parent {
width: 100%;
height: 500px;
display: table;
}
.left {
display: table-cell;
width: 100px;
background-color: #f00;
}
.center {
display: table-cell;
background-color: #eeff2b;
}
.right {
display: table-cell;
width: 200px;
background-color: #0f0;
}
5. flex实现
<div class="parent">
<div class="left">左列定宽</div>
<div class="center">中间自适应</div>
<div class="right">右列定宽</div>
</div>
.parent {
height: 500px;
display: flex;
}
.left {
width: 100px;
background-color: #f00;
}
.center {
flex: 1; /*均分#parent剩余的部分*/
background-color: #eeff2b;
}
.right {
width: 200px;
background-color: #0f0;
}
6. position实现
<div class="parent">
<div class="left">左列定宽</div>
<div class="center">中间自适应</div>
<div class="right">右列定宽</div>
</div>
.parent {
position: relative; /*子绝父相*/
}
.left {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 500px;
background-color: #f00;
}
.center {
height: 500px;
margin-left: 100px; /*大于等于#left的宽度,或者给#parent添加同样大小的padding-left*/
margin-right: 200px; /*大于等于#right的宽度,或者给#parent添加同样大小的padding-right*/
background-color: #eeff2b;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 500px;
background-color: #0f0;
}
优点和缺点
缺点:需要把center位置放到中间
多列布局
多列布局就是几个元素呈现水平方式排列的效果
- 块级元素默认是垂直方向排列,给他们设置浮动即可让他们,水平排列
- 内 元素默认本身就是水平方向排列的
- 行内块级元素也是默认水平方向排列的
CSS3多列布局
columns属性
- columns属性是一个简写属性
- column-count属性:定义列的数量或者允许的最大列数
- auto 为默认值,用于表示列的数量由其他css属性决定
- number 必须是正整数,用于定义列数量
- column-width属性:定义列的宽度
- auto 为默认值,用于表示列的数量由其他css属性决定
- lenght 必须是正整数,用于定义列的宽度
- column-count属性:定义列的数量或者允许的最大列数
column-gap属性
column-gap属性定义用columns属性设置的列后的间距
column-gap
- normal 规定列间间隔为一个常规的间隔。W3C 建议的值是 1em
- length 必须是正整数,把列间的间隔设置为指定的长度
column-rule属性
column-rule属性 用于定义列与列之间的边框属性,其中包括边框的宽度、边框颜色以及边框样式
- column-rule-width 设置边框的宽度
- column-rule-style 设置边框线条的样式
- column-rule-color 设置边框的颜色
注意:只是间隙中的边框,并不是围绕上下左右
column-span 横跨多列属性
column-span属性用于定义一个列元素是否跨列
- none:用于表示元素不跨列
- all 用于表示元素跨所有列
- 1 用于表示元素跨一列
column-fill 列的填充属性
column-fill属性用于定义列的高度是由内容决定,还是统一高度
- auto 默认值,用于表示列的高度由内容决定
- balance 用于表示列的高度根据内容最多的一列为准
等分布局(多列等宽)
等分布局就是一行被分为若干列,每一列的宽度是相同的值
1. float属性配合宽度百分比实现
要点
由于div默认宽度是100%,给子级元素设置浮动后,需要给子元素设置均分的宽度百分比和高度
<!-- 作为父级容器出现 -->
<div class="parent">
<div class="col1"></div>
<div class="col2"></div>
<div class="col3"> </div>
<div class="col4"> </div>
</div>
.col1,.col2,.col3,.col4{
float: left;
/* 由于div默认宽度是100%,高度是0,所以需要设置高度 */
height: 300px;
/* 由于是4列等分,每列就是25% */
width: 25%;
}
.col1{
background-color: hotpink;
}
.col2{
background-color: aqua;
}
.col3{
background-color: yellowgreen;
}
.col4{
background-color: green;
}
优点和缺点
优点:简单易懂
缺点:需要给子元素设置高度,或者需要手动清除浮动,否则会产生高度塌陷
2. display属性配合table实现
要点
父容器设置宽度为100%,display: table子元素设置table-cell
<!-- 作为父级容器出现 -->
<div class="parent">
<div class="col1"></div>
<div class="col2"></div>
<div class="col3"> </div>
<div class="col4"> </div>
</div>
.parent{
/* 认为设置宽度为父级的100% */
width: 100%;
/* display: table相当于table元素 */
display: table;
}
.col1,.col2,.col3,.col4{
/* 由于div默认宽度是100%,高度是0,所以需要设置高度 */
height: 300px;
/* display: table-cell相当于td元素,由于表格的特点,它会被自动分配宽度 */
display: table-cell;
}
.col1{
background-color: hotpink;
}
.col2{
background-color: aqua;
}
.col3{
background-color: yellowgreen;
}
.col4{
background-color: green;
}
3. 间距问题
间距
公式:间距+容器宽度=(间距+列宽度)x N
4. float边距问题解决思路
给子元素添加一个容器
<div class="parent-fix">
<!-- 作为父级容器出现 -->
<div class="parent">
<div class="col1">
<div class="inner">
</div>
</div>
<div class="col2">
<div class="inner">
</div>
</div>
<div class="col3">
<div class="inner">
</div> </div>
<div class="col4">
<div class="inner">
</div> </div>
</div>
</div>
.parent{
height: 300px;
/* 移走左边的10px边距 */
margin-left: -10px;
}
.col1,.col2,.col3,.col4{
float: left;
/* 由于div默认宽度是100%,高度是0,所以需要设置高度 */
height: 300px;
/* 由于是4列等分,每列就是25% */
width: 25%;
/* 子元素各自向右挤压10px */
padding-left: 10px;
box-sizing: border-box;
/* 原本的页面宽度是 各个子元素的25% + 和各自元素的padding-left值
设置成border-sizing后,整个盒子,包括padding值在内,就是25%,向内收缩,此时无论怎么去设置padding值,都不会影响这个元素在页面中所占的区域
*/
}
.inner{
height: 300px;
}
.col1 .inner{
background-color: hotpink;
}
.col2 .inner{
background-color: aqua;
}
.col3 .inner{
background-color: yellowgreen;
}
.col4 .inner{
background-color: green;
}
要点
给子元素添加一个容器元素后,给子元素padding-left(同时配合box-sizing: border-box,防止内容撑爆影响所占区域),使用margin-left的负值挤出左边的间距
优点和缺点
优点:代码简单,容易理解;兼容性较好
缺点:需要记得给父元素高度,或者使用overflow:hidden,避免高度塌陷
5. table边距问题
<div class="parent-fix">
<!-- 作为父级容器出现 -->
<div class="parent">
<div class="col1">
<div class="inner">
</div>
</div>
<div class="col2">
<div class="inner">
</div>
</div>
<div class="col3">
<div class="inner">
</div> </div>
<div class="col4">
<div class="inner">
</div> </div>
</div>
.parent-fix{
overflow: hidden;
}
.parent{
/* 此时外层容器的宽度应等于 当前容器的宽度减去边距的宽度 ,经过测试发现parent宽度为1520,此时把外层父容器的宽度设置1510即可,但是在实际开发定宽中,只要保证此等式成立即可 */
width: 100%;
display: table;
margin-left: -10px;
}
.col1,.col2,.col3,.col4{
height: 300px;
display: table-cell;
box-sizing: border-box;
padding-left: 10px;
/* 此时,.parent-fix 多出10px的右边距 */
}
.inner{
height: 300px;
}
.col1 .inner{
background-color: hotpink;
}
.col2 .inner{
background-color: aqua;
}
.col3 .inner{
background-color: yellowgreen;
}
.col4 .inner{
background-color: green;
}
要点
给子元素添加 padding-left的同时,要给父元素margin-left赋值,抵消最左边的边距
此外由于用户浏览器和设备等原因,分辨率大小不一样,需要保证此等式成立即可:外层父容器的宽度=当前容器的宽度-边距
优点和缺点
优点:table自动划分
缺点:需要保证此公式(外层父容器的宽度=当前容器的宽度-边距)成立,即可保证外层容器最右侧,不会也出现边距
等高布局
1. display属性配合table属性
div class="parent">
<div class="left">左边测试</div>
<div class="right">大熊猫(学名:Ailuropoda melanoleuca):属于食肉目、熊科、大熊猫亚科和大熊猫属唯一的哺乳动物。仅有二个亚种。雄性个体稍大于雌性。体型肥硕似熊、丰腴富态,头圆尾短,头躯长1.2-1.8米,尾长10-12厘米。体重80-120千克,最重可达180千克,体色为黑白两色,脸颊圆,有大的黑眼圈,标志性的内八字的行走方式,也有解剖刀般锋利的爪子。大熊猫皮肤厚,最厚处可达10毫米。黑白相间的外表,有利于隐蔽在密林的树上和积雪的地面而不易被天敌发现。</div>
</div>
.parent{
display: table-cell;
}
.left,.right{
width: 300px;
display: table-cell;
}
.left{
background-color: aqua;
}
.right{
background-color: pink;
}
要点
表格中的单元格默认是等高的,无论内容多少
2. padding配合margin属性实现
dy>
<div class="parent">
<div class="left">左边测试</div>
<div class="right">大熊猫(学名:Ailuropoda melanoleuca):属于食肉目、熊科、大熊猫亚科和大熊猫属唯一的哺乳动物。仅有二个亚种。雄性个体稍大于雌性。体型肥硕似熊、丰腴富态,头圆尾短,头躯长1.2-1.8米,尾长10-12厘米。体重80-120千克,最重可达180千克,体色为黑白两色,脸颊圆,有大的黑眼圈,标志性的内八字的行走方式,也有解剖刀般锋利的爪子。大熊猫皮肤厚,最厚处可达10毫米。黑白相间的外表,有利于隐蔽在密林的树上和积雪的地面而不易被天敌发现。</div>
</div>
.parent{
overflow: hidden;
}
.left,.right{
width: 300px;
float: left;
/* padding和margin互相对冲 */
padding-bottom: 9999px;
/* margin-bottom为赋值,表示向上移动 */
margin-bottom: -9999px;
}
.left{
background-color: aqua;
}
.right{
background-color: pink;
}
要点
使用margin极大的负值荷padding极大的正值相冲,给子元素设置浮动后,再给父元素设置overflow:hidden
但是这种实现的并不是真正的等高布局,只是视觉上等高的伪等高布局
全屏布局
全屏布局是指HTML页面铺满整个浏览器窗口,并且没有滚动条。而且还可以根据浏览器大小变化而变化,高度和宽度达到自适应的效果,其次在垂直方向中作为主要内容的承载者,第2行的高度是自适应的
1. 固定定位
<header></header>
<div class="content">
<div class="left"></div>
<div class="right"></div>
</div>
<footer></footer>
/* 清除默认样式 body的默认像素是8px */
html,body{
margin: 0;
overflow: hidden;
}
header{
/* width默认为父级元素的100% */
height: 100px;
/* 头部固定在窗口顶部 */
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: lightgray;
}
.content{
position: fixed;
left: 0;
right: 0;
/* top等于header的高度 bottom等于footer的高度 */
top: 100px;
bottom: 100px;
background-color: lightblue;
overflow: auto;
}
/* 中部内容区 定宽+自适应 */
.content .left{
width: 300px;
height: 100%;
position: fixed;
left: 0;
/* top等于header的高度 bottom等于footer的高度 */
top: 100px;
bottom: 100px;
background-color: lightcoral;
}
.content .right{
/* div是块元素,块元素默认高度为后代元素高度之和 */
height: 1000px;
margin-left: 300px;
background-color: greenyellow;
}
footer{
height: 100px;
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: lightslategray;
}
2. 绝对定位
<div class="parent">
<div class="top">top</div>
<div class="left">left</div>
<div class="right">right</div>
<div class="bottom">bottom</div>
</div>
html, body, .parent {height: 100%;overflow: hidden;}
.parent > div {
border: 1px solid #000;
}
.top {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100px;
background-color: lightgray;
}
.left {
position: absolute;
top: 100px; /*值大于等于.top的高度*/
left: 0;
bottom: 50px; /*值大于等于.bottom的高度*/
width: 200px;
background-color: pink;
}
.right {
position: absolute;
overflow: auto;
left: 200px; /*值大于等于.left的宽度*/
right: 0;
top: 100px; /*值大于等于.top的高度*/
bottom: 50px; /*值大于等于.bottom的高度*/
background-color: aqua;
}
.bottom {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 50px;
background-color: lightslategray;
}
###3. flex
<div class="parent">
<div class="top">top</div>
<div class="middle">
<div class="left">left</div>
<div class="right">right</div>
</div>
<div class="bottom">bottom</div>
</div>
*{
margin: 0;
padding: 0;
}
html,body,.parent{
height:100%;
}
.parent {
display: flex;
flex-direction: column;
background-color: pink;
}
.top {
height: 100px;
background-color: lightgray;
}
.bottom {
height: 50px;
background-color: lightslategray;
}
.middle {
flex: 1;
display: flex;
}
.left {
width: 200px;
background-color: limegreen;
}
.right {
flex: 1;
overflow: auto;
background-color: skyblue;
}
4. grid
<div class="parent">
<div class="top">top</div>
<div class="left">left</div>
<div class="right">right</div>
<div class="bottom">bottom</div>
</div>
*{
margin: 0;
padding: 0;
}
html, body, .parent {
height: 100%;
}
.parent {
width: 100%;
height: 100%;
display: grid;
/*分成2列,第一列宽度200px,第二列1fr平分剩余的部分,此处换成auto也行*/
grid-template-columns: 200px 1fr;
/*分成3行,第一行高度100px,第二行auto为自适应,此处换成1fr也行,第3行高度为50px*/
grid-template-rows: 100px auto 50px;
/*定义网格区域分布*/
grid-template-areas:
"header header"
"aside main"
"footer footer";
}
.parent>div{
border: 1px solid #000;
}
.top{
grid-area: header; /*指定在哪个网格区域*/
background-color: lightgray;
}
.left{
grid-area: aside; /*指定在哪个网格区域*/
background-color: skyblue;
}
.right{
grid-area: main; /*指定在哪个网格区域*/
background-color: yellow;
}
.bottom{
grid-area: footer; /*指定在哪个网格区域*/
background-color: lightsalmon;
}