布局模型是基于盒模型基础上进行的拓展,关于布局有流式布局(标准的布局),浮动布局、定位布局、flex布局等。
描述:元素按照自己默认的元素类型在页面中进行排列的方式叫做标准流布局。
块块元素block
前后具有换行符,默认独占一行。
可以设置宽高,设置宽高后容器范围为设置的宽高的范围,但换行符一直存在。
设置上下外边距存在合并问题。
非块状元素设置为块状元素 display:block;
目前学过的块状元素 h1-h6 p div 等
行内元素inline
在同一行内与其它行内级元素从左到右依次排列。默认包裹内容。
行内元素不能设置宽高。
设置左右外边距生效,上下外边距不生效;
设置左右内填充生效,上下内填充不生效(不占位,不会撑大盒子,但是背景色又呈现);
非行内元素设置为行内元素 display:inline;
目前学过的行内元素 span a strong em ins del 等
行内块元素 inline-block
在同一行内与其它行内级元素从左到右依次排列。默认包裹内容。
可以设置宽高,设置宽高后容器范围为设置的宽高的范围。
所有的外边距和内填充都是生效的。
非行内块元素设置为行内块元素 display:inline-block;
常见的行内块元素 input textarea select img等
总结:标准流中,块级元素block在页面中从上往下依次排列,行内级元素(inline、inline-block)在同一行内从左到右依次排列,超出父容器后自动换行。如果文本内容没有使用元素进行包裹,那么被识别为匿名行内元素。
浮动模型:用来改变块元素(block element)对象的默认显示方式。block对象设置了float属性之后,它将本来占据一行的元素,可以并列排在一行里。
设置浮动属性, 可以向左侧或右侧,浮动的框就因此向左或向右移动,直到它的外边缘碰到包含框(浮动元素的包含块是其最近的块级祖先元素)或另一个浮动框的边框为止。
通过属性 float 设置元素的浮动,对应的属性值
浮动设计的初衷,仅仅是为了在排版中,实现文字环绕图片效果
....
以上代码使用样式对img设置左浮动,p不设置浮动,适量增加p中的内容,缩放视口查看效果; 脱离了文档流(是相对于普通文档流来说的),该元素就不在占空间,因此在计算高度时这个元素就不考虑,上面本身div没有设置高度,它的高度由元素里的内容 与元素里的内容高度共同决定(把父元素撑开),当元素设置浮动后,它就脱离文档流,在标准流中,就只有元素一个,元素就自然排在上面去了,此时 父元素div的高度就是由元素里的内容的高度决定。(也就是经常说的,父元素会塌陷问题,道理就在这)脱离文档流只是在视觉上这个元素还是占据空间的,图片元素 不会覆盖其他元素内容(这里内容俩字很重要,也充分说明了在使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本内容依然会为这个元素让出位置, 环绕在周围),或不被其他元素内容覆盖,如以下操作:在以上代码基础上,div外新增一个p元素,添加文本内容,然后将div内部img和p元素设置左浮动,查看效果
为什么要清除浮动
当父元素不设置高度或者设置的高度小于子元素;而子元素又设置了浮动,那么会造成父元素塌陷。如下,子元素全部设置浮动后,父元素塌陷效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SYUc4rBu-1687136272709)(浮动与定位.assets/clip_image002.jpg)]
清除浮动的属性 clear,属性值
清除浮动的方式(至少需要讲以下四种)
父元素设置合理的高度
这种方式可以解决视觉上父元素塌陷问题,但元素还是浮动的效果;
且在页面布局中,更多的容器其实是被内容撑起来的,在一开始布局的时候,父元素的高度其实是不太好确定的,所以除非是明确尺寸的布局,否则不建议使用这种方式
父元素设置overflow:hidden|scroll |auto
属性
描述:通过给父元素设置overflow:hidden | scroll | auto
问题:如果子元素及内容不超出父元素,用起来很方便。但是如果有定位存在需要将子元素定位到父元素外的某个位置,那么溢出的部分就看不到了。根据实际情况使用。
利用空元素(内墙或外墙)
描述:这种方式是在父元素内部的最后,添加一对空标签,然后给这个空标签设置清除浮动clear:both
问题:当页面应用浮动过多的时候,会增加html空标签的数量,一方面影响加载速度,另一方面也不美观
after 伪类清浮动(推荐)
这种方法是推荐使用的,bootsrtap也在使用,应该掌握,不然太low了,他的原理就是通过伪元素选择器,在div后面添加了一个clear:both的属性,跟第三种方法是一样的道理。
如下:给父元素添加一个伪元素
.clearfix::after{
display: block;
height: 0;
content: '';
clear: both;
visibility: hidden;
}
.clearfix{
//兼容低版本IE
zoom:1;
}
了解其它清除浮动的方式
给父元素设置浮动,会造成新的问题
给父元素设置 display:table;
将div属性变成表格,会产生新的未知问题
使用双伪元素清除浮动
.clearfix:after,.clearfix:before{
content:'';
display:block;
clear:both;
}
.clearfix{
//兼容低版本IE
zoom:1;
}
日常生活中,去到某个陌生的城市,我们通常打开手机地图,定位自己当前位置和要去的位置,查找所对应的路线。
在CSS中的定位,道理其实差不多。就是给当前元素进行位置的处理。
W3CSchool规定定位的基本思想:它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置。
参考文档:https://www.w3school.com.cn/css/css_positioning.asp
top | right | bottom | left
元素的定位与文档流无关,所以它们可以覆盖页面上的其它元素
z-index属性指定了一个元素的堆叠顺序(哪个元素应该放在前面,或后面),属性值为 number 数字
一个元素可以有正数或负数的堆叠顺序,一般设置大于0的数字
具有更高堆叠顺序的元素总是在较低的堆叠顺序元素的前面。
如果两个定位元素重叠,没有指定z - index,最后定位在HTML代码中的元素将被显示在最前面。
通过z-index设置,属性值大于0的数字
1)第一种情况:设置了定位压盖没有设置定位的元素
2)第二种情况:设置了非静态定位的同级元素之间默认后面压盖前面;如果设置z-index,值越大,越靠上
3)第三种情况,嵌套的元素,父元素的z-index决定压盖的顺序
弹性盒容器:通过设置 display 属性的值为 flex 或 inline-flex 将其定义为弹性容器。
direction
属性值为 rtl
, 使弹性子元素的排列方式发生改变,页面布局也跟着改变(改变子元素的排列方式);弹性子元素:盒子里面的元素
flex-direction
指定了弹性子元素在父容器中的位置,属性值如下
flex-wrap:wrap
设置盒子内部元素的换行方式,在页面缩放时,水平方向溢出部分可以进行换行
flex-flow
复合属性,用于同时设置子元素的位置和换行方式
注意:如果元素不是弹性盒对象的元素,则 flex-flow 属性不起作用。
justify-content
应用在弹性容器上,把弹性项沿着弹性容器的主轴线(main axis)对齐,属性值如下
align-items
设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式,属性值如下
align-content:类似于justify-content,子元素根据设置的属性值在Y方向进行不同的排列方式,属性值如下
设置元素垂直居中:
css
属性 line-height 的值与该元素的父级元素 css
属性 height 一致即可css
属性:display: table-cell; vertical-align: middle;,还需设置该元素的父级元素 css
属性:display: table;三栏布局 左右固定 中间自适应
使用浮动实现:左 float + 右 float + 中 设为 BFC(overflow:hidden
)
HTML结构:
左
右
content area
CSS样式:
.container {
height:100%;
.left {
float: left;
height: 100%;
width:100px;
background-color:lightblue;
}
.right {
float: right;
height: 100%;
width:100px;
background-color:lightgreen;
}
.main {
height:100%;
overflow:hidden;
background-color:lightpink;
}
}
使用定位实现 左absolute
+ 右 absolut
+ 中 margin
上面 HTML 结构 left right 和 main,顺序可以随意调换
CSS代码:
.container {
height:100%;
position:relative;
.left {
position:absolute;
left:0;
top:0;
height: 100%;
width:100px;
background-color:lightblue;
}
.right {
position:absolute;
right:0;
top:0;
height: 100%;
width:100px;
background-color:lightgreen;
}
.main {
height:100%;
margin:0 100px;
background-color:lightpink;
}
}
使用弹性盒子实现
HTML代码:
中间栏
CSS代码:
.wrap{
/*设置父元素为弹性盒*/
display: flex;
height: 400px;
background-color: lightgray;
}
.left{
width: 260px;
height: 100%;
background-color: red;
}
.center{
width: 320px;
height: 120%;
/*设置弹性子元素的属性,对剩余空白空间的分配比重*/
flex: 1;
background-color: #00b1e8;
}
.right{
width: 320px;
height: 100%;
background-color: yellow;
}
在面试时,你会经常遇到那么一个考题?有left、right、container三个盒子,要求left与right盒子宽度固定,分别固定于浏览器两侧,container位于中间,
宽度随浏览器窗口自适应;说白了,就是要你进行两边定宽,中间自适应的三栏布局,并且中间栏要放在文档流前面以优先渲染。而圣杯布局与双飞翼布局就是用
来解决这个问题最常见的布局方法。
圣杯布局的出现是来自于a list part上的一篇文章In Search of the Holy Grail。比起双飞翼布局,它的起源不是源于对页面的形象表达。在西方,圣杯是
表达“渴求之物”的意思。而双飞翼布局则是源于淘宝的UED,可以说是灵感来自于页面渲染
圣杯布局和双飞翼布局基本上是一致的,都是两边固定宽度,中间自适应的三栏布局,其中,中间栏放到文档流前面,保证先行渲染。解决方案大体相同,都是三
栏全部float:left浮动,区别在于解决中间栏div的内容不被遮挡上,圣杯布局是中间栏在添加相对定位,并配合left和right属性,效果上表现为三栏是单独分
开的(如果可以看到空隙的话),而双飞翼布局是在中间栏的div中嵌套一个div,内容写在嵌套的div里,然后对嵌套的div设置margin-left和margin-right,
效果上表现为左右两栏在中间栏的上面,中间栏还是100%宽度,只不过中间栏的内容通过margin的值显示在中间。
简单说起来就是:双飞翼布局比圣杯布局多创建了一个div,但不用相对布局了。
双飞翼布局的好处:
官方文档:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
Box
Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:
Formatting context
Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。
CSS2.1 中只有 BFC
和 IFC
, CSS3 中还增加了 GFC
和 FFC。
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
根元素html
float属性不为none
position为absolute或fixed
display为inline-block, table-cell, table-caption, flex, inline-flex
overflow不为visible
参考文档:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
自适应两栏布局
效果
根据BFC
布局规则第3条:
每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
因此,虽然存在浮动的元素aslide,但main的左边依然会与包含块的左边相接触。
根据BFC
布局规则第四条:
BFC
的区域不会与float box
重叠。
我们可以通过通过触发main生成BFC
, 来实现自适应两栏布局。
.main {
overflow: hidden;
}
当触发main生成BFC
后,这个新的BFC
不会与浮动的aside重叠。因此会根据包含块的宽度,和aside的宽度,自动变窄。效果如下:
清除内部浮动
页面效果:
根据BFC
布局规则第六条:
计算
BFC
的高度时,浮动元素也参与计算
为达到清除内部浮动,我们可以触发par生成BFC
,那么par在计算高度时,par内部的浮动元素child也会参与计算。
代码:
.par {
overflow: hidden;
}
防止垂直 margin 重叠
Haha
Hehe
两个p之间的距离为100px,发送了margin重叠。
根据BFC布局规则第二条:
Box
垂直方向的距离由margin决定。属于同一个BFC
的两个相邻Box
的margin会发生重叠
我们可以在p外面包裹一层容器,并触发该容器生成一个BFC
。那么两个P便不属于同一个BFC
,就不会发生margin重叠了。
代码:
Haha
Hehe
页面效果:
其实以上的几个例子都体现了BFC
布局规则第五条:
BFC
就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
因为BFC
内部的元素和外部的元素绝对不会互相影响,因此, 当BFC
外部存在浮动时,它不应该影响BFC
内部Box的布局,BFC
会通过变窄,而不与浮动有重叠。同样的,当BFC
内部有浮动时,为了不影响外部元素的布局,BFC
计算高度时会包括浮动的高度。避免margin重叠也是这样的一个道理。