一、简介
网页布局 对于一个前端开发者而言至关重要,把握好布局常识有助于咱们更好的实现 CSS 界面的设计和开发。布局是 无限空间内的元素排列形式 ,因为页面设计横向不滚动,纵向有限延长,所以大多数时候探讨的布局都是对程度方向进行宰割。罕用的布局形式为 单列布局 、 两列布局 、 三列布局 、 粘连布局 等。
二、单列布局
单列表布局是 将一个元素作为布局容器 ,通常 设置一个较小的 (最大) 宽度 来保障不同像素宽度屏幕下显示统一。
<body>
<div class="header"> 头部 </div>
<div class="content"> 单列布局 </div>
<div class="footer"> 底部 </div>
</body>
<style>
body{
margin: 0;
padding: 0;
}
.header {
margin: 0 auto;
max-width: 720px;
height: 100px;
background: red;
}
.content {
margin: 0 auto; /* 宽度足够的时候元素居中显示 */
max-width: 720px; /* 设置一个最大宽度,保障各种屏幕显示统一 */
height: 400px;
background: green;
}
.footer {
margin: 0 auto;
max-width: 720px;
height: 100px;
background: blue;
}
</style>
单列布局的劣势在于 基本上能够适配超过布局容器宽度的各种显示屏幕 ,能够保障 在超过设置的最大宽度的屏幕上 浏览网站看到的成果是统一的。而它的毛病就是 屏幕空间的节约,在屏幕空间足够大的状况下,页面两侧显示了大量空白,如果屏幕特地大,两侧空白的区域可能会比页面内容更宽。
二、两列布局
两列布局就是 将页面宰割成左右宽度不等的两列 , 宽度较小的列设置为固定宽度 , 残余宽度由另一列撑满 。这种布局 实用于内容上具备显著主次关系的网页 。
① float + margin 形式
通过让 左侧浮动 ,而后 给右侧设置一个 margin-left,值为左侧元素的宽度 即可。
<div class="container">
<div class="left">
左侧定宽
</div>
<div class="right">
右侧自适应
</div>
</div>
<style>
.container {
min-width: 500px;
height: 100px;
}
.left {
background: red;
width: 200px;
height: 100px;
float: left; /* 让左侧元素浮动 */
}
.right {
background: green;
width: 100%;
height: 100px;
margin-left: 200px; /* 给右侧元素增加一个 margin-left,为左侧区域留出空间 */
}
</style>
② 相对定位
首先给 父容器设置一个绝对定位 ,而后给 左侧元素设置一个相对定位 , 给右侧也设置一个相对定位,left 值为左侧元素的宽度,right 值为 0 ,即可。
<style>
.container {
height: 100px;
min-width: 500px;
position: relative; /* 父容器设置为绝对定位 */
}
.left {
background: red;
width: 200px;
height: 100px;
position: absolute;
left: 0;
}
.right {
background: green;
height: 100px;
position: absolute;
left: 200px; /* 值为左侧定宽元素的宽度 */
right: 0; /* 同时设置 left 和 right 能够实现宽度的自适应成果 */
}
</style>
③ Float + BFC
所谓 BFC 就是 Block fomatting context(块级格式化上下文),对于 BFC 盒子而言,其 领有一个独立的布局环境 ,BFC 容器外面的子元素不会影响到里面的元素,反之亦是如此。
BFC 容器绝对于一般的盒子而言,有一些个性:
a. 在同一个文档流中 ,BFC 的区域不会与 float box 重叠。
b. 为了不影响 BFC 容器外元素的布局 , 计算 BFC 的高度时,浮动元素也会参加计算。
如何让一个一般的盒子变成 BFC 容器?
- float 的值不是 none。
- position 的值不是 static 或者 relative
- display 的值是 inline-block、table-cell、flex、table-caption 或者 inline-flex
- overflow 的值不是 visible
<style>
.container {
height: 100px;
min-width: 500px;
}
.left {
background: red;
width: 200px;
height: 100px;
float: left;/* 左侧浮动 */
}
.right {
background: green;
height: 100px;
overflow: hidden; /* 让右侧变成一个 BFC 容器,防止与左侧浮动元素重合 */
}
</style>
④ Flex 实现
次要就是 给父容器设置成 flex 布局容器 ,而后 给右侧设置 flex 为 1 即可让右侧变成自适应。
<style>
.container {
height: 100px;
min-width: 500px;
display: flex; /* 给父容器设置为 flex 容器 */
}
.left {
background: red;
width: 200px;
height: 100px;
}
.right {
background: green;
height: 100px;
flex: 1; /* 给右侧设置成自适应 */
}
</style>
三、三列布局
三列布局依照左中右的程序进行排列,通常 两头列最宽 (自适应), 左右两列次之。三列布局绝对简单些,咱们会按步骤一步一步实现,如:
① 圣杯布局
<div class="container">
<div class="main"> 圣杯布局 </div>
<div class="left">left</div>
<div class="right">right</div>
</div>
所谓圣杯布局,就是 依据左右两侧元素的宽度 , 给父容器元素设置一个左右内边距 ,为了不便记忆,咱们能够了解成一开始父容器内是方形填满的, 给父容器增加左右内边距 ,咱们能够设想成 将圣杯压缩成形的过程。
<style>
.container {
background: yellow;
height: 100px;
padding: 0px 100px 0px 150px; /* 父元素增加内边距将圣杯压缩成形 */
}
.main {
background: green;
width: 100%;
height: 100px;
}
.left {
background: red;
width: 150px;
height: 100px;
}
.right {
background: blue;
width: 100px;
height: 100px;
}
</style>
因为目前左右两局部都在内容的垂直排列,所以接下来须要 给左中右三局部都增加一个左浮动 , 让三个元素程度排在一起 ,须要留神的是三个元素进行左浮动之后,左右两个元素依然在两头元素的上面,因为 两头元素设置的宽度是 100%,所以 两头元素会占满父元素,因为宽度无奈容下左右两块元素,所以左右两块元素会换行排列在一起,如:
<style>
.main {float: left; /* 让三个元素程度排列在一起 */}
.left {float: left; /* 让三个元素程度排列在一起 */}
.right {float: left; /* 让三个元素程度排列在一起 */}
</style>
此时左中右三个元素能够看做是程度排列在一起的,咱们能够通过 给左右两块元素设置一个负的 margin-left即可 让左右两块元素向右边挪动 。 左侧元素须要到最右边去 ,故其 margin-left 值为-100%,即两头元素的宽度, 右侧元素须要到最左边去 ,故其 margin-left 值为 负的右侧元素本身宽度。
<style>
.left {margin-left: -100%; /* 将左侧元素挪动两头元素的宽度,到最右边去 */}
.right {margin-left: -100px; /* 将右侧元素挪动负的本身宽度,到最左边去 */}
</style>
此时曾经能够看到左中右三个元素程度排列在一起,并且左侧元素在最右边,右侧元素在最左边,然而左侧元素其实应该是要在左侧黄色区域中,右侧元素应该在右侧黄色区域中才对,所以咱们须要 给左右两个元素一个绝对定位。左侧元素再向左挪动本身宽度的间隔,故其left 值为负的左侧元素本身宽度,右侧元素须要右侧挪动本身宽度的间隔,故其right 值为负的右侧元素本身宽度。
<style>
.left {
position: relative; /* 设置一个绝对定位 */
left: -150px; /* 绝对于以后地位向左挪动负的本身宽度 */
}
.right {
position: relative; /* 设置一个绝对定位 */
right: -100px; /* 绝对于以后地位向右挪动负的本身宽度 */
}
</style>
接下来咱们调整浏览器的宽度,发现元素产生了布局错乱,因为当浏览器宽度特地小的时候,容器元素也会跟着变小 ,而 左侧元素因为是浮动的 , 左侧元素要想上来,必须向左挪动一个负的本身宽度 ,因为左侧元素的 margin-left 值为 -100%,即 挪动了容器的可用内容宽度 , 当容器的可用内容宽度小于左侧元素的宽度的时候 (容器的 100% 值 < 左侧元素的本身宽度),左侧元素将无奈浮上来,只能换行显示。
而要想解决这个问题,咱们就 须要给容器设置一个最小宽度 ,这个最小宽度值怎么定呢?左侧元素要想不换行显示,那么容器的宽度必须可能包容左侧元素的大小,所以 容器内容区的最小值为左侧元素的宽度。
.container {min-width: 150px; /* 给容器设置一个最小宽度,值为左侧元素的宽度,避免换行显示 */}
残缺款式为:
<style>
.container {
background: yellow;
height: 100px;
padding: 0px 100px 0px 150px; /* 父元素增加内边距将圣杯压缩成形 */
min-width: 150px; /* 给容器设置一个最小宽度,值为左侧元素的宽度,避免换行显示 */
}
.main {
background: green;
width: 100%;
height: 100px;
float: left; /* 让三个元素程度排列在一起 */
}
.left {
background: red;
width: 150px;
height: 100px;
float: left; /* 让三个元素程度排列在一起 */
margin-left: -100%; /* 将左侧元素挪动两头元素的宽度,到最右边去 */
position: relative; /* 设置一个绝对定位 */
left: -150px; /* 绝对于以后地位向左挪动负的本身宽度 */
}
.right {
background: blue;
width: 100px;
height: 100px;
float: left; /* 让三个元素程度排列在一起 */
margin-left: -100px; /* 将右侧元素挪动负的本身宽度,到最左边去 */
position: relative; /* 设置一个绝对定位 */
right: -100px; /* 绝对于以后地位向右挪动负的本身宽度 */
}
</style>
② 双飞翼布局
<div class="container">
<div class="main">
<div class="content"> 双飞翼布局 </div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
所谓双飞翼布局,就是 给两头元素包裹一层 div 盒子 ,而后 依据左右两侧元素的宽度 , 给两头内容元素设置一个左右外边距 ,为了不便记忆,咱们能够了解成, 给两头增加左右外边距 ,就像 给两头元素加装了一双翅膀,从而造成双飞翼布局。
<style>
.container {
background: yellow;
height: 100px;
}
.main {width: 100%;}
.content {
background: green;
height: 100px;
margin-left: 150px; /* 给两头元素增加一个左外边距(翅膀)*/
margin-right: 100px; /* 给两头元素增加一个右外边距(翅膀)**/
}
.left {
background: red;
width: 150px;
height: 100px;
}
.right {
background: blue;
width: 100px;
height: 100px;
}
</style>
同样的,须要 给左中右三局部都增加一个左浮动 , 让三个元素程度排在一起,如:
<style>
.main {float: left; /* 让三个元素程度排列在一起 */}
.left {float: left; /* 让三个元素程度排列在一起 */}
.right {float: left; /* 让三个元素程度排列在一起 */}
</style>
同样的,须要给左侧增加一个负的 margin-left,值为 -100%,给右侧增加一个负的 margin-left,值为 负的右侧元素本身宽度大小 。
因为之前两头元素曾经设置好了左右外边距给左右两个元素留出了地位,所以增加 margin-left 之后就曾经实现了。
<style>
.left {margin-left: -100%; /* 将左侧元素挪动两头元素的宽度,到最右边去 */}
.right {margin-left: -100px; /* 将右侧元素挪动负的本身宽度,到最左边去 */}
</style>
同样的为了避免容器宽度太小导致左右两个元素换行显示,须要设置一个最小宽度。
.container {min-width: 400px; /* 给容器设置一个最小宽度,值为左侧元素的宽度,避免换行显示 */}
残缺款式如下:
<style>
.container {
background: yellow;
height: 100px;
min-width: 400px; /* 给容器设置一个最小宽度,值为左侧元素的宽度,避免换行显示 */
}
.main {
float: left;
width: 100%;
}
.content {
background: green;
height: 100px;
margin-left: 150px; /* 给两头元素增加一个左外边距(翅膀)*/
margin-right: 100px; /* 给两头元素增加一个右外边距(翅膀)**/
}
.left {
background: red;
width: 150px;
height: 100px;
float: left;
margin-left: -100%; /* 将左侧元素挪动两头元素的宽度,到最右边去 */
}
.right {
background: blue;
width: 100px;
height: 100px;
float: left;
margin-left: -100px; /* 将右侧元素挪动负的本身宽度,到最左边去 */
}
</style>
③ Flex 实现三列布局
Flex 实现三列布局绝对简略些,就是 将父容器设置为 flex 容器 , 两头元素设置 flex 值为 1 ,让其自适应残余宽度,将左右元素设置为禁止放大,即 flex-shrink 值设置为 0.
<div class="container">
<div class="left">left</div>
<div class="main">flex 三列布局 </div>
<div class="right">right</div>
</div>
<style>
.container {
background: yellow;
height: 100px;
display: flex; /* 将父容器设置为 flex 布局 */
}
.main {
background: green;
height: 100px;
flex: 1; /* 自适应残余宽度 */
min-width: 150px; /* 给两头元素设置一个最小宽度避免适度缩放导致布局错乱 */
}
.left {
background: red;
width: 150px;
height: 100px;
flex-shrink: 0; /* 禁止放大 */
}
.right {
background: blue;
width: 100px;
height: 100px;
flex-shrink: 0; /* 禁止放大 */
}
</style>
四、sticky footer 粘连布局
所谓粘连布局,就是将页面分成上、中、下三个局部,上、下局部都为固定高度 , 两头局部高度不定 (但有一个最小高度为浏览器高度),当 页面高度小于浏览器高度 时,下局部应固定在屏幕底部 ,当 页面高度超出浏览器高度 时,下局部应该随两头局部被撑开,显示在页面最底部 。
① margin-top + padding-bottom 实现
首先布局上 将 footer 局部放到 container 容器上面,header 和 main 放到 container 容器的中。
<div class="container">
<div class="header">header</div>
<div class="main">
<h1>Sticky Footer 粘连布局 </h1>
<button id="add"> 增加内容 </button>
</div>
</div>
<div class="footer">footer</div>
<script>
const addButton = document.getElementById("add");
const main = document.querySelector(".main");
addButton.onclick = function() {const p = document.createElement("p");
p.innerText = "粘连布局内容";
main.appendChild(p);
}
</script>
<style>
* {
padding: 0;
margin: 0;
}
html, body {height: 100%;}
.container {min-height: 100%; /* 整个容器撑满整个浏览器的高度 */}
.header {
background: red;
height: 100px;
}
.main {background: green;}
.footer {
background: blue;
height: 100px;
}
</style>
目前因为 container 容器设置了 min-height 为 100%,所以 footer 局部会被挤压到浏览器底部的上面。接下来咱们就 须要让 footer 局部上移到浏览器的底部 ,能够通过给 footer 设置一个 margin-top,值为 负的 footer 本身高度。
.footer {margin-top: -100px; /* 让 footer 上移到浏览器的底部 */}
此时点击增加内容按钮,增加一些内容,能够看到增加的内容会笼罩 footer 区域,如:
之所以呈现这种状况,是因为 footer 通过 margin-top 上移后只是笼罩在了 container 下面,所以 须要给 container 容器设置一个 padding-bottom,将 container 容器的内容区上移。
* {box-sizing: border-box; /* 将所有元素都定义成 border-box 边框盒模型,十分重要 */}
.container {padding-bottom: 100px; /* 将 container 的内容区向上挪动 footer 高度的间隔 */}
须要留神的是,咱们给 container 容器增加 padding-bottom 之后,为不影响整个 container 容器的高度 , 须要将 container 容器设置成边框盒模型。
残缺款式代码如下:
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box; /* 将所有元素都定义成 border-box 边框盒模型,十分重要 */
}
html, body {height: 100%;}
.container {
min-height: 100%; /* 整个容器撑满整个浏览器的高度 */
padding-bottom: 100px; /* 将 container 的内容区向上挪动 footer 高度的间隔 */
}
.header {
background: red;
height: 100px;
}
.main {background: green;}
.footer {
background: blue;
height: 100px;
margin-top: -100px; /* 让 footer 上移到浏览器的底部 */
}
</style>
② 通过 flex 布局实现
布局上有所不同,会 将 header、main 和 footer 都放到 container 容器的中 ,并将 container 容器设置为 flex 布局,给 container 容器设置一个最小高度为浏览器高度即 100%,而后 给两头局部设置 flex 值为 1 ,自适应将 footer 撑开到浏览器底部,等两头内容过多的时候就会将 footer 往下推。
<div class="container">
<div class="header">header</div>
<div class="main">
<h1>Sticky Footer 粘连布局 </h1>
<button id="add"> 增加内容 </button>
</div>
<div class="footer">footer</div>
</div>
<script>
const addButton = document.getElementById("add");
const main = document.querySelector(".main");
addButton.onclick = function() {const p = document.createElement("p");
p.innerText = "粘连布局内容";
main.appendChild(p);
}
</script>
<style>
* {margin: 0;}
html, body {height: 100%;}
.container {
min-height: 100%; /* 给容器设置一个最小高度为 100%,以便将 footer 撑到底部 */
display: flex; /* 将 container 容器设置成 flex 布局 */
flex-direction: column; /*flex 布局的方向设置为列 */
}
.header {
background: red;
height: 100px;
}
.main {
background: green;
flex: 1; /* 让两头局部自适应,以便将 footer 撑到底部 */
}
.footer {
background: blue;
height: 100px;
}
</style>