Css视觉格式化模型

本文涉及Css基础内容较多,(包含盒模型、文档流、浮动、定位)可以选择性阅读。

视觉格式化模型就是指页面中多个盒子(即盒模型)的排列规则,在了解视觉格式化模型前,先重温下盒模型。

  1. 盒模型

当对一个文档进行布局的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型,将所有元素表示为一个个矩形的盒子

盒模型由内到外的构成:content、padding、border、margin

.box {
    height: 100px;
    width: 100px;
    margin: 20px;
    padding: 30px;
    border: 10px solid rgb(70, 9, 127);
    background-color: blueviolet;
}

蓝色区域为content即内容区域,通过width、height设置;

绿色区域为padding即内边距区域,通过padding设置;

黄色区域为border即边框区域,通过border设置;

橙色区域为margin即外边距区域,通过margin设置;

盒模型有两种:标准盒模型和怪异盒模型(IE盒模型)

标准盒模型:content + padding + border + margin(width为content的宽度,height同)

上述紫色正方形就是标准盒模型。

怪异盒模型(IE盒模型):content + padding + border + margin(width为content+padding + border 的宽度,height同)

可以通过box-sizing: border-box将标准盒模型转换为怪异盒模型,默认状态下都为标准盒模型。

.box {
    height: 100px;
    width: 100px;
    margin: 20px;
    padding: 30px;
    border: 10px solid rgb(70, 9, 127);
    background-color: blueviolet;
    box-sizing: border-box;
}

将标准盒子转换为了怪异盒子,由width = content+padding + border可知,content = 100 - (30 + 10)*2 = 20(实验时,需要将系统设置的缩放与布局改为100%)

视觉格式化模型就是指页面中多个盒子(即盒模型)的排列规则,大致可分为3种:文档流、浮动、定位

  1. 文档流(常规流)

所有元素默认情况下都属于文档流。规则:块元素独占一行,行元素多个占一行。

包含快:包含其他盒子的块称为包含块,其决定了内部盒子的活动范围。

文档流下的一些小规则:

1 %:padding、width、margin如果以%作为长度单位,那么都是相对于包含快的宽度大小;height如果以%作为长度单位,那么是相对于包含快的高度大小。

outer即为inner的包含块,inner内部设置的%都符合上述规则

.outer {
    height: 100px;
    width: 100px;
    background-color: blueviolet;
    color: #fff;
}

.inner {
    margin-left: 10%;
    width: 50%;
    height: 50%;
    background-color: rgb(51, 11, 88);
    color: #fff;
}

2 外边距合并

当两个margin重叠时,取margin最大的为有效值,而非相加,常见场景有相邻盒子、父子盒子

以父子盒子举例:

.outer {
    margin-top: 40px;
    height: 100px;
    width: 100px;
    background-color: blueviolet;
}

.inner {
    margin-top: 20px;
    width: 50%;
    height: 50%;
    background-color: rgb(51, 11, 88);
}

解决办法,让margin不相邻即可,可以通过给父元素加border或者改成使用padding即可

border写法
.outer {
    margin-top: 40px;
    height: 100px;
    width: 100px;
    background-color: blueviolet;
    border: 1px solid #fff;
}

.inner {
    margin-top: 20px;
    width: 50%;
    height: 50%;
    background-color: rgb(51, 11, 88);
}
padding写法
.outer {
    margin-top: 40px;
    height: 100px;
    width: 100px;
    background-color: blueviolet;
    padding-top: 20px;
}

.inner {
    width: 50%;
    height: 50%;
    background-color: rgb(51, 11, 88);
}

3 width、height、margin的auto属性

水平方向(width、margin):

假如没有给子盒子定义宽度,如下:

.outer {
    height: 100px;
    width: 100px;
    background-color: blueviolet;

}

.inner {
    height: 50%;
    background-color: rgb(51, 11, 88);
}

子元素的width会自动撑满父元素内部宽度,因为width默认值为auto,auto在这里的意思是"占用剩余全部空间"。如下,是子元素盒模型。可以看出子元素width等于父元素的width。

margin默认值是0,但是给margin设置auto属性,也是起到"占用剩余全部空间"的作用。

常见margin: 0 auto居中原理

.outer {
    height: 100px;
    width: 100px;
    background-color: blueviolet;
}

.inner {
    width: 50px;
    height: 50%;
    background-color: rgb(51, 11, 88);
    margin-right: auto;
    margin-left: auto;
}

给子盒子设置了左右margin为auto属性,那么默认的它们会占用剩余空间,并且是公平占用,即实现了水平方向居中,这种居中方式是块级元素的。

垂直方向(height、margin):

height默认值为auto,但是区别于水平方向的auto,这里的auto是指内容区域高度,即内容区域多高,height多高

.outer {
    height: 100px;
    width: 100px;
    background-color: blueviolet;
}

.inner {
    width: 50px;
    background-color: rgb(51, 11, 88);
    color: #fff;
}
<div class="outer">
    <div class="inner">文本内容</div>
</div>

如上,在未定义高度情况下,高度自动为内容区域高度37.333。

而垂直方向margin的auto就都是0了。

  1. 浮动

浮动的设计初衷是实现文字环绕效果,后来也被应用到了更多场景如横向排列。

正常元素默认是走文档流这一路线,通过float属性可以将元素改为浮动。

描述

left

元素向左浮动。

right

元素向右浮动。

none

默认值。元素不浮动,并会显示在其在文本中出现的位置。

inherit

规定应该从父元素继承 float 属性的值。

浮动元素特点:

1-当元素浮动后,元素的display属性会被改为为block,也就是变成了块级元素

span {
    float: left;
    height: 100px;
    background-color: bisque;
}
<span>span浮动</span>

如上,给span标签设置浮动后,它的高度可以设置了,正常情况,行内元素无法设置高度。

2-浮动元素也有包含块,其决定了浮动元素的活动范围。

3-width、height、margin的auto值

width与height的auto值,都为适应内容的宽度或高度。

div {
    background-color: antiquewhite;
    float: left;
}
<div>浮动</div>

如图,默认下width与height都为auto,它们的长度取决于内容的长度。

margin的auto值为0。

4-左浮动的元素向左上方排列,右浮动的元素向右上方排列

.left {
    background-color: antiquewhite;
    float: left;
}

.right {
    background-color: antiquewhite;
    float: right;
}
<div class="left">左浮动</div>
<div class="right">右浮动</div>

5-当文档流块级元素在浮动元素前,浮动元素会给文档流块级元素让道。

.left {
    background-color: antiquewhite;
    float: left;
}

.right {
    background-color: antiquewhite;
    float: right;
}

.normal {
    background-color: blueviolet;
}
<div class="normal">文档流</div>
<div class="left">左浮动</div>
<div class="right">右浮动</div>

6-文档流块级元素在浮动元素后,浮动元素会浮在文档流块级元素上,就不让道了。

.left {
    background-color: antiquewhite;
    float: left;
}

.right {
    background-color: antiquewhite;
    float: right;
}

.normal {
    background-color: blueviolet;
}
<div class="left">左浮动</div>
<div class="right">右浮动</div>
<div class="normal">文档流</div>

5、6可以记忆为对”浮动元素“而言,谁在前谁就是老大,谁就可以不让道。浮动元素不让道的标准就是”浮“在上面(仅相对于文档流块级元素)。

带背景色,看着不直观,所以去掉浮动元素的背景色

至于文字“文档流”为何没有被左浮动元素压着,第7条会说。

看下面的例子

.left {
    background-color: antiquewhite;
    float: left;
}

.right {
    background-color: antiquewhite;
    float: right;
}

.normal {
    background-color: blueviolet;
}
<div class="left">左浮动</div>
<div class="normal">文档流</div>
<div class="right">右浮动</div>

左浮动在前,可以不让道了,就浮在上面了。右浮动在后,得让道,就排到下面了。

7-文档流行内元素在排列时,会给浮动元素让道(这次跟顺序无关了)。

.left {
    background-color: antiquewhite;
    float: left;
}

.normal {
    background-color: blueviolet;
}
<div class="left">左浮动</div>
<span class="normal">文档流</span>
<div class="left">左浮动</div>

带背景色看着不明显,所以去掉背景色

文字环绕图片原理:

.img {
    width: 80px;
    height: 100px;
    float: left;
    margin-right: 10px;
}
<img class="img" src="./uae.jpg">
<p>许嵩,1986年5月14日出生于安徽省合肥市,毕业于安徽医科大学,中国内地男歌手、音乐人、海蝶音乐公司(现为太合音乐集团)音乐总监。2009年1月发行首张词曲全创作专辑《自定义》。2010年1月发行第二张词曲全创作专辑《寻雾启示》。2011年4月发行第三张词曲全创作专辑《苏格拉没有底》。2012年7月发行第四张词曲全创作专辑《梦游计》。2014年8月发行第五张词曲全创作专辑《不如吃茶去》。2016... >>></p>

p标签是块级元素,但是文字部分,不会被浮动元素所覆盖,这是因为如果文字不是在行内元素内,浏览器会自动在文字外包裹一层行内元素。结合第7条—‘行内元素在排列时,会给浮动元素让道’,就可以理解为什么块级元素内的文字不会被浮动元素覆盖了,这个由浏览器自动生成的行内元素,不可见,叫做匿名行内框。

8-高度坍塌

.outer {
    padding: 5px;
    background-color: brown;
}

.inner {
    width: 15vw;
    height: 15vw;
    background-color: antiquewhite;
    float: left;
    margin-right: 10px; 
    margin-top: 1px;
}
 <div class="outer">
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
</div>

如果不给inner加浮动,结果会是如下:

以上由浮动属性造成的现象叫做高度坍塌(前者),文档流元素的默认高度是由内容区域决定的,在计算时,不会包含浮动元素(浮动元素脱离了文档流)。

解决方案:

通过使用clear属性,其包含以下值

描述

left

左侧不允许浮动元素

right

右侧不允许浮动元素

none

允许两侧都有浮动元素。默认值

both

左侧或右侧均不允许浮动元素

inherit

元素继承其父级的 clear 值

设置了clear属性的标签会给浮动元素让道,也就是排列在了浮动元素下方。

清除浮动方法一
.outer {
    padding: 5px;
    background-color: brown;
}

.inner {
    width: 15vw;
    height: 15vw;
    background-color: antiquewhite;
    float: left;
    margin-right: 10px;
    margin-top: 1px;
}

.clearfix {
    clear: both;
}
<div class="outer">
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="clearfix"></div>
</div>
清除浮动方法二(推荐)
.outer {
    padding: 5px;
    background-color: brown;
}

.inner {
    width: 15vw;
    height: 15vw;
    background-color: antiquewhite;
    float: left;
    margin-right: 10px;
    margin-top: 1px;
}

.clearfix::after {
    content: '';
    display: block;
    clear: both;
}
<div class="outer clearfix">
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
</div>

方法一通过在最后的位置添加一个标签,设置clear: both属性,解决了父元素高度坍塌问题,原理就是设置了clearfix css属性的标签会给浮动的所有元素让道,排列在它们的下方,而父盒子虽然不包含浮动元素,但是包含了设置了clearfix css属性的标签元素,而父盒子如果想要去包含它,就必须撑开自己,去包含设置了clearfix css属性的标签元素。因此,父盒子有了高度,其高度包括设置了clearfix css属性的标签元素及它上面的所有浮动元素(both情况下)。

方法二的原理与方法一本质相同,只是通过伪元素实现,这种方法既不用多写一个标签,也可以将clearfix属性复用到其它有高度坍塌问题的标签上,是推荐写法。

  1. 定位

用来指定一个元素在网页上的位置,通过position实现

描述

static

默认值,即没有定位,遵循正常的文档流对象

fixed

固定位置,元素的位置相对于浏览器窗口

relative

相对定位,相对其正常位置

absolute

绝对定位,相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于<html>:

sticky

粘性定位,基于用户的滚动位置来定位

定位元素特点:脱离文档流(相对定位除外)

相对定位

不会使元素脱离文档流,只是相对其正常位置进行偏移,可以通过left、right、top、bottom四个属性设置偏移方向。

.box {
    width: 50px;
    height: 50px;
    background-color: brown;
    border: 1px solid #fff;
}

.relative {
    position: relative;
    left: 50px;
}
<div class="box"></div>
<div class="box relative"></div>

下面的元素使用相对定位,向左偏移了50px

绝对定位

绝对定位的元素是相对于其包含块的。从内向外找,其祖先元素中第一个定位元素(position不为static)就是其包含块

.grandfather {
    position: relative;
    background-color: brown;
    width: 100px;
    height: 100px;
}

.father {
    background-color: rgb(238, 135, 135);
    width: 50px;
    height: 50px;
}

.son {
    position: absolute;
    bottom: 0;
    background-color: rgb(255, 231, 231);
    width: 25px;
    height: 25px;
}
<div class="grandfather">
    <div class="father">
        <div class="son"></div>
    </div>
</div>

儿子元素使用了绝对定位,那么其包含块就不再是父亲元素了,而是从内向外第一个使用定位元素的祖先元素,即祖父元素。

如果从内向外都没有定位元素,则绝对定位元素的包含块就是整个html标签(去掉grandfather的position属性结果如下)

固定定位

固定定位的元素是相对于其包含块的。其包含块是视口,即浏览器的可视窗口部分(视口和整个html标签不同,使用固定定位的元素,无论怎样滚动浏览器,该元素位置都不会发生任何变化)

.button {
    width: 30px;
    height: 30px;
    background-color: brown;
    position: fixed;
    bottom: 10px;
    right: 10px;
}
<div class="button"></div>

无论如何滚动浏览器,按钮元素始终位于浏览器可视区域右下方。

粘性定位

相当于relative和fixed定位的混合,在正常情况下表现为relative,而达到了某种条件,就会由relative转为fixed。必须结合left、right、top、bottom一起使用,这四个属性就是某种条件。

* {
    margin: 0;
    padding: 0;
}

dl {
    width: 100px;
    border: 1px solid #000;
}

dt {
    width: 100px;
    color: #fff;
    position: sticky;
    top: 0;
}

dd {
    border-bottom: 1px solid #000;
}
<dl>
    <dt style="background-color: rgb(236, 101, 4);">块级元素</dt>
    <dd>p</dd>
    <dd>div</dd>
    <dd>h1-h6</dd>
    <dd>ul</dd>
    <dd>ol</dd>
    <dd>li</dd>
    <dd>...</dd>
</dl>
<dl>
    <dt style="background-color: rgb(154, 71, 12);">行内元素</dt>
    <dd>a</dd>
    <dd>span</dd>
    <dd>b</dd>
    <dd>strong</dd>
    <dd>em</dd>
    <dd>...</dd>
</dl>
<dl>
    <dt style="background-color: rgb(4, 236, 139);">行内块元素</dt>
    <dd>img</dd>
    <dd>input</dd>
    <dd>...</dd>
</dl>
<div style="height:500px"></div>

在正常情况下,dt标签就是relative定位,当达到临界值时(top:0),dt标签会变成fixed定位。临界值可通过left、right、top、bottom设置,且必须设置,否则,就没有粘性效果了。

这里面的临界值是指粘性定位元素与它从内向外的第一个设置了overflow属性的元素的相对距离,如果都没有,就是视口。如上例,dt元素外无任何设置了overflow属性的元素,所以,是相对于视口,当dt元素的top相对于视口的距离为0时,转为fixed定位。而当父元素从视口中消失,fixed定位结束,转为relative定位。

需要注意:当父元素设置了overflow属性(除默认值visible外),粘性定位会失效。原因:用上述例子举例,给dl添加了overflow:hidden,dt就相对于dl了,dl和dt的相对位置怎样都不会有变化。不可能达到临界值,故不会有粘性效果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值