布局:排列页面中的区域;布局写起来不难,但是里面蕴含着许多基本知识
我下面讲的布局方式,都是自适应的(若你要将布局全部定宽,看完本文,这对你来说更是没有难度了,把下文中代码出现的自适应宽度值改为你需要的宽度值即可,本文很多知识点的讲解都是围绕auto的)
先了解一个知识点:常规流格式化模型,大体上将页面的排列方式分为三种方式
- 常规流
- 浮动
- 定位
常规流布局讲解-start
常规流:
- 又名文档流
- 所有元素,默认情况下都属于常规流布局
- 总体规则:块盒独占一行,行盒水平依次排列
包含块: 每个盒子都有它的包含块,包含块决定了盒子的排列区域,绝大部分情况下,盒子的包含块为父元素的内容盒
块盒(水平方向):
- 每个块盒的总宽度(border-box + margin),必须等于包含块的宽度
- 宽度的默认值是auto(会将包含块的剩余空间吸收掉)
- margin默认值为0,也可以取值为auto(当width不等于auto时,margin吸收包含块的剩余空间)
- width、margin都取值为auto时,
width: auto;
的吸收能力更强,优先级高,包含块的剩余空间由width吸收 - 若width、border、padding、margin计算后,仍然有剩余空间,该剩余空间会被margin-right吸收掉
块盒(垂直方向):
height: auto;
适应内容的高度(高度会被内容撑开)margin: auto 0
auto表示0
块盒,百分比取值:
- width、padding、margin可以取值百分比,相对于包含块的宽width
- height可以取值百分比,相对于包含快的高height
- 注意:当包含块的height取值为默认值auto时(适应内容高度),然后子元素的height设置百分比是无效的(因为它们冲突了)
块盒,上下外边距合并:两个常规流块盒,上下文外边距相邻,会进行合并(取最大值)
在常规流中,块盒在其包含块中水平居中:可以定宽,然后左右margi设置为auto
一个有意思的玩法:其余值已定,将margin-left和margin-right设置负数,则其content-box的宽度将会拉长
因为width + padding-left + padding-right + border-left + border-right + margin-left + margin-right = 其包含块content-box的width
常规流布局讲解-end
两栏布局
对于两栏布局而言,一个是侧边栏,一个是主要内容区域;而且侧边栏和主要内容区域的高是自适应的,然后侧边栏定宽,主要内容区的宽度自适应。
- 高是自适应的(被内容撑开),即:
height: auto;
- 宽是自适应的,即:
width: auto;
- 侧边栏定宽,即给侧边栏的
width
设置一个固定值 - 补充:常规流布局中,块盒的宽、高的默认值都是auto
所有元素,默认情况下,都属于常规流布局(排除:浮动元素、定位元素)
一:用浮动实现两栏布局
html:
- aside.aside是侧边栏(我以侧边栏放在左边来讲解两栏布局)
- div.main是右边栏(即:主要内容区)
- 这两个标签下,我都放入了1000个随机的英文字母(不用管内容)
- 而且侧边栏和主要内容区的顺序摆放,是需要注意的(这个下面会讲到原因)
侧边栏和右边栏(主要内容区)的父元素我还设置了一个类选择器.clearfix
,因为浮动元素有一个很坑爹的特性:
高度坍塌: 常规流盒子的自动高度(即height: auto;
)在计算时,不会考虑浮动盒子。
解决高度坍塌的最佳办法就是清除浮动,而且清除浮动有固定的语句:
- 给浮动元素们的父元素一个类选择器
.clearfix
- 然后在css代码中这么写:
.clearfix::after{
content: '';
display: block;
clear: both;
}
::after
是伪元素选择器,.clearfix::after
即给.clear
选中的元素末尾添加内容
css:(完整的还在下面啊,先循序渐进的看)
/* 清楚浮动,解决高度坍塌 */
.clearfix::after{
content: '';
display: block;
clear: both;
}
.container{
/* 自己根据需求设置 */
}
/* 侧边栏 */
.container .aside{
folat: left;
width: 一个固定值;
margin-right: 一个值;/* 侧边栏、主要内容区域间产生空隙,根据需求来写 */
}
/* 主要内容区域 */
.container .main{
overflow:hidden;
}
- 侧边栏
- 需要定宽
- 设置浮动(看你的需求,来选择是左浮动
float: left
还是右浮动float: right
)
- 主要内容区域
- 它的宽度默认值是auto,就不用再设置了
- 需要将它变成bfc
overflow: hidden;
的副作用最小
float讲解-start
float取值:
float: left;
左浮动,元素靠上靠左float: right;
右浮动,元素靠上靠右float: none;
默认值,为常规流
float的基本特点:
- 当一个元素浮动后,元素必定为块盒
display: block;
- 浮动元素的包含块,依旧为父元素的内容盒
- 浮动盒子的顶边不得高于上一个浮动盒子的顶边
- 若剩余空间无法放下浮动盒子,则该盒子向下移动,知道具备足够的空间容纳盒子,然后向左(向右)移动
float盒子尺寸:
- 宽度为auto时,适应内容宽度
- 高度为auto时,与常规流盒子一致,适应内容的高度
- margin为auto时,即为0
- 百分比取值与常规流一样
- 外边距合并并不会发生
float盒子排列:
- 浮动盒子在包含块中排列时,会避开常规流盒子
- 常规流块盒在排列时,无视浮动盒子
- 行盒在排列时,会避开浮动盒子
注意:如果文字没有在行盒中,浏览器会自动生成一个行盒包裹文字(匿名行盒)
高度坍塌:
- 原因:常规流盒子的自动高度
height: auto;
,在计算时,不会考虑浮动盒子 - 解决办法:清楚浮动(副作用最小的办法了)
- 这个上面有讲,不再赘述
float讲解-end
再来一个知识点
bfc讲解-start
bfc:块级格式化上下文(Block Formatting Context),它是一块独立的渲染区域,它规定了在该区域上,常规流块盒的布局。
常规流块盒布局的4个特点:
- 常规流块盒在水平方向上,必须撑满包含块
包含块: 每个盒子都有它的包含块,包含块决定了盒子的排列区域,绝大部分情况下,盒子的包含块为父元素的内容盒 - 常规流块盒在包含块的垂直方向上依次摆放
- 常规流块盒若外边距无缝相邻,则进行外边距合并
- 常规流块盒的自动高度和摆放位置,无视浮动元素、定位元素
浮动元素:float
的取值为left
或者right
(默认值为none
,即常规流)
定位元素:position
的取值为relative
、absolute
或者fixed
(默认值为static
,即不定位)
bfc渲染区域:这个区域由某个HTML元素创建,以下元素会在其内部创建bfc区域
- 根元素(即
<html> </html>
) - 浮动元素、绝对定位元素
position:absolute;
和固定定位元素position:fixed;
- overflow不等与visible的块盒
- display等于table,display等于inline-block
独立的渲染区域:不同的bfc区域,它们进行渲染时互不干扰(创建bfc的元素,隔绝了它内部和外部的联系,内部的渲染不会影响到外部),
有三个具体规则:
- 创建bfc的元素,它的自动高度需要计算浮动元素
- 创建bfc的元素,它的边框盒不会与浮动元素重叠
- 创建bfc的元素,不会和它的子元素进行外边距合并
bfc讲解-end
那么,在上面的前提下,在html中对于侧边栏和主要内容区的顺序摆放是有要求的:侧边栏需要放在主要内容区域的前边
因为侧边栏是左浮动,主要内容区域是bfc
- 若侧边栏在主要内容区域的前面:侧边栏浮动到其包含块的最上最左位置,然后主要内容区域由于是bfc,不会和浮动元素重叠,那么就形成了自适应的两栏布局
- 若主要内容区域在侧边栏的前面:由于主要内容区域的宽是自适应的,那么它在宽度上会撑满包含块,然后浮动盒子在包含块中排列时,会避开常规流盒子,那么侧边栏就跑到下面去了,哦哦,两栏布局就木有了
侧边栏、主要内容区域间设置间隙:
然后,如果你觉得两栏布局,他们紧紧的挨着一起,你不喜欢,你想把它们分开一段距离,这里也有需要注意的地方:
如果你打算使用margin
来分割两个区域的话,最好去设置浮动元素(侧边栏)的margin-right
;
不要去设置bfc区域(主要内容区域)的margin-left
,因为bfc的margin-left
相对于父元素的左边框,这样设置是没有意义的
等高布局
由于我的布局讲究的是自适应,侧边栏和主要内容区域的高是自适应的
那么就会出现一个问题,侧边栏和主要内容区域的高度都是自适的,高度被内容撑开,那么侧边栏和主要内容区域的高度就很可能不会相同
解决办法:
- css3的弹性盒
- js控制
- 伪等高
一般来说,主要内容区域的内容更多,其高度会比侧边栏的高度要高
本文只涉及html、css,所以只能采用第三种方法
给侧边栏的height设计一个很夸张的值,然后在给侧边栏设置一个margin-bottom(值为负数,其绝对值稍微比高度小),再给其父元素加一个溢出隐藏
- 给侧边栏的height设计一个很夸张的值:会把父元素的盒子撑开,导致父元素的高度也超级高
- 给侧边栏margin-bottom设计一个极大负值(绝对值 < height):那么,侧边栏的总高度就会很小,不会把父元素的高度撑开
总宽度 = 内部所有元素的height + padding-top + padding-bottom + border-top + border-bottom + margin-top + margin-bottom - 溢出隐藏:
overflow: hidden;
- 前提: 主要内容区域的内容足够多
css:
/* 清楚浮动,解决高度坍塌 */
.clearfix::after{
content: '';
display: block;
clear: both;
}
.container{
/* 自己根据需求设置 */
overflow: hidden;
}
/* 侧边栏 */
.container .aside{
folat: left;
width: 一个固定值;
margin-right: 一个值;/* 侧边栏、主要内容区域间产生空隙,根据需求来写 */
height: 一个很夸张的值;
margin-bottom: 极大负值(绝对值 < height);
}
/* 主要内容区域 */
.container .main{
overflow:hidden;
}
自此,用浮动实现两栏布局讲完了
二:用定位实现两栏布局
用浮动实现两栏布局,html代码里面的侧边栏和主要内容区域的书写顺序只能让侧边栏放在前面(但这样对搜索引擎不太友好)
网站的主要内容应该尽量的靠前书写(搜索引擎读取html代码时,是从上到下读取的,搜索引擎认为代码越靠前的越重要)
使用定位,可以把主要内容区域靠前书写
css:
.container{
min-width: 一个值;/* 根据需求决定是否要设置最小宽度 */
position: relative;
}
.container .aside{
width: 一个定值;
position: absolute;
top: 0px;
left: 0px;
}
.container .main{
margin: 0 0 0 一个定值;
}
上面的css代码,我只是把两栏布局需要的最基本、最必须的代码写了(而且,里面很多css属性的值你可以根据需求来改动)
position讲解-start
position取值:
position: static;
静态定位,即不定位position: relative;
相对定位position: absolute;
绝对定位position: fixed;
固定定位
一个元素,只要position的取值不是static,认为该元素是定位元素;定位元素会脱离文档流(相对定位除外)
一个脱离了文档流的元素:
- 文档流中的元素摆放时,会忽略脱离了文档流的元素
- 文档流中元素计算auto高度时,会忽略脱离了文档流的元素
相对定位:
- 不会导致元素脱离文档流,知识让元素在原来的位置上进行偏移
- 盒子的偏移不会对其它盒子产生任何影响
绝对定位:
- 宽高为auto时,适应内容
- 包含块:找祖先元素中第一个定位元素,改元素的填充盒;若找不到,则它的包含块为整个网页(初始化包含块)
- 绝对定位元素、固定定位元素一定是块盒,一定不会浮动
- 没有外边距合并
固定定位:
- 其它情况和绝对定位完全一样
- 包含块不同:固定为视口(浏览器的可视窗口)
定位下的居中(某个方向):
- 定width(height)
- 将left、right(top、bottom)距离设置为0
- 将左右(上下)margin设置为auto(自动吸收剩余空间)
多个定位元素重叠时:
- 设置css属性
z-index
,通常情况下,该值越大,越靠近用户(越不会被覆盖) - 只有定位元素设置
z-index
才有效 z-index
可以设置负数,如果为负数,遇到常规流、浮动元素,则会被其覆盖
position讲解-end
三栏布局
一:用浮动实现三栏布局,原理和上面的(用浮动实现两栏布局)一样
html:
- aside.left是左边栏
定宽,左浮动 - aside.right是右边栏
定宽,右浮动 - div.main是主要内容区域,放在中间
宽度自适应,bfc - 因为使用float实现的三栏布局,所以需要将浮动元素放在前面,不然浮动元素会避开常规流元素,就不会形成三栏布局
css:
.clearfix::after{
content: '';
display: block;
clear: both;
}
.container{
/* 根据需求,设置样式 */
overflow: hidden;
min-width: 一个值;/* 下面会讲解这个css属性 */
}
.container .left{
float: left;
width: 一个定值;
margin-right: 一个值;/* 根据需求设置 */
height: 一个很夸张的值;
margin-bottom: 极大负值(绝对值 < height);
}
.container .right{
float: right;
width: 一个定值;
margin-left: 一个值;/* 根据需求设置 */
height: 一个很夸张的值;
margin-bottom: 极大负值(绝对值 < height);
}
.container .main{
overflow: hidden;
}
很显然,用浮动实现的三栏布局中,两个侧边栏是定宽的,中间的主要内容区域确是宽度自适应,那么,你将浏览器界面缩小的时候,两个侧边栏一开始保持宽度,而主要内容区域由于宽度自适应,所以是主要内容区域的宽度在减少…减少到主要内容区域没了(即页面结构变形,跑到下面去了),(Chrome为例)就会开始从页面的右边开始消失…
但有时我们希望页面,有一个最小宽度,当界面小于这个值时,页面出现滚动条(这样的话,页面就不会由于我们在浏览器界面的时候导致html的结构变得乱七八糟)
min-width
补充:自然也有max-width
了
二:用定位实现三栏布局
html:
css:
.container{
min-width: 一个值;/* 根据需求决定是否要设置最小宽度 */
position: relative;
}
.container .left{
width: 一个定值;
position: absolute;
top: 0px;
left: 0px;
}
.container .right{
width: 一个定值;
position: absolute;
top: 0px;
right: 0px;
}
.container .main{
margin: 0 一个定值;
}
上面的css代码,我只是把三栏布局需要的最基本、最必须的代码写了(而且,里面很多css属性的值你可以根据需求来改动)
后台页面的布局
布局将整个网页撑满,网页中的每个区域都可以发生滚动(不是整个页面的滚动)
html:
css:
.background{
position: fixed;
width: 100%;
height: 100%;
background-color: lightblue;
}
.background .header{
height: 60px;
background-color: #000;
color: #fff;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.background .container{
width: 100%;
height: 100%;
padding-top: 60px;
box-sizing: border-box;
}
.background .container .left{
float: left;
width: 300px;
height: 100%;
background-color: #008c8c;
color: #fff;
padding: 20px;
box-sizing: border-box;
overflow: auto;
}
.background .container .main{
overflow: auto;
height: 100%;
background-color: #fff;
padding: 20px;
box-sizing: border-box;
}