页面布局的几种方式
2019-08-09 本文已影响0人
KevinLee0424
居中布局
一、水平居中布局
- 水平居中:absolute + transform: translateX(-50%)
另外:除了transform: translateX(-50%)这种方式以外,还可以采用给子容器设置负margin值的方法实现居中(其绝对值必须为子容器宽度的一半),但前提是必须要知道子容器的宽度,也就是说子元素要定宽。
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
position: relative;
/* 如果不写这句,下面子元素的定位将不会是相对父级的绝对定位 */
}
.child {
position: absolute;
left: 50%;
transform: translateX(-50%); /* 相对自身偏移-50% */
}
- 水平居中:flex + justify content: center
另外:除了给父容器设置justify-content:center这种方式以外,还可以采用在子容器设置margin:0 auto的方法实现居中,因为flex元素是支持margin: 0 auto的。
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
display: flex; /* flex布局 */
justify-content: center;
}
- 水平居中:inline-block + text-align: center在使用inline-block布局时需要注意的是:
A:vertical-align属性会影响到inline-block元素,你可能会想把它的值设置为top;
B:设置在父容器的text-align:center会继承到子容器,如果要改变子容器的text-align属性,则需要重新设置进行覆盖;
C:如果HTML源代码中元素之间有空格,那么列与列之间会产生空隙。
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
text-align: center;
/* text-align设置在块级元素的时候可以对里面的inline元素起作用 */
}
.child {
display: inline-block;
}
- 水平居中:table + margin: 0 auto
给子元素设置display:table属性,并且不设置宽度时,可以使其宽度由内容撑开,适合需要宽度自适应的水平居中布局。
<div class="parent">
<div class="child">DEMO</div>
</div>
.child {
display: table;
/* table在没有对它进行宽度100%的设置的时候,它的宽度就是和内容一样宽 */
margin: 0 auto;
}
- 水平居中:table-cell + text-align: center + inline-block
display:table-cell属性指让标签元素以表格单元格的形式呈现,类似于td标签。td单元格有一些比较特别的属性,例如元素的垂直居中对齐,关联伸缩等,所以display:table-cell还是有不少潜在的使用价值的。需要注意的是:
A:与其他一些display属性类似,table-cell同样会被其他一些CSS属性破坏,例如float,position:absolute,所以,在使用display:table-cell时,与float:left或是position:absolute属性尽量要同时使用;
B:设置了display:table-cell的元素对宽度高度敏感,对margin值无反应,响应padding属性,基本上就是活脱脱的一个td标签元素了。
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
display: table-cell;
text-align: center;
}
.child {
display: inline-block;
}
二、垂直居中布局
- 垂直居中:absolute + transform: translateY(-50%)
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
position: relative;
/* 如果不写这句,下面子元素的定位将不会是相对父级的绝对定位 */
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%); /* 相对自身偏移-50% */
}
- 垂直居中:flex + align-items
注意:如果不设置align-items:center,那么其默认值则是stretch,这时子容器将撑满父容器的高度;
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
display: flex;
align-items: center; /* 默认值是stretch, 即拉伸, 改为center即可居中 */
}
- table-cell + vertical-align
display:table-cell这里要提醒一下需要注意:
A:与其他一些display属性类似,table-cell同样会被其他一些CSS属性破坏,例如float, position:absolute,所以,在使用display:table-cell时,与float:left或是position:absolute属性尽量不要同时使用;
B:设置了display:table-cell的元素对宽度高度敏感,对margin值无反应,响应padding属性,基本上就是活脱脱的一个td标签元素了。
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
display: table-cell;
vertical-align: middle;
}
三、水平方向和垂直方向同时居中布局
- 同时居中:absolute + transform: translate(-50%, -50%)
另外:除了transform: translate(-50%, -50%)这种方式以外,还可以采用给子容器设置负margin值的方法实现居中(其绝对值必须为子容器宽度和高度的一半),但前提是必须要知道子容器的宽度和高度,也就是子元素要定宽定高。
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
position: relative;
/* 如果不写这句,下面子元素的定位将不会是相对父级的绝对定位 */
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 相对自身偏移-50% */
}
- 同时居中:inline-block + text-align: center + table-cell + vertical-align
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.child {
display: inline-block;
}
- 同时居中:flex + justify-content + align-items
<div class="parent">
<div class="child">DEMO</div>
</div>
.parent {
display: flex;
justify-content: center;
align-items: center; /* 默认值是stretch, 即拉伸, 改为center即可居中 */
}
多列布局
一、定宽 + 自适应
left和center容器定宽,right容器自适应。
- float + margin
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.left {
float: left;
width: 100px;
}
.right {
margin-left: 120px; /* 多出的20px作为left容器与right容器之间的边距 */
}
- float + overflow
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.left, .center {
float: left;
width: 100px;
margin-right: 20px; /* 边距 */
}
.right {
overflow: hidden; /* BFC原理 */
}
- table
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.parent {
display: table;
width: 100%; /* 如果不设置,宽度将由内容决定 */
table-layout: fixed;
/* 如果不设置,table内部子容器的宽度可能会被内容影响,即使设置了子容器的宽度也是如此 */
}
.left, .center, .right {
display: table-cell;
}
.left, .center {
width: 100px;
padding-right: 20px;
/* table-cell相当于td元素,是不能设置margin的,所以用padding代替 */
}
- flex
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.parent {
display: flex;
}
.left, .center {
width: 100px;
margin-right: 20px; /* 边距 */
}
.right {
flex: 1; /* flex: 1 1 0%; */
}
二、不定宽 + 自适应
left和center容器不定宽(即宽度由内容撑开),right容器自适应。
- float + overflow
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.left, .center {
float: left;
margin-right: 20px; /* 边距 */
}
.right {
overflow: hidden;
}
- table
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.parent {
display: table;
width: 100%; /* 如果不设置,宽度将由内容决定 */
/* 这里不设置table-layout: fixed,因为我们需要table内部子容器的宽度由内容决定 */
}
.left, .center, .right {
display: table-cell;
}
.left, .center {
width: 0.1%; /* table-cell的特性,内容优先 */
padding-right: 20px;
/* table-cell相当于td元素,是不能设置margin的,所以用padding代替 */
}
- flex
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="center">
<p>center</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.parent {
display: flex;
}
.left, .center {
margin-right: 20px; /* 边距 */
}
.right {
flex: 1; /* flex: 1 1 0%; */
}
三、等宽
当父容器中有N个列时,它们的列宽相等,并且当父容器变宽(或变窄)时,这些列也要相应的变宽(或变窄)。
- float
<div class="parent">
<div class="column"><p>1</p></div>
<div class="column"><p>2</p></div>
<div class="column"><p>3</p></div>
<div class="column"><p>4</p></div>
</div>
.parent {
margin-left: -20px;
/* 将父容器撑开20px,但名义宽度不变,这20px是内部列与列之间的边距 */
}
.column {
float: left;
width: 25%; /* 由列数决定 */
padding-left: 20px; /* 列与列之间的边距 */
box-sizing: border-box; /* 意味着padding-left值被包含在25%的宽度中 */
}
- table
<div class="parent-fix">
<div class="parent">
<div class="column"><p>1</p></div>
<div class="column"><p>2</p></div>
<div class="column"><p>3</p></div>
<div class="column"><p>4</p></div>
</div>
</div>
.parent-fix {
margin-left: -20px;
/* 将父容器撑开20px,但名义宽度不变,这20px是内部列与列之间的边距,但是table不能设置margin值,所以在parent外面再加一个修正用的容器 */
}
.parent {
display: table;
width: 100%;
table-layout: fixed; /* 设置为fixed时,列宽会相等 */
}
.column {
display: table-cell;
padding-left: 20px; /* 列与列之间的边距 */
}
- flex
<div class="parent">
<div class="column"><p>1</p></div>
<div class="column"><p>2</p></div>
<div class="column"><p>3</p></div>
<div class="column"><p>4</p></div>
</div>
.parent {
display: flex;
}
.column {
flex: 1;
}
.column + .column {
margin-left: 20px;
}
四、等高
- table
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.parent {
display: table;
width: 100%;
table-layout: fixed;
}
.left, .right {
display: table-cell;
}
.left {
width: 100px; /* 不设置也没关系 */
border-right: 20px solid transparent; /* 通过border来设置间距 */
background-clip: padding-box;
/* 背景颜色默认会显示到border部分,也就是border-box,所以这里设置到padding-box */
}
- flex
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.parent {
display: flex;
}
.left {
width: 100px;
margin-right: 20px;
}
.right {
flex: 1;
}
- float
伪等高方案,只是背景颜色一样高,不推荐。
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
.parent {
overflow: hidden; /* 必须 */
}
.left {
float: left;
width: 100px;
margin-right: 20px;
}
.right {
overflow: hidden;
}
.left, .right {
padding-bottom: 9999px;
margin-bottom: -9999px;
} /* 一升一降 */