CSS 多栏布局
栅格系统,是 bootstrap 常用的布局模式,下列就举个简单四栏例子
html:
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
css:
.col{
width:25%;
height:500px;
float: left;
background: #ccc;
}
.col:nth-child(1){
background: red;
}
.col:nth-child(2){
background: green;
}
.col:nth-child(3){
background: black;
}
.col:nth-child(4){
background: yellow;
}
常见还有 column-count、column-gap、column-rule、columns
- 弹性布局 (flex) html:
<ul>
<li><a href="#">菜单1</a></li>
<li><a href="#">菜单2</a></li>
<li><a href="#">菜单3</a></li>
<li><a href="#">菜单4</a></li>
</ul>
css:
ul{
display: flex;
height:100px;
width:100%;
}
ul li{
flex: auto;
list-style:none;
text-align:center;
border:1px solid red;
}
CSS 等宽布局
//假如是n个child
<div class="parent-fix">
<div class="parent">
<div class="child"><p>1</p></div>
<div class="child"><p>2</p></div>
<div class="child"><p>3</p></div>
<div class="child"><p>4</p></div>
</div>
</div>
table
.parent-fix{
margin-left: -20px;
}
.parent{
display: table;
width: 100%;
table-layout: fixed;
}
.child{
display: table-cell;
padding-left: 20px;
}
flex
.parent{
display: flex;
}
.child{
flex: 1;
}
.child+.child {
margin-left: 20px;
}
等高布局
<div class="parent" style="background: black;">
<div class="left" style="background: red;">
<p>left</p>
</div>
<div class="right" style="background: green;">
<p>right</p>
<p>right</p>
</div>
</div>
table
.parent{
display: table;
width: 100%;
table-layout: fixed;
}
.left,.right{
display: table-cell;
}
.left{
width: 100px;
border-right: 20px solid transparent;
background-clip: padding-box;
}
flex
.parent{
display: flex;
}
.right{
flex: 1;
}
.left{
width: 100px;
margin-right: 20px;
}
float
//部分UI框架采用的就是这种方式,
.parent{
overflow: hidden;
}
.left{
float: left;
margin-right: 20px;
}
.right{
overflow: hidden;
}
.left,.right{
padding-bottom: 9999px;
margin-bottom: -9999px;
}
等分等高
5,等分
float + margin
.parent {
margin-left: -20px;
}
.column {
float: left;
width: 25%;
padding-left: 20px;
box-sizing: border-box;
}
table + margin
.parent-fix{
margin-left: -20px;
}
.parent{
display: table;
width:100%;
table-layout: fixed;
}
.column{
display: table-cell;
padding-left: 20px;
}
flex
.parent{
display: flex;
}
.column{
flex: 1;
}
.column+.column{
margin-left: 20px;
}
6,等高
float + overflow
.parent {
overflow: hidden;
}
.left,.right {
padding-bottom: 9999px;
margin-bottom: -9999px;
}
.left {
float: left;
width: 100px;
}
.right {
overflow: hidden;
}
table
.parent {
display: table;
width: 100%;
}
.left {
display:table-cell;
width: 100px;
margin-right: 20px;
}
.right {
display:table-cell;
}
flex
.parent {
display:flex;
width: 100%;
}
.left {
width: 100px;
}
.right {
flex:1;
}
7,并排等分,单排对齐靠左布局
.main {
display: flex;
flex-flow: row-wrap;
justify-content: space-between;
}
.item {
display: inline-block;
}
.empty {
height: 0;
visibility: hidden;
}
6.1 等宽布局
6.1.1四列等宽
(1)使用float实现▲
效果图:
image.png
html代码:
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
css代码:
/*使整体内容看起来居中,抵消padding-left的影响*/
#parent {margin-left: -20px;}
.column{
padding-left: 20px; /*盒子的边距*/
width: 25%;
float: left;
box-sizing: border-box;
border: 1px solid #000;
background-clip: content-box; /*背景色从内容开始绘制,方便观察*/
height: 500px;
}
.column:nth-child(odd){background-color: #f00;}
.column:nth-child(even){background-color: #0f0;}
原理:根据父元素空间宽度平分,子元素设置浮动,用padding去模拟间隔,再给父元素一个位移抵消第一个间隔
优缺点:
优点:代码简单,容易理解;兼容性较好(ie8+) 缺点:需要手动清除浮动,否则会产生高度塌陷;由于是百分比平分宽度不能设置margin,否则占位超出父元素宽度换行显示
(2)使用table实现▲
效果图:
image.png
html代码:
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
css代码:
#parent {
height: 540px; /*抵消上下边20*2间距的高度影响*/
display: table;
margin: -20px 0; /*抵消上下边20*2间距的位置影响*/
/*两边离页面间距无法消除,改用子元素设置padding来当成间隔就不会有这样的问题*/
border-spacing: 20px; /*设置间距*/
}
.column{display: table-cell;}
.column:nth-child(odd){background-color: #f00;}
.column:nth-child(even){background-color: #0f0;}
原理:CSS Table以表格的形式显示
优缺点:
优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素
(3)使用flex实现
效果图:
image.png
html代码:
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
css代码:
#parent {
margin-left: -15px; /*使内容看起来居中*/
height: 500px;
display: flex;
}
.column{
flex: 1; /*一起平分#parent*/
margin-left: 15px; /*设置间距*/
}
.column:nth-child(odd){background-color: #f00;}
.column:nth-child(even){background-color: #0f0;}
原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐
优缺点
优点:简单灵活;功能强大 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer
6.1.2多列等宽
效果图:
image.png
(1)使用float实现▲
html代码:
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
css代码:
#parent {height: 500px;}
.column{
float: left; /*添加浮动*/
width: 16.66666666666667%; /*100÷列数,得出百分比*/
height: 500px;
}
.column:nth-child(odd){background-color: #f00;}
.column:nth-child(even){background-color: #0f0;}
原理:根据父元素空间宽度平分,子元素设置浮动,用padding去模拟间隔,再给父元素一个位移抵消第一个间隔
优缺点:
优点:代码简单,容易理解;兼容性较好(ie8+) 缺点:需要手动清除浮动,否则会产生高度塌陷;由于是百分比平分宽度不能设置margin,否则占位超出父元素宽度换行显示
(2)使用table实现▲
html代码
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
css代码:
#parent {
width: 100%;
height: 500px;
display: table;
}
/*无需关注列数,单元格自动平分*/
.column{display: table-cell;}
.column:nth-child(odd){background-color: #f00;}
.column:nth-child(even){background-color: #0f0;}
原理:CSS Table以表格的形式显示
优缺点:
优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素
(3)使用flex实现
html代码:
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
css代码:
#parent {
height: 500px;
display: flex;
}
/*无需关注列数,一起平分#parent*/
.column{flex: 1;}
.column:nth-child(odd){background-color: #f00;}
.column:nth-child(even){background-color: #0f0;}
原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐
优缺点
优点:简单灵活;功能强大 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer
(4)使用Grid实现
html代码:
<body>
<div id="parent">
<div class="column">1 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">2 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">3 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">4 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">5 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
<div class="column">6 <p>我是文字我是文字我输文字我是文字我是文字</p></div>
</div>
</body>
css代码:
#parent {
height: 500px;
display: grid;
grid-template-columns: repeat(6,1fr); /*6就是列数*/
}
.column{}
.column:nth-child(odd){background-color: #f00;}
.column:nth-child(even){background-color: #0f0;}
原理:css grid布局,请查看文末的阅读推荐
优缺点
优点:灵活划分网格区域;新型布局利器,适用于页面三维布局 缺点:兼容性不好,移动端(Android5.0+)
6.2 九宫格布局
效果图:
image.png
(1)使用table实现▲
html代码:
<body>
<div id="parent">
<div class="row">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="row">
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div class="row">
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</div>
</body>
css代码:
#parent {
width: 1200px;
height: 500px;
margin: 0 auto;
display: table;
}
.row {display: table-row;}
.item {
border: 1px solid #000;
display: table-cell;
}
原理:CSS Table以表格的形式显示
优缺点:
优点:代码简单;容易理解;适用于宽度高度未知情况;兼容性好(ie8+) 缺点:margin失效;设置间隔比较麻烦;设置tabl-cell的元素,宽度和高度的值设置百分比无效,需要给它的父元素设置display: table; 才生效;table-cell不感知margin,在父元素上设置table-row等属性,也会使其不感知height;设置float或position会对默认布局造成破坏,可以考虑为之增加一个父div定义float等属性;内容溢出时会自动撑开父元素
(2-1)使用flex实现
html代码:
<body>
<div id="parent">
<div class="row">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="row">
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div class="row">
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</div>
</body>
css代码:
#parent {
width: 1200px;
height: 500px;
margin: 0 auto;
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex: 1;
}
.item {
flex: 1;
border: 1px solid #000;
}
原理:flex设置排列方式、对齐方式罢了,请查阅文末flex阅读推荐
优缺点
优点:简单灵活;功能强大 缺点:每三个一行,对于动态创建不确定数量的元素要控制好嵌套结构,PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer
(2-2)flex优化版(不需要遵守三个嵌套一行)
image.png
html代码:
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
css代码:
* {
margin: 0;
padding: 0;
}
ul {
width: 100%;
background-color: #ccc;
list-style: none;
display: flex;
flex-wrap: wrap;
}
ul > li {
width: 33.333333333333%;
height: 100px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #000;
}
原理:父元素flex并设置换行,子元素不设置伸缩,转而定宽设置宽三分之一,高度自定义,计算好宽度即能实现九宫格布局(也可以多列等宽布局)
优缺点
优点:简单;功能强大;不需要额外的嵌套关系,灵活运用于动态创建数量不等的元素布局中; 缺点:高度需要自定无法等宽,PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer
(2-3)flex再优化版(高度等宽九宫格)
image.png
html代码:
<body>
<ul>
<li>
<span>1</span>
</li>
<li>
<span>1</span>
</li>
<li>
<span>1</span>
</li>
<li>
<span>1</span>
</li>
</ul>
</body>
css代码:
*{
margin: 0;
padding: 0;
}
ul{
width: 100%;
margin: 0 auto;
background-color: #ccc;
list-style: none;
display: flex;
flex-wrap: wrap;
}
ul>li{
width: 33.33333%;
padding-top: 33.33333%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #000;
position: relative;
height: 0;
}
ul>li>span{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #999;
}
原理:无法实现高度等宽的原因是因为宽度根据百分比而定,无法通过px去确定高度,又由于padding,width,margin这些百分比都是相对于父元素宽度的,那么只要padding-top或者padding-bottom和width的百分比一样,就能实现一个元素宽高相等,同时利用子绝父相,让子元素占满这个盒子就实现正方形的效果了,此处的span换成img同样可行,这个特性同时也适用于之前介绍的布局(比如float…)。单纯一个正方形效果,除去flex,兼容ie8+
优缺点
优点:简单;功能强大;高度等宽;不需要额外的嵌套关系,灵活运用于动态创建数量不等的元素布局中 缺点:PC端兼容性不好,移动端(Android4.0+) flex务必带上兼容,写法请参考文末阅读推荐,也可以使用autoprefixer
(3)使用Grid实现
CSS Grid非常强大,可以实现各种各样的三维布局,可查阅本文结尾的阅读推荐
html代码:
<body>
<div id="parent">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
css代码:
#parent {
width: 1200px;
height: 500px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(3, 1fr); /*等同于1fr 1fr 1fr,此为重复的合并写法*/
grid-template-rows: repeat(3, 1fr); /*等同于1fr 1fr 1fr,此为重复的合并写法*/
}
.item {border: 1px solid #000;}
6.3 栅格系统▲
优缺点:
优点:代码简洁,容易理解;提高页面内容的流动性,能适应多种设备; 缺点:浮动脱离文档流,需要清除浮动;由于是百分比平分宽度不能设置margin,否则占位超出父元素宽度换行显示
(1)用Less生成
/*生成栅格系统*/
@media screen and (max-width: 768px){
.generate-columns(12); /*此处设置生成列数*/
.generate-columns(@n, @i: 1) when (@i <= @n) {
.column-xs-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i+1));
}
}
@media screen and (min-width: 768px){
.generate-columns(12); /*此处设置生成列数*/
.generate-columns(@n, @i: 1) when (@i <= @n) {
.column-sm-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i+1));
}
}
div[class^="column-xs-"]{
float: left;
}
div[class^="column-sm-"]{
float: left;
}
编译后的CSS代码:
@media screen and (max-width: 768px) {
.column-xs-1 { width: 8.33333333%; }
.column-xs-2 { width: 16.66666667%; }
.column-xs-3 { width: 25%; }
.column-xs-4 { width: 33.33333333%; }
.column-xs-5 { width: 41.66666667%; }
.column-xs-6 { width: 50%; }
.column-xs-7 { width: 58.33333333%; }
.column-xs-8 { width: 66.66666667%; }
.column-xs-9 { width: 75%; }
.column-xs-10 { width: 83.33333333%; }
.column-xs-11 { width: 91.66666667%; }
.column-xs-12 { width: 100%; }
}
@media screen and (min-width: 768px) {
.column-sm-1 { width: 8.33333333%; }
.column-sm-2 { width: 16.66666667%; }
.column-sm-3 { width: 25%; }
.column-sm-4 { width: 33.33333333%; }
.column-sm-5 { width: 41.66666667%; }
.column-sm-6 { width: 50%; }
.column-sm-7 { width: 58.33333333%; }
.column-sm-8 { width: 66.66666667%; }
.column-sm-9 { width: 75%; }
.column-sm-10 { width: 83.33333333%; }
.column-sm-11 { width: 91.66666667%; }
.column-sm-12 { width: 100%; }
}
div[class^="column-xs-"]{
float: left;
}
div[class^="column-sm-"]{
float: left;
}
★本章小结:
- 对于多列等宽布局,目前常用的还是浮动,宽度按百分比去平分。要是百分比的话就不太好设置margin,只能用padding去模拟间隔。又或者是固定宽度,计算好间隔,刚好填满或接近填满,这样倒是可以直接设置margin;
- 除了浮动,其实还可以用到inline-block,但是要注意html换行或空格都会占位,有可能导致空间不够换行显示,这样就要给父元素设置一个font-size:0,然后再给设置inline-block的盒子设置所需要大小的font-size;
- 然后就是css table布局了,想划分多少列都可以,灵活简单,就是一些不感知属性要注意;
- 移动端兼容性允许的情况下能用flex就用flex,务必带上兼容,写法可参考文末阅读推荐,也可以使用Autoprefixer;