视觉格式化
- width
- height
- margin
- padding
- width height margin padding相互作用
- position 与 float
- display 与visibility文本属性
- text-align
- line-height
- vertical-align
- text-indent
- text-shadow
- word-spacing
- letter-spacing
- text-transform
- white-space
字体属性
盒模型
问题一: 如何理解盒模型的内外尺寸以及流体特性?
每个元素都两个盒子, 外在盒子和内在容器盒子。外在盒子负责元素是可以一行显示,还是只能换行显示;内在容器盒子负责 宽高、内容呈现什么的。按照display的属性值不同,值为 block的元素的盒子实际由外在的“块级盒子” 和内在的“块级容器盒子”组成,值为inline-block的元素则由外在的“内联盒子”和内在的“块级容器盒子”组成,值为 inline的元素则内外均是“内联盒子”。盒子分“内在盒子”和“外在盒子”,显示也分“内部 显示”和“外部显示”,同样地,尺寸也分“内部尺寸”和“外部尺寸”。其中“内部尺寸”英 文写作“Intrinsic Sizing”,表示尺寸由内部元素决定; 还有一类叫作“外部尺寸”,英文写作“Extrinsic Sizing”,宽度由外部元素决定。width:auto 是“外部尺寸”,其余 全部是“内部尺寸”。而这唯一的“外部尺寸”,是“流”的精髓所在。
外部尺寸 width有两种表示形式:
- 正常流宽度
- 格式化宽度
正常流宽度
- 在页面中随便扔一个<div>元素,其尺寸表现就会和这水流一样铺满容器。这就是 block 容器的流特性。这种特性,所有浏览器的表现都是一致的。
- 表现为“外部尺寸”的块级元素一旦设置了宽度,流动性就丢失了。
- 所谓流动性,并不是看上去的宽度 100%显示这么简单,而是一种 margin/border/padding 和 content 内容区域自动分配水平空间的机制。
<h4>无宽度,借助流动性无宽度,借助流动性 </h4>
<div class="nav">
<a href="" class="nav-a">导航1</a>
<a href="" class="nav-a">导航2</a>
<a href="" class="nav-a">导航3</a>
</div>
<h4>width:100%</h4>
<div class="nav">
<a href="" class="nav-a width">导航1</a>
<a href="" class="nav-a width">导航2</a>
<a href="" class="nav-a width">导航3</a>
</div>
.width {
width: 100%;
}
.nav {
background-color: #cd0000;
}
.nav-a {
display: block;
margin: 0 10px;
padding: 9px 10px;
border-bottom: 1px solid #b70000;
border-top: 1px solid #de3636;
color: #fff;
}
.nav-a:first-child { border-top: 0; }
.nav-a + .nav-a + .nav-a { border-bottom: 0;}
上下两个导航均有 margin 和 padding,前者无 width 设置,完全借助流特性,后者宽度 width:100%。结果,后者的尺寸超出了外部的容器,完全就不像“水流” 那样完全利用容器空间,即所谓的“流动性丢失”。
![360c19f63d3902d1b205e370409b3f3f.png](https://i-blog.csdnimg.cn/blog_migrate/622b77d0435659e507d6a82b5853e91d.png)
- 格式化宽度
格式化宽度仅出现在“绝对定位模型”中,也就是出现在 position 属性值为 absolute 或 fixed 的元素中。在默认情况下,绝对定位元素的宽度表现是“包裹性”,宽度由内部尺寸决定,但是,有一种情况其宽度是由外部尺寸决定的,是什么情况呢? 对于非替换元素,当 left/top 或 top/bottom 对立方位的属性值同时存在的时候,元素的宽度表现为“格式化宽度”,其宽度大小相对于最近的具有定位特(position 属性值不是 static)的祖先元素计算。
div {
position: absolute;
left: 20px;
right: 20px;
}
假设该<div>元素最近的具有定位特性的祖先元素的宽度是 1000 像素,则这个<div>元素的宽 度是 960(即 1000−20−20)像素。
内部尺寸 width有三种表示形式:
- 包裹性
- 首选最小宽度
- 最大宽度
所谓“内部尺寸”,简单来讲就是元素的尺寸由内部的元素决定,而非由外部的容器决定。如何快速判断一个元素使用的是否 为“内部尺寸”呢? 很简单,假如这个元素里面没有内容,宽度就是 0,那就是应用的“内部尺寸”。
- 包裹性
“包裹性”,除了“包裹”,还有“自适应性”。“自适应性”是区分后面两种尺寸表现很重要的一点。所谓“自适应性”,指的是元素尺寸由内部元素决定,但永远小于“包含块”容器的 尺寸(除非容器尺寸小于元素的“首选最小宽度”)。换句话说就是,“包裹性”元素冥冥中有个 max-width:100%罩着的感觉(注意,此说法只是便于大家理解,实际上是有明显区别的)。因此,对于一个元素,如果其 display 属性值是 inline-block,那么即使其里面内容再多,只要是正常文本,宽度也不会超过容器。
CSS 世界为何要设计“包裹性”呢?按钮就是 CSS 世界中极具代表性的 inline-block 元素,可谓展示“包裹性”最好的例 子,具体表现为:按钮文字越多宽度越宽(内部尺寸特性),但如果文字足够多,则会在容器的 宽度处自动换行(自适应特性)。“包裹性”对实际开发有什么作用呢? 请看这个需求:页面某个模块的文字内容是动态的,可能是几个字,也可能是一句话。然后,希望文字少的时候居中显示,文字超过一行的时候居左显示。该如何实现?
<div class="box">
<div class="conent">
文字多文字多文字多文字多文字多文字多文字多
</div>
</div>
.box{
text-align: center;
width: 200px;
background-color: red;
}
.conent{
display: inline-block;
text-align: left;
}
如果inline-block 内容多了就会触发自适应特性,自动换行,包裹性的应用
![3dc902cd1eeb0263d2347c19148ab199.png](https://i-blog.csdnimg.cn/blog_migrate/22fd961f214eee375a17dcefae42bc5f.png)
- 首选最小宽度
首选最小宽度,指的是元素适合的最小宽度,在上面的例子中,外部容器的宽度是200px,如果宽度是0,那么里面的inline-block的元素的宽度是什么?是 0 吗?不是。在 CSS 世界中,图片和文字的权重要远大于布局,因此,CSS 的设计者显然是不会让图文在 width:auto 时宽度变成 0 的,此时所表现的宽度就是“首选最小宽度”首选最小宽度,
具体表现规则如下:东亚文字(如中文)最小宽度为每个汉字的宽度。西方文字最小宽度由特定的连续的英文字符单元决定。并不是所有的英文字符都会组成连续单元, 一般会终止于空格(普通空格)、短横线、问号以及其他非英文字符等,如果想让英文字符和中文一样,每一个字符都用最小宽度 单元,可以试试使用 CSS 中的 word-break:break-all。类似图片这样的替换元素的最小宽度就是该元素内容本身的宽度。
首选最小宽度”对我们实际开发有什么作用呢? 可以让我们遇到类似现象的时候知道原因是什么,方便迅速对症下药,其他就没什么用了。有点失望? 那好,我就举个利用“首选最小宽度”构建图形的例子吧。请问,如何使用一 层 HTML 标签分别实现下图所示的“凹”和“凸”效果(注意要兼容 IE8)? 由于要兼容 IE8,CSS 新世界中图形构建利器的盒阴影和背景渐变全都没有用武之地,怎么办呢?我们可以利用“首选最小宽度”的行为特点把需要的图形勾勒出来。
<span class="ao"></span>
<span class="tu"></span>
.ao,
.tu {
display: inline-block;
width: 0;
font-size: 14px;
line-height: 18px;
margin: 35px;
color: #fff;
}
.ao:before,
.tu:before {
outline: 2px solid #cd0000;
font-family: Consolas, Monaco, monospace;
}
.ao:before {
content: "love你love";
}
.tu {
direction: rtl;
}
.tu:before {
content: "我love你";
}
![a2ce5bb1709d93240a204ebae4d25440.png](https://i-blog.csdnimg.cn/blog_migrate/8a44c56f4e02e5daed5483da734e69bd.png)
![4d4387752084b0e5196df6253524017b.png](https://i-blog.csdnimg.cn/blog_migrate/49dfd55883bff8ab5ea84a18bb068e2b.png)
![9363e0b3c518c2eee382598a25ea3a10.png](https://i-blog.csdnimg.cn/blog_migrate/952465561a3ff9b2986db739cc1c9575.png)
- 最大宽度
最大宽度就是元素可以有的最大宽度。我自己是这么理解的,“最大宽度”实际等同于“包裹性”元素设置 white-space:nowrap 声明后的宽 度。如果内部没有块级元素或者块级元素没有设定宽度值,则“最大宽度”实际上是最大的连 续内联盒子的宽度。 什么是连续内联盒子?这里你就简单地将其理 解为 display 为 inline、inline-block、inline-table 等元素。“连续内联盒子”指 的全部都是内联级别的一个或一堆元素,中间没有任何的换行标签<br>或其他块级元素。
![95e57e16bf84d19d0e610f2fd2cd7b2e.png](https://i-blog.csdnimg.cn/blog_migrate/d77435d2b21ec324322fdd760d6fc333.png)
内联盒模型
- 内容区域(content area)
- 内联盒子(inline box)
- 行框盒子(line box)
- 包含盒子(containing box)
内联盒子(inline box)。“内联盒子”不会让内容成块显示,而是排成一行,这里的内联盒子指的是元素的“外在盒子”,用来决定元素是内联还是块级。该盒子又可以细分为“内联盒子”和“匿名内联盒子”,不会成块显示,而是并排显示在一行的boxes,如span
,a
,em
等标签以及匿名inline boxes(即不含把标签的裸露的文字)
行框盒子(line box)。每一行就是一个行框盒子,每个行框盒子都是由一个个内联盒子组成,注意:line-height是作用在行框盒子上的,并最终决定高度(替换元素除外,后面会讲解什么是替换元素)。由一个一个的inline boxes组成,一行即为一个line box,单个line box的高度由其包含的所有inline boxes中,高度最大的那个决定(由line-height
起作用,后面解释),而一个一个的line box的高度就堆叠成了containing box的高度。
包含盒子(containing box)。外层盒子模型,包含了其他的boxes, 此盒子由一行一行的“行框盒子”组成(css规范中,并没有“包含盒子”的说法,更准确的称呼是“包含块”(containing block)。
内容区域(content area)。内容区域指的是一种围绕文字看不见的盒子,其大小仅受字符本身特性控制,本质上是一个字符盒子(character box);但是图片这样的替换元素,其显示内容不是文字,因此内容区域可以看成是元素自身。
<div>
这里是一个div,里面包含了独立的文字,
<span>span标签</span>
<em>em标签</em>,
以及其他的一些文字。
</div>
![f1b7c0cc2d030d55b5b3738a5173cdc8.png](https://i-blog.csdnimg.cn/blog_migrate/e920938aac2f8c771d1ee1b892a0e229.png)
替换元素
由于替换元素在很多表现上都与普通内联元素不一样,因此在这里着重介绍一下替换元素。
- 根据“外在盒子”是内联还是块级,我们把元素分为内联元素和块级元素,而根据内容是否可替换,我们把元素分为可替换元素和非替换元素。
- <img>,<video>,<canvas>,<input>,<textarea>,<iframe>都是替换元素。
- 替换元素外观不受页面css的影响,有自己的尺寸,一般为300 * 150,在很多css属性上有自己的一套表现规则,例如vertical-align默认就是元素下边缘对齐,而不是基线对齐。
- 替换元素尺寸计算规则:css尺寸 > html尺寸 > 固有尺寸
- 内联替换元素和块级替换元素规则一致,即display: block,其宽度也不会100%。
- 替换元素固有尺寸无法更改,width和height改变的是content-box的宽高,而默认替换元素的object-fit是fill,也就是会填充content-box,因此看上去像是改变了固有尺寸。
- 替换元素before和after伪元素无效。
1 width
![148f88375bf683c7ce35a3849bbbf1a1.png](https://i-blog.csdnimg.cn/blog_migrate/1507075e1bbf4a257d5b7751f3e68a61.jpeg)
width:auto与width:100%区别?width:auto意思是width + margin+padding+border=内容宽;width:100%,就是width就等于父内容宽,当增加padding,border,margin时候,会大于父内容宽,出现滚动条。
子元素width:100%:是把整个个content拉伸的和父相同。
1、当设置"box-sizing:content-box"时,子元素设置宽度的百分比是指子元素内容区域相对于父元素内容区域;
2、当设置"box-sizing:border-box"时,子元素设置宽度的百分比是指子元素整个盒子区域相对于父元素内容区域;
3、如果想要正确使用"width:100%"这一属性,一定要设置"box-sizing:border-box",否则会造成子元素溢出。
子元素width:auto;是把整个盒模型拉伸的和父相同,它也可以表示为以下四个值 CSS2.1的尺寸体系
- fill-available
- fit-content
- min-content
- max-content
width:fill-available比较好理解,比方说,我们在页面中扔一个没有其他样式的<div>
元素,则,此时,该<div>
元素的width表现就是fill-available,自动填满剩余的空间。也就是我们平常所说的盒模型的margin,border,padding的尺寸填充。出现fill-available关键字值的价值在于,我们可以让元素的100%自动填充特性不仅仅在block水平元素上,其他元素,例如,我们一直认为的包裹收缩的inline-block元素上:此时,元素兼具了块状元素的自动填充特性以及内联元素的定位对齐等特性(vertical-align/height/line-height)。于是,(例如)我们就可以直接使用line-height让一个块状表现的元素垂直居中。
![894e8e3a49ca22f9dc4b2e809dc207cb.png](https://i-blog.csdnimg.cn/blog_migrate/4989ab05d5fc75c5e3a020575993eaf1.png)
width:max-content表现得好像设置了white-space:nowrap一样,文字一马平川下去,元素的宽度也变成了这些文字一行显示的宽度!为什么会这么表现呢?定义就是这样的,对吧,我们对照下,首先,假设我们的容器有足够的空间,你想呀,容器足够空间,那下面的描述文字肯定会从左到右排列一行显示了,此时,上面的图片和下面的文字哪个内容宽度大?,自然是文字啦,所谓max-content就是width值采用宽度大的那个内容的宽度,也就是这里的文字的长度了
![b344761d3bd5719b3ff2d1ea95d3472a.png](https://i-blog.csdnimg.cn/blog_migrate/865f6ad7330851d4bf06c28a8d593027.jpeg)
min-content宽度表示的并不是内部哪个宽度小就是哪个宽度,而是,采用内部元素最小宽度值最大的那个元素的宽度作为最终容器的宽度。首先,我们要明白这里的“最小宽度值”是什么意思。对于替换元素,例如图片的最小宽度值就是图片呈现的宽度,对于文本元素,如果全部是中文,则最小宽度值就是一个中文的宽度值;如果包含英文,因为默认英文单词不换行,所以,最小宽度可能就是里面最长的英文单词的宽度。So,大家明白的说同样的是和display:inline-block做比较,display:inline-block虽然也具有收缩特性,但宽度随最大长度长的那一个(同时不超过可用宽度)。而width:min-content的最终宽度是图片和文字最小宽度值里面较大的那一个。
![023f92e77587d72f5ddb6177d51fb032.png](https://i-blog.csdnimg.cn/blog_migrate/8cf5ed7a3ee2e6cc9c67afc267e7d060.jpeg)
width:fit-content也是应该比较好理解的,“shrink-to-fit”表现,换句话说,和CSS2.1中的float, absolute, inline-block的尺寸收缩表现是一样的OK,然后,有小伙伴会疑问,既然跟很多CSS声明有一样的表现,那为什么还要再弄个新东西呢?就拿水平居中效果举例,首先浮动肯定不行,因为只有左浮动和右浮动;绝对定位压根不占据空间,普通流中根本无法应用,而inline-block需要父级使用text-align:center,而本身可能还需要text-align:left略烦。而width:fit-content可以没有这些烦恼,因为,width:fit-content可以实现元素收缩效果的同时,保持原本的元素block水平状态,于是,就可以直接使用margin:auto实现元素向内自适应同时的居中效果了。
![d1d75a957aab0f6482015e75271e3a7d.png](https://i-blog.csdnimg.cn/blog_migrate/4e45c0ad2335e35fa8a76d2938d6719c.jpeg)
![c5b99cb14f7926057b0a4d93d2df9167.png](https://i-blog.csdnimg.cn/blog_migrate/18eb65476433c1143a025ac29fe1babf.jpeg)
![4a1116b03c874b590d106ddf6d08e25e.png](https://i-blog.csdnimg.cn/blog_migrate/d166f0b82546f53be4750332df73b972.jpeg)
2 hieght
height:100%不生效的原因以及解决办法?
错误观点是形成死循环,正确观点是如果父元素的高度是没有显示表示,并且没有使用绝对定位,则它的计算值 渲染后值是auto,然后子元素根据auto乘以100%,'auto' * 100/100 = NaN,所以子元素是不可以得到正确高度,给过为0.解决办法是1可以显示设置html,body{ height: 100%} 2 使用父元素绝对定位(格式化宽度/高度仅出现在“绝对定位模型”中,也就是出现在position属性值为absolute或fixed的元素中。当left/top或top/bottom对立方位的属性值同时存在的时候,元素的宽度/高度表现为“格式化宽度/高度”,其宽度/高度相对于最近的具有定位特性(position属性值不是static)的祖先元素计算)
<div class="box">
</div>
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.box {
width: 100%;
height: 100%;
background: #000;
}
![4b5f03c142907ba50584792f58727660.png](https://i-blog.csdnimg.cn/blog_migrate/80a08002ded749ab7b26a4f807503a52.jpeg)
3 margin
- 元素的margin-left,top,right,bottom百分比时,依据谁计算?
是依据相对于父元素的width计算,当没有为元素设置width,则默认值为width:auto,原因是:height:100%不生效,所以不能用height只能用width(CSS权威指南中死循环说法 正常流中的大多数元素都会足够高以包含其后代元素(包括外边距),如果一个元素的上下外边距时父元素的height的百分数,就可能导致一个无限循环,父元素的height会增加,以适应后代元素上下外边距的增加,而相应的,上下外边距因为父元素height的增加也会增加,如此循环。) - 为什么margin:auto可以让元素水平居中,不可以让元素垂直居中
margin: auto的填充规则:一侧定值(包括不设定值取默认值0的情况),另一侧auto,那么另外一侧的margin为剩余空间大小。两侧auto,则平分剩余空间。所以之所以可以水平居中是因为浏览器的水平居中全都是因为元素在水平方向上具有自动填充父元素剩余空间的特性,但是垂直方向并没有这个特性(文档流方向决定了这一现象)解决办法:绝对定位元素的垂直居中,将其“格式化宽度和高度”(这个概念在另一篇flex替代布局中有讲过),令元素在水平和垂直方向上都具有自动填充的特性,就可以通过margin: auto的“触发条件”啦,这也是水平居中办法,position:absolute+ margin:auto原理。具体解决方法
.father {
width: 300px;
position: relative;
}
.son {
position: absolute;
top: 0;bottom: 0;
left: 0;right:0;
margin: auto;
- BFC塌陷,垂直方向margin合并
4 padding
5 width height margin padding相互作用
水平格式化:
替换元素:作为其他内容占位符的一个元素,例如img,它只指向一个图像文件,这个文件将插入到文档流中该img元素本身所在的位置,大多数的单元素也可以替换例如<input>
非替换元素: 如果元素的内容包含在文档中,例如一个段落的文本内容都放在钙元素本身之内 水平属性只有margin-left,margin-right以及width可以设置为auto;下面介绍使用auto场景:
非替换元素auto规则:auto出现目的就是为了弥补一个计算,当前值以及实际所需总和的差距。
单auto:如果margin中有一个值为auto,那么这个auto值等于总和-margin另一个值-padding,
多auto: 如果margin两个都设置为auto;width有值,那么父元素则居中。
![25864f62246e41730320dd4246ba3f32.png](https://i-blog.csdnimg.cn/blog_migrate/3cb2d4b689ff90c02f68499e64f6e6af.jpeg)
如果margin-left:auto; width:auto; 那么设置为auto的外边距会减少到0;
如果三个属性都设置设置为auto;结果两个外边距都设置为0,而width会尽可能的宽,这种情况和默认情况相同。
替换元素auto规则:如果width为auto;元素的宽度则是内容的股友宽度。如果img的高度改变则其宽度也会改变。
垂直格式化:margin-top,margin-bottom以及height可以为auto;
如果上下边距设置为auto,实际上会重置为0;如果父元素为auto;并且子元素为auto;
那么子元素的外边距会超出包含这些子元素的元素不过如果块级元素有上内边距活下内边距,其高度则是从其最高子元素的上外边距边界到其最低子元素的下外边距边界之间的距离。
负外边距:如果上下两个负外边都设置为负值,则取绝对值最大的,如果设置为一正一负,则会从正外边距减去这个负外边距的绝对值。
![131127bdeed46710846016ca4e3a9e1b.png](https://i-blog.csdnimg.cn/blog_migrate/ee1662b551c2ac037c8409459fb2f685.jpeg)
![acca86960af5c571efbdae8b81fd36e7.png](https://i-blog.csdnimg.cn/blog_migrate/192453eed780c6a36f1c37439d4dd7e3.jpeg)
6 position
![bb68674ef322f4bc96e77d9aea11106e.png](https://i-blog.csdnimg.cn/blog_migrate/40bfce9dc6c23dbc680ccaed93205125.jpeg)
![f1810b7ab0cc392370b9ea15df6f6665.png](https://i-blog.csdnimg.cn/blog_migrate/855d093040a5848b138be55614b64a19.jpeg)
7 float
float的设计初衷就是为了为了实现文字环绕效果 ,所以老 IE 浏览器与浮动相关的 bug 非常多。
float 布局优点:相对于 流 玄玄乎乎的东西 更加容易理解以及上手,缺点就是: 一个原因是纯浮动布局容错性差,容易出现比较严重的布局问 题,还有一个原因就是 float 本身就是魔鬼属性,容易出现意料之外的情况,这里的意料之外 除了 float 属性自身特性(如父元素高度塌陷)导致的布局问题外,还包括诸多兼容性问题。 所以 浮动是魔鬼,少砌砖头、少浮动,要更多地去挖掘 CSS 世界本身的“流动性”和“自适应性”,以构建能够适用于各种环境的高质量的网页布局 。 如何解决这种砖头式思维的float布局? CSS3 出现了类似 flex 弹性盒 子布局这种更表层、更上层、更浅显、更直白的 CSS 属性,以另外一种更加简单的方式让大家 不得不以自适应的方式去实现布局。
float的特性:
- 包裹性;
- 块状化并格式化上下文;
- 破坏文档流;
- 没有任何 margin 合并;
- 包裹性以及自适应性
所谓“包裹 性”,由“包裹”和“自适应性”两部分组成。 假设浮动元素父元素宽度 200px,浮动元素子元素是一个 128px 宽度的图片, 则此时浮动元素宽度表现为“包裹”,就是里面图片的宽度 128px,
.father { width: 200px; }
.float { float: left; }
.float img { width: 128px; }
<div class="father">
<div class="float">
<img src="1.jpg">
</div>
</div>
自适应性。如果浮动元素的子元素不只是一张 128px 宽度的图片,还有一大波普通 的文字, 则此时浮动元素宽度就自适应父元素的 200px 宽度,最终的宽度表现也是 200px。
<div class="father">
<div class="float">
<img src="1.jpg">我是帅哥,好巧啊,我也是帅哥,原来看这本书的人都是帅哥~
</div>
</div>
- 块状格式化上下文
元素一旦 float 的属性值不为 none,则其 display 计算值就是 block 或者 table。
span {
display: block; // 多余, 已经是块元素的
float: left;
}
span {
float: left;
vertical-align: middle; // 多余,块元素对vertical-align 不生效
}
![dbbf3637881892b616f28afe45921a87.png](https://i-blog.csdnimg.cn/blog_migrate/bebf996269c025fb4d792531456ab090.jpeg)
![4c31db4dc00d95e65a526ea08c6f5f58.png](https://i-blog.csdnimg.cn/blog_migrate/20aa1e7a2b0234068a576e8e0e16f26b.jpeg)
float 属性有个著名的特性表现,就是会让父元素的高度塌陷 , float 属性让父元素高度塌陷的原因就是为了实现文字环绕效果。 但是,后来事情的发展超出了 CSS 设计者的意料,图文展示只是新时代 Web 展示的一小部分, 而文字环绕这种上世纪风格的效果现在已然不流行了,于是 float 很少发挥其原本的作用,反 而被大肆使用满屏布局。显然,布局的时候是不需要父元素塌陷的。于是,高度塌陷这种特反而成为了 float 属性一个不得不重视的坑。
高度塌陷”只是让跟随的内容可以和浮动元素在一个水平线上,但这只是实现“环 绕效果”的条件之一 , 行框盒子如果和浮动元素的垂直高度有 重叠,则行框盒子在正常定位状态下只会跟随浮动元素,而不会发生重叠”。 意,这里说的是“行框盒子”,也就是每行内联元素所在的那个盒子,而非外部的块状 盒子。实际上,由于浮动元素的塌陷,块状盒子是和图片完全重叠的,例如,我们给环绕的<p> 元素设置个背景色,同时把图片搞透明,则效果如图 6-6 所示 块状盒子中的“行框盒子”却被浮动元素限制,没有任何的重叠,我们可以借助::first-line 伪元素暴露第一行的“行框盒子 , 这种“限制”是根深蒂固的,也就是“行框盒子”的区域永远就这么大,只要不改变当前 布局方式,我们是无法通过其他 CSS 属性改变这个区域大小的。浮动后 面元素 margin 负无穷大依然无效的原因只有外部的块状容器盒子尺寸变大,而和浮动元素垂直方向有重叠的“行框盒子” 依然被限死在那里,如图 6-8 所示。
![4e0e71a3cbfb4823a212d1397ba0132e.png](https://i-blog.csdnimg.cn/blog_migrate/287d8c9816343f0af0823e98bca9971e.jpeg)
![e62f0f65ca25d056e661d9bfeb6264bc.png](https://i-blog.csdnimg.cn/blog_migrate/523e0c96f14243075878115113b06c36.jpeg)
很多人会有这样的想法,就是认为一个元素只 要设置了具体的高度值,就不需要担心 float 属性造成的高度塌陷的问题了,既然有了高度, 何来“高度塌陷”。这句话对不对呢?是对的。但是,其中也隐含了陷阱,因为“文字环绕效果” 是由两个特性(即“父级高度塌陷”和“行框盒子区域限制”)共同作用的结果,定高只能解决
“父级高度塌陷”带来的影响,但是对“行框盒子区域限制”却没有任何效果,结果导致的问题 是浮动元素垂直区域一旦超出高度范围,或者下面元素 margin-top 负值上偏移,就很容易使 后面的元素发生“环绕效果”,代码示意如下:
<div class="father">
<div class="float">
<img src="zxx.jpg">
</div>
我是帅哥,好巧啊,我也是帅哥,原来看这本书的人都是帅哥~ </div>
<div>虽然你很帅,但是我对你不感兴趣。</div> .father {
height: 64px;
border: 1px solid #444;
}
.float {
float:left;
}
.float img {
width: 60px; height: 64px;
}
从这段代码可以看出父级元素.father 高度设置的和图片高度一模一样,都是 64px。按 道理,下面的“虽然你很帅,但是我对你不感兴趣。”这些 文字应该居左显示,但最后的结果却是图 6-9 所示的这样。 口口声声说“不感兴趣”,最后却依旧环绕在帅哥图片 周围。为什么会出现这种现象呢? 虽然肉眼看上去容器和图片一样高,但是,应该都知道内联状态下的图片底部是有间隙的,也就是.float 这个浮动元素的实际高度 并不是 64px,而是要比 64px 高几像素,带来的问题就是浮动元素的高度超出.father 几像素。 于是,下面的文字就遭殃了,因为“虽然你很帅......”这段文字所在的“行框盒子”和浮动元素在 直位置有了重叠,尽管就那么几像素。于是,区域被限制,形成了图 6-9 所示的“被环绕”效果。 直位置有了重叠,尽管就那么几像素。于是,区域被限制,形成了图 6-9 所示的“被环绕”效果。
![4ed2162169dd52e10866d89ad2115ef9.png](https://i-blog.csdnimg.cn/blog_migrate/e01309aba3eab52b1df7b4db01e76c69.png)
浮动的作用机制:
<h3>标题<a href="#">更多</a></h3>
![eef937983b89ee075c43f8ee6b8a15e4.png](https://i-blog.csdnimg.cn/blog_migrate/722e7dc96ab7a5600577cf0cc22286bc.png)
为啥会出现这种现象?
- 浮动锚点是 float 元素所在的“流”中的一个点,这个点本身并不浮动,就表现而言 更像一个没有 margin、border 和 padding 的空的内联元素。
- 浮动参考指的是浮动元素对齐参考的实体。
在 CSS 世界中,float 元素的“浮动参考”是“行框盒子”,也就是 float 元素在当前 “行框盒子”内定位。再强调一遍,是“行框盒子”,不是外面的包含块盒子之类的东西,因为 CSS 浮动设计的初衷仅仅是实现文字环绕效果。在 CSS 新世界中,float 被赋予了更多的作用 和使命,“浮动参考”就不仅仅是“行框盒子”了,不过此非本书重点,就不展开了。 正是因为 float 定位参考的是“行框盒子”,所以“更多”才会在第二行显示。还没理解? 那再具体解释一下:每一行内联元素都有一个“行框盒子”,这个例子中标题文字比较多,两行 显示了,因此有上下两个“行框盒子”,而“更多”所在的<a>元素是在标题文字后面,位于第 二行,因此,这里设置了 float:right 的<a>元素是相对于第二行的“行框盒子”对齐的, 也就是图 6-11 所示的效果。 趁热打铁,假如说我们的标题文字再多两个字,正好两行,请问:“更多”两字又当如何 显示呢?估计不少人已经可以脑补出最终的样式表现了,“更 多”会孤零零地显示在第三行的右边,但容器高度仍然是两行 文字的高度,如图 6-12 所示。 上面的解释有一个很大的漏洞就是,如果 float 元 素前后全是块元素,那根本没有“行框盒子”,何来对齐的说法? 此时,就需要上面提到的“浮动锚点”出马了。“浮动锚点”这个术语名称本身很具有欺骗性, 看上去应该与 float 的定位位置有关,实际上关系浅薄,在我看来,其作用就是产生“行框盒 子”,因为“浮动锚点”表现如同一个空的内联元素,有内联元素自然就有“行框盒子”,于是, float 元素对齐的参考实体“行框盒子”对于块状元素也同样适用了,只不过这个“行框盒子” 由于没有任何内容,所以无尺寸,看不见也摸不着罢了。
![85c2dbb285de089cd169e910441a3b9c.png](https://i-blog.csdnimg.cn/blog_migrate/9a55cea6fde5ac1896d243b847c82cce.png)
float高度坍塌带来问题,但是可以实现两栏或者多栏自适应布局。
![18c5f39914e7e57ae05fd4da0f0cc7fe.png](https://i-blog.csdnimg.cn/blog_migrate/913e9a9d092509bcbc6d0c508bdc2a4d.jpeg)
.animal 多了一个 margin-left:70px,也就是所有小动 物都要跟男主保持至少 70px 的距离,由于图片宽度就 60px,因此不会发生环绕,自适应效果达成。 原理其实很简单,.animal 元素没有浮动,也没有设置宽度,因此,流动性保持得很好, 设置margin-left、border-left或者padding-left都可以自动改变content box的尺寸,
继而实现了宽度自适应布局效果。
<div class="father">
<img src="me.jpg">
<p class="animal">小猫1,小猫2,...</p>
</div>
.father {
overflow: hidden;
}
.father > img {
width: 60px; height: 64px;
float: left;
}
.animal {
margin-left: 70px;
}
解决浮动坍塌问题 方法就是clear 属性。
clear 属性的元素自身如何 如何,而不是让 float 元素如何如何 。
none:默认值,左右浮动来就来。
left:左侧抗浮动。
right:右侧抗浮动。
both:两侧抗浮动。
clear 属性是让自身不能和前面的浮动元素相邻,注意这里“前面的”3 个字, 也就是 clear 属性对“后面的”浮动元素是不闻不问的,因此才 2 行显示而非 3 行。 更进一步,考虑到 float 属性要么就 left 要么就 right,不可能同时存在,同时由于 clear 属性对“后面的”浮动元素不闻不问,因此,当 clear:left 有效的时候,clear:right 必定无效,也就是此时 clear:left 等同于设置 clear:both;同样地,clear:right 如果 有效也是等同于设置 clear:both。由此可见,clear:left 和 clear:right 这两个声明就 没有任何使用的价值,至少在 CSS 世界中是如此,直接使用 clear:both 吧。
举个例子,假设容器宽度足够宽,有 10 个<li>元素,设置了如下 CSS 代码:
li {
width: 20px; height: 20px;
margin: 5px;
float: left;
}
li:nth-of-type(3) {
clear: both;
}
也就是说,第三个<li>设置了 clear:both,请问表现是怎样的?或者这么问吧:列表最后 是 1 行显示、2 行显示,还是 3 行显示呢?
clear 属性只有块级元素才有效的,而::after 等伪元素默认都是内联水平,这就是借 助伪元素清除浮动影响时需要设置 display 属性值的原因 .
.clear:after {
content: '';
display: table; // 也可以是'block',或者是'list-item' clear: both;
}
<div class="father">
<img src="me.jpg">
<div class="animal">
小猫 1,小猫 2,
<div class="clear"></div> 小猫 3,小猫 4,...
</div>
</div>
由于 clear:both 的作用本质是让自己不和 float 元素在一行显示,并不是真正意义上 的清除浮动,因此 float 元素一些不好的特性依然存在,于是,会有类似下面的现象。
(1)如果 clear:both 元素前面的元素就是 float 元素,则 margin-top 负值即使设 成-9999px,也不见任何效果2 clear:both 后面的元素依旧可能会发生文字环绕的现象
BFC
如果一个元素具有 BFC,内部子元素再怎么翻江倒海、翻 云覆雨,都不会影响外部的元素。所以,BFC 元素是不可能发生 margin 重叠的,因为 margin 重叠是会影响外面的元素的;BFC 元素也可以用来清除浮动的影响,因为如果不清除,子元素 浮动则父元素高度塌陷,必然会影响后面元素布局和定位,这显然有违 BFC 元素的子元素不会 影响外部元素的设定。 只要元素符合上面任意一个条件,就无须使用 clear:both 属性去清除浮动的 影响了。因此,不要见到一个<div>元素就加个类似.clearfix 的类名 ,
触发BFC情景:
<html>根元素;
float 的值不为 none;
overflow 的值为 auto、scroll 或 hidden;
display 的值为 table-cell、table-caption 和 inline-block 中的任何一个;
position 的值不为 relative 和 static。
<div class="father">
<img src="me.jpg">
<p class="animal">小猫1,小猫2,...</p>
</div>
img { float: left; } .animal { overflow: hidden; }
具有 BFC 特性的元素的子元素不会受外部元素影响,也不会影响外 部元素。于是,这里的.animal 元素为了不和浮动元素产生任何交集,顺着浮动边缘形成自己 的封闭上下文,如图 6-19 所示(垂直虚线为辅助示意)。 通流体元素在设置了 overflow:hidden 后,会自动填满容器中除了浮 动元素以外的剩余空间,形成自适应布局效果,而且这种自适应布局要比纯流体自适应 更加智能。比方说,我们让图片的尺寸变小或变大,右侧自适应内容无须更改任何样式代 码,都可以自动填满剩余的空间, 我们把图片的宽度从 60px 改成 30px.
![24bc71a4d5a17ab8472152792bb03173.png](https://i-blog.csdnimg.cn/blog_migrate/45414e7af992a3d9c9382d1e370c8b18.jpeg)
和基于纯流体特性实现的两栏或多栏自适应布局相比,基于 BFC 特性的自适应布局有如下 优点。
自适应内容由于封闭而更健壮,容错性 更强。比方说,内部设置 clear:both 不会与 float 元素相互干扰而导致错位,也就不会发生 类似于图 6-22 所示的问题。
(2)自适应内容自动填满浮动以外区域,无 须关心浮动元素宽度,可以整站大规模应用。比 方说,抽象几个通用的布局类名,如:
.left { float: left; } .right { float: right; } .bfc { overflow: hidden; }
<div class="bfc">
<img src="me.jpg" class="left">
<p class="bfc">小猫1,小猫2,...</p>
</div>
纯流体布局需要大小不确定的 margin 或 padding 等值撑开合适间距,无法 CSS 组件 化。例如,前面出现的 70px,其他类似布局可能就是 90px,无法大规模复用:
.animal { margin-left: 70px; }
两种不同原理的自适应布局策略的高下一看便知。甚至可以这么说,有了 BFC 自适应布局, 纯流体特性布局基本上没有了存在的价值。然 任何 BFC 元素和 float 元素相遇的时候,都可以实现自动填充的自适应布局。 但是,由于绝大多数的触发 BFC 的属性自身有一些古怪的特性,所以,实际操作的时候,能兼 顾流体特性和 BFC 特性来实现无敌自适应布局的属性并不多。下面我们一个一个来看,每个 CSS 属性选一个代表来进行说明。
float:left。浮动元素本身 BFC 化,然而浮动元素有破坏性和包裹性,失去了元素 本身的流体自适应性,因此,无法用来实现自动填满容器的自适应布局。
position:absolute。这个脱离文档流有些严重,过于清高,和非定位元素很难玩 到一块儿去
overflow:hidden。这个超棒!不像浮动和绝对定位,玩得有点儿过。其本身还是 一个很普通的元素,因此,块状元素的流体特性保存得相当完好,附上 BFC 的独立区域特性, 可谓如虎添翼、宇宙无敌!而且 overflow:hidden 的 BFC 特性从 IE7 浏览器开始就支持, 兼容性也很不错。唯一的问题就是容器盒子外的元素可能会被隐藏掉,一定程度上限制了这种 特性的大规模使用。不过,溢出隐藏的交互场景比例不算很高,所以它还是可以作为常用 BFC 布局属性使用的。
display:inline-block 会让元素尺寸包裹收缩,完全就不是我们想要的 block 水平的流动特性。
display:table-cell 这个 BFC 元素宽度设置得很大,比方说 3000px,那其实就跟 block 水平元素自动适应容器空间效果一模一样了,除非你的容器 宽度超过 3000px。实际上,一般 Web 页面不会有 3000px 宽的模块,所以,要是实在不放心,设个 9999px 好了! float-left { float: left; } .bfc-content { display: table-cell; width: 9999px; } 一是需要 IE8 及以上版本的浏览器;二是应 付连续英文字符换行有些吃力。但是,总体来看,其适用的场景要比 overflow:hidden 更为 广泛。
display:table-row。对 width 无感,无法自适应剩余容器空间。
display:table-caption。此属性一无是处。
对 BFC 声明家族大致过了一遍,能担任自适应布局重任的也就是以下 几个。
overflow:auto/hidden,适用于 IE7 及以上版本浏览器;
- display:inline-block,适用于 IE6 和 IE7;
- display:table-cell,适用于 IE8 及以上版本浏览器。 最后,我们可以提炼出两套 IE7 及以上版本浏览器适配的自适应解决方案。
借助 overflow 属性,如下: .lbf-content { overflow: hidden; }
融合 display:table-cell 和 display:inline-block ;
.lbf-content {
display: table-cell; width: 9999px; /* 如果不需要兼容 IE7,下面样式可以省略 */ *display: inline-block; *width: auto;
}
这两种基于 BFC 的自适应方案均支持无限嵌套,因此,多栏自适应可以通过嵌套方 式实现。这两种方案均有一点不足,前者如果子元素要定位到父元素的外面可能会被隐藏, 后者无法直接让连续英文字符换行。
overflow:hidden
要想彻底清除浮动的影响,最适合的属性不是 clear 而是 overflow。一般使用 overflow:hidden,利用 BFC 的“结界”特性彻底解决浮动对外部或兄弟元素的影响。虽然 有很多其他 CSS 声明也能清除浮动,但基本上都会让元素的宽度表现为“包裹性”,也就是会 影响原来的样式布局,而 overflow:hidden 声明不会影响元素原先的流体特性或宽度表现, 因此在我看来是最佳“结界”。
不过话又说回来,overflow 属性原本的作用指定了块容器元素的内容溢出时是否需要裁 剪,也就是“结界”只是其衍生出来的特性,“剪裁”才是其本职工作。
只要 overflow-x 和 overflow-y 设置了 上面的属性值,就一定会是这样的表现,实际上 overflow-x 和 overflow-y 的表现规则要 比看上去复杂些:如果 overflow-x 和 overflow-y 属性中的一个值设置为 visible 而另 外一个设置为 scroll、auto 或 hidden,则 visible 的样式表现会如同 auto。也就是说, 除非 overflow-x 和 overflow-y 的属性值都是 visible,否则 visible 会当成 auto 来 解析。换句话说,永远不可能实现一个方向溢出剪裁或滚动,另一方向内容溢出显示的效果。
关于浏览器的滚动条,有以下几个小而美的结论.
在 PC 端,无论是什么浏览器,默认滚动条均来自<html>,而不是<body>标签。
滚动条会占用容器的可用宽度或高度
一个可以让页面滚动条不发生晃动的小技巧,
html {
overflow-y: scroll;
}
:root {
overflow-y: auto;
overflow-x: hidden;
}
:root body {
position: absolute;
}
body {
width: 100vw;
overflow: hidden;
}
整体部分,::-webkit-scrollbar;
• 两端按钮,::-webkit-scrollbar-button;
• 外层轨道,::-webkit-scrollbar-track;
• 内层轨道,::-webkit-scrollbar-track-piece; • 滚动滑块,::-webkit-scrollbar-thumb;
• 边角,::-webkit-scrollbar-corner。 但是我们平时开发中只用下面 3 个属性:
::-webkit-scrollbar { /* 血槽宽度 */ width: 8px; height: 8px;
}
::-webkit-scrollbar-thumb { /* 拖动条 */
background-color: rgba(0,0,0,.3);
border-radius: 6px; }
::-webkit-scrollbar-track { background-color: #ddd; border-radius: 6px;
}
![acf7d15e1d816a585ea2de09b6de80a3.png](https://i-blog.csdnimg.cn/blog_migrate/089cc2ca9cf9e7fbbccecadad32f0cdb.png)
当 absolute 和 float 同时存在的时候,float 属性是无任何效果的。因此,没有任何理由 absolute 和 float 同时使用 , “块状化”和浮动类似,元素一旦 position 属性值为 absolute 或 fixed,其 display 计算值就是 block 或者 table。例如,<span>元素默认是 inline 水平,但是一 旦设置 position:absolute,其 display 计算值就变成了 block, 破坏性”,指的是破坏正常的流 特性。和 float 类似,虽然 absolute 破坏正 常的流来实现自己的特性表现,但本身还是受普 通的流体元素布局、位置甚至一些内联相关的 CSS 属性影响的, 两者都能“块状格式化上下文”, 也就是 BFC。 两者都具有“包裹性”,也就是尺寸收缩包裹,同时具有自适应性。有些人知道 display:inline-block 声明具有“包裹性”,希望绝对定位元素也如此,就有了下面这样 的设置: 实际上 absolute 天然具有“包裹性”,因此没有必要使用 display:inline-block, 如果要让元素显示或者“无依赖定位”,可以试试更简短的 display:inline。但是,和 float 或其他“包裹性”声明带来的“自适应性”相比,absolute 有一个平时不太被人注意的差异, 那就是 absolute 的自适应性最大宽度往往不是由父元素决定的,本质上说,这个差异是由“包 含块”的差异决定的。换句话说,absolute 元素具有与众不同的“包含块”。
.wrap {
display: inline-block; // 没有必要 position: absolute;
}
根元素(很多场景下可以看成是<html>)被称为“初始包含块”,其尺寸等同于浏览 器可视窗口的大小。
(2)对于其他元素,如果该元素的 position 是 relative 或者 static,则“包含块” 由其最近的块容器祖先盒的 content box 边界形成。
(3)如果元素 position:fixed,则“包含块”是“初始包含块”。
(4)如果元素 position:absolute,则“包含块”由最近的 position 不为 static 的祖先元素建立,具体方式如下。
如果该祖先元素是纯 inline 元素,则规则略复杂:
- 假设给内联元素的前后各生成一个宽度为 0 的内联盒子(inline box),则这两
个内联盒子的 padding box 外面的包围盒就是内联元素的“包含块”; - 如果该内联元素被跨行分割了,那么“包含块”是未定义的,也就是 CSS2.1
规范并没有明确定义,浏览器自行发挥。 否则,“包含块”由该祖先的 padding box 边界形成。
如果没有符合条件的祖先元素,则“包含块”是“初始包含块”。 可以看到,和常规元素相比,absolute 绝对定位元素的“包含块”有以下 3 个明显差异:
(1)内联元素也可以作为“包含块”所在的元素;
(2)“包含块”所在的元素不是父块级元素,而是最近的 position 不为 static 的祖先 元素或根元素;
(3)边界是 padding box 而不是 content box。 首先讲第一点差异,也就是内联元素可以作为“包含块”。这一点估计很多人都不知道,
因为平时使用得少。为何平时用得少?原因如下。
(1)我们一旦使用 absolute 绝对定位,基本上都是用来布局,而内联元素主要的作用是
图文展示,所谓道不同不相为谋,因此两者很难凑到一块儿。 (2)理解和学习成本比较高。内联元素的“包含块”不能按照常规块级元素的“包含块”
来理解。举个例子,如下 HTML 代码: 此时<span>元素的“包含块”范围是什么?
<span style="position:relative;">
我是<big style="font-size:200%;">字号很大</big>的文字!
</span>
如果对定义理解不够,很容易误认为包含块的上下边缘被其中“字号很大”的<big>元素 给撑大了。实际上,此时元素的“包含块”范围与<big>元素毫无关系,就算其字号大小设置
得再大,“包含块”范围依然是图 6-42 虚线所示的那么大。原因很简单,内联元素的“包含块” 是由“生成的”前后内联盒子决定的,与里面的内联盒子细节没有任何关系
我根据自己的进一步测试发现,内联元素的“包含块”可以受::first-line 伪元素影响, 但不受::first-letter 伪元素影响。
可以看出,内联元素的“包含块”范围相对稳固,不会受 line-height 等属性影响,因 此,理论上其还是有实用价值的。
兼容性问题。无论内联元素是单行还是跨行都存在兼容性问题。单行的兼容性问题存 在于“包含块”是一个空的内联元素的时候。例如,按照我们的理解,下面的代码实现的效果 应该是图片在容器的右上角对齐:
8 display
值: none, inline, block, list-item(列表), inline-block, table(表格), flex, inline-flex
4个div设置inline-block后,他们顶端没有对齐原因
inline-block 元素的基线是这个元素下正常文档流中最后一个 line box 的基线,除非这个元素中没有正常流的 line box 或者本身的 overflow 属性值不是默认的 visible ,这个时候 inline-block 元素的基线位置是margin的底边缘。
在 Firefox 浏览器下,display:none 的元素的 background-image 图片是不加载的, 包括父元素 display:none 也是如此;如果是 Chrome 和 Safari 浏览器,则要分情况,若父元 素 display:none,图片不加载,若本身背景图所在元素隐藏,则图片依旧会去加载;对 IE 浏览器而言,无论怎样都会请求图片资源。 如果不是 background-image 图片,而是<img>元素,则设置 display:none 在所有浏览器下依旧都会请求图片资源。
HTML5 中新增了 hidden 这个布尔属性,可以让元素天生 display:none 隐藏。例如: <div hidden>看不见我</div> 文本属性:
- text-align
- line-height
- vertical-align
- text-indent
- text-shadow
- word-spacing
- letter-spacing
- text-transform
- white-space
9 text-align
水平对齐 默认值是left
- 作用于块级元素
- 有left center right justify(两端对齐不同浏览器设置不同) inherit
- 具有继承性 对于块元素 水平居中就有两种方式一种是 margin: 0 auto text-align:center 都是针对父元素设置 垂直居中 也是针对父元素设置 height:xxx;line-height: xxx; 但是如果子元素是图片,还要对子元素图片设置vertical-align:center(适用于行内元素以及表单元格);
10 line-height
垂直对齐 行高
- 作用于所有元素
- 值有 百分比 数值 normal 以及 inherit
- 具有继承性
- line-height计算原理是行高减去字体大小的值平均分为上下两部分
- 百分比相对于元素字体的大小
11 vertical-align适用于行内元素以及表单元格
![45b621419dfd43ed1191342f6c89a069.png](https://i-blog.csdnimg.cn/blog_migrate/5e310275ad8421984d962877791d9acd.png)
中线的位置应该是字母高度的一半,顶线和底线很好理解就是最高和最低,基线指的是字母的最下方
从上到下这样方便记忆:
先是两个子元素的底线和父元素的顶线以及上基线对齐
top:元素的底线在 父元素的顶线 上,与之对齐
![33c9d75b59ccd2d66ddfba02a0066da0.png](https://i-blog.csdnimg.cn/blog_migrate/d5ba3338cdce794f118cf09beb01402e.png)
接下来就是super了
super:子元素的底线在父元素的上基线,与之对齐
![0e2c66adc45792ae091d254e655f8cc8.png](https://i-blog.csdnimg.cn/blog_migrate/da4b43262598d77a6198d8837b6b30f7.png)
然后就是
baseline:元素的基线与父元素的基线对齐
![f50121c33427f946996ac05ac4989bc6.png](https://i-blog.csdnimg.cn/blog_migrate/0c5672ed35772bbc2aac5bfbe474f4bb.png)
text-top:使元素的顶部与父元素的字体顶部对齐。
![42ed39170ef00f9d39b4f1cd26fd1fba.png](https://i-blog.csdnimg.cn/blog_migrate/27f0b61cca14686f96d883642054bfd0.png)
middle: 元素的中间与父元素上基线以及下基线中间对齐
![b7a57869be90ea0b7209767a12b9c118.png](https://i-blog.csdnimg.cn/blog_migrate/25876e2cfa7ab4c4c8ba9ddd627dc5e6.png)
text-bottom:使元素的底部与父元素的字体底部对齐。
![c226ac24e3f73f56c0f04b6f675f6a44.png](https://i-blog.csdnimg.cn/blog_migrate/9829ab0da2fd000a7b4bae7ccaefc539.png)
sub: 元素的基线和 父元素的下标基线对齐
![491c5191323b93d88c774a8127b49169.png](https://i-blog.csdnimg.cn/blog_migrate/7442d6a7f78fa27731efdc7d5dc3d4fd.png)
bottom: 子元素的顶部和父元素的底线对齐
![13da1ec0644887dd2e777f5e9eea7e03.png](https://i-blog.csdnimg.cn/blog_migrate/a3f73f5daf55334027b1f1134f505401.png)
为什么说vertical-align:middle并不是绝对的垂直居中对齐,我们看到的只是一种近似的效果?
答:middle指的是基线网上二分之一的x-height高度,我们可以近似理解字母x交叉点的位置,但是因为不同字体在行内盒子中的位置是不一样的,比如微软雅黑是一个字符下沉明显的字体,所有字符的位置都比其他字体要偏下一点,导致字母x的交叉点要在容器中分先的下面一点,所以居中就不是在容器的中分线了。
div的高度是由谁撑开的?
答:是由line-height属性全权决定的。并不是有文字撑开的。
行距是如何计算的? 行距 = line-height - font-size
内连元素中的幽灵空白节点原理?
.box {
line-height: 256px;
}
<div class="box">
<img src="1.jpg" height="128">
</div>
图片为内敛元素,会构成一个行框盒子,每一个行框盒子的前面都会有一个宽度为0的幽灵空白节点,其内敛特性和普通字符一模一样,这里的容器高度会等于lin-height设置的属性256px;元素默认情况下的对齐方式是基线对齐,即baseline。而在浏览器中,都有默认的字体的大小,在wrap里面虽然只有一个img标签,但其实存在一个我们看不见的空白节点。这个特殊的空白节点与普通文节点一样,具有文字大小,行高。因此,我们可以利用普通文本来代替这个节点来观察现象。我们在图片的后面输入一串XXX。如下:由于空白节点的存在,图片后面相当于跟了一个文本节点。而默认情况下,图片的对齐方式是以父级元素的基线对齐,为了保持与基线对齐,图片底部必须留出间隙,大小为上面提到的半倍文本间距[即(line-height
- font-size
) / 2]。而且line-height的值越大,间隙将越大。到此为止,结合我们上面对属性值特点的一些分析,要找到问题的解决办法就变得相当简单了。要去除图片底部的间隙,只需要将line-height
和vetical-align
属性的其中一个给干掉就可以了。
![9b89ee8a66defc61286b3f631ece09c0.png](https://i-blog.csdnimg.cn/blog_migrate/4639d9173f8e82aa79bd522c6778c1ad.png)
(1)将图片设置为display:block(利用vertical-align的生效前提);
(2)将vertical-align设置为top,bottom,或者middle等值(利用属性值的表现行为);
(3)将line-height设置为0(利用line-height为0时,基线上移);
(4)将font-size设置为0 (如果line-height的值为相对值,如1.5);
(5)将img设置浮动或者绝对定位(如果布局允许的话)
图文和文字混在一起是很常见的,那这种内联替换元素和内联非替换元 素在一起时的高度 表现又是怎样的呢 ?
由于同属内联元素,因此,会共同形成一个“行框盒子”,line-height 在这个混合元素 的“行框盒子”中扮演的角色是决定这个行盒的最小高度,听上去似乎有点儿尴尬,对于纯文 本元素,line-height 非常威风,直接决定了最终的高度。但是,如果同时有替换元素,则 line-height 的表现一下子弱了很多,只能决定最小高度,对最终的高度表现有望尘莫及之 感。为什么会这样呢?一是替换元素的高度不受line-height影响,二是vertical-align 属性在背后作祟
line-height继承 数值 百分比值 长度值有什么区别?
使用数值作为line-height的属性值,所有子元素继承的都是这个值,子元素计算出来就是继承值*子元素数值大小,如果使用百分比或者长度值作为属性值,所有子元素继承的最终的计算值。百分比时候则是从父元素那里计算好值,直接传给子元素。
解释下内连元素line-height的大值特性?为什么?
<div class="box">
<span>内容...</span>
</div>
CSS 代码有所不同,分别为
.box {
line-height: 96px;
}
.box span {
line-height: 20px;
}
和
.box {
line-height: 20px;
}
.box span {
line-height: 96px;
}
.box 元素的高度分别是多少
<span>是一个内联元素,因此自身是一个“内联盒子”,本例就这一个“内联盒子”,只要有“内联盒子”在,就 一定会有“行框盒子”,就是每一行内联元素外面包裹的一层 看不见的盒子。然后,重点来了,在每个“行框盒子”前面有 一个宽度为 0 的具有该元素的字体和行高属性的看不见的“幽 灵空白节点”,如果套用本案,则这个“幽灵空白节点”就在 <span>元素的前方 。
<div class="box">
字符<span>内容...</span>
</div>
当.box 元素设置 line-height:96px 时,“字符”高度 96px;当设 置 line-height:20px 时,<span>元素的高度则变成了 96px,而行框盒子的高度是由高度 最高的那个“内联盒子”决定的,这就是.box 元素高度永远都是最大的那个 line-height 的原因。
为什么下面的行距大于32px;
.box { line-height: 32px; }
.box > span { font-size: 24px; }
<div class="box">
<span>文字</span>
</div>
<div class="box">
x<span>文字 x</span>
</div>
![f16ebc510b4f4ea22fc8d89d2c47e4fd.png](https://i-blog.csdnimg.cn/blog_migrate/f13f9c1b555af5d1c364f68d370d12af.png)
对字符 而言,font-size 越大字符的基线位置越往下,因为文字默认全部都是基线对齐,所以当字 号大小不一样的两个文字在一起的时候,彼此就会发生上下位移,如果位移距离足够大,就会 超过行高的限制,而导致出现意料之外的高度
如何解决?
.box {
line-height: 32px;
font-size: 24px;
}
.box > span { }
问题一: 图片底部留有间隙的问题 ?
![cd203156d0706e4e9bedcd79020445ff.png](https://i-blog.csdnimg.cn/blog_migrate/37ce543fb8b92cf587c7b8e1669c940e.png)
当前 line-height 计算值是 20px,而 font-size 只有 14px,因此,字母 x 往下一定 有至少 3px 的半行间距(具体大小与字体有关),而图片作为替换元素其基线是自身的下边缘。 根据定义,默认和基线(也就是这里字母 x 的下边缘)对齐,字母 x 往下的行高产生的多余的 间隙就嫁祸到图片下面,让人以为是图片产生的间隙,实际上,是“幽灵空白节点”、 line-height 和 vertical-align 属性共同作用的结果。
解决问题的方法:
- 图片块状化。可以一口气干掉“幽灵空白节点”、line-height 和 vertical- align。
容器 line-height 足够小。只要半行间距小到字母 x 的下边缘位置或者再往上,自
然就没有了撑开底部间隙高度空间了。比方说,容器设置 line-height:0。
容器 font-size 足够小。此方法要想生效,需要容器的 line-height 属性值和当 前 font-size 相 关,如 line-height:1.5 或者 line-height:150%之类;否则只会让下
面的间隙变得更大,因为基线位置因字符 x 变小而往上升了。 (4)图片设置其他 vertical-align 属性值。间隙的产生原因之一就 是基线对齐,所以我们设置 vertical-align 的值为 top、middle、 bottom 中的任意一个都是可以的。
baseline确定规则
inline-block元素,如果内部有line box 则inline-block元素的baseline就是最后一个最为内容存在的元素[inline box]的baseline,而这个元素的baseline的却定就是根据它自身来定了
inline-block元素,如果其内部没有line box或者它的overflow属性不是visible,那么baseline将是这个inline-block元素的底margin边界。
一个inline-block元素,如果里面没有inline内联元素,或者overflow不是visible,则该元素的基线就是其margin底边缘,否则,其基线就是元素里面最后一行内联元素的基线。
![66e76a143a73785a0ae1798a0cdace09.png](https://i-blog.csdnimg.cn/blog_migrate/65aac5744ea722986d0655e5e4899fe2.png)
inline-box是指同一行的不同box模型,line-box则是一整行的box模型,
<div>
<span>123</span>
<span>abc</span>
<span>呵呵</span>
</div>
其中div是line-box,里面的三个span都是inline-box
.dib-baseline {
display: inline-block; width: 150px; height: 150px;
border: 1px solid #cad5eb; background-color: #f0f3f9;
}
<span class="dib-baseline"></span>
<span class="dib-baseline">x-baseline</span>
![40a49e05e1f92b175bbdc549122cceff.png](https://i-blog.csdnimg.cn/blog_migrate/4bdd613e6be3e673a0ea8240fd61ab37.png)
![f3cf3640da6f9b389cb89167223875ab.png](https://i-blog.csdnimg.cn/blog_migrate/77e2124e6a9ee8e41b60fe0aa830e68f.png)
注意basline和line-height息息相关,因为字符占据的高度是有line-height决定的,当行高变为0时,高度的起始位置就变为字符content area 的垂直中心位置。
问题二: 两个inline-box产生错位:比如设置line-height为0:
![13523dee3ef2b56bd0d5839da42f71f0.png](https://i-blog.csdnimg.cn/blog_migrate/29f93d712d6de44bee22ab48e74ec78a.png)
因为字符实际占据的高度是由行高决定的,当行高变成0的时候,字符占据的高度也是0
,此时,高度的起始位置就变成了字符content area的垂直中心位置,于是,文字就一半落在看看2的外面了。由于文字字符上移了,自然基线位置(字母x
的底边缘)也往上移动了,于是,两个框框的垂直落差就更大了,前面的对于inline-block基线的定义可知,对于有内容的inline-block,其基线为最后一行文本基线所在的位置,而对于空白的inline-block,其基线为margin bottom边缘所在位置,即底部边缘。因为默认情况下为基线对齐,这两条基线对齐后就形成了上图那种错位的现象。知道了错位的原因,要解决也方便了。我们仅需将对齐方式设置为bottom,middle,top等值就可以了。现在设置为middle。
inline-box是指同一行的不同box模型,line-box则是一整行的box模型,
<div>
<span>123</span>
<span>abc</span>
<span>呵呵</span>
</div>
其中div是line-box,里面的三个span都是inline-box
问题三: 对图片设置vertical-align: center 无效
按照vertical-align生效个条件可知,给img设置middle对齐后理论上应该是居中对齐才对,但为什么没有起作用呢?是真的没有起作用吗?答案是:起作用了。实际上,vertical-align:middle是起作用的了,但至于最后图片为什么没有在父级里面垂直居中,是因为后面的空白节点高度不足,导致基线偏上。按照中线的定义,中线也是偏上。我们可以用一个字母x代替后面的空白节点,来观察现象。
图片“近似”垂直居中在了父级元素。这是因为设置行高后,根据之前分析的line-height
等于font-size
+2倍的文字上下间距
可知,父级基线往下。中线为基线往上二分之一x高度,此时图片的中线就与后面的x中线点对齐,实现了近似垂直居中的效果
<div class="wrap" style="height:200px;">
<img src="xxx.png" class="middle" />
</div>
![3480f6ada05164e6e140d044df576c66.png](https://i-blog.csdnimg.cn/blog_migrate/9612e4161c9a359f1afb8ecc925aadb4.png)
![21ce987f14a8cd7cc5507ae15efcbc48.png](https://i-blog.csdnimg.cn/blog_migrate/a06fd45ffa37201b97f3ebc2c8dd5afc.png)
12 text-indent: 文本缩进
- 作用于块级元素,
- 缩进值为百分比时,缩近值是相对于父元素的。
- 具有继承性,子元素会继承父元素的文本缩进值。
- 值 为 length,inherit
13 word-spacing:字间隔
- 作用域所有元素
- 值为 数值 normal inherit
- 基友继承性
14 letter-spacing: 字母间隔
- 作用于所有元素
- 值为 数值 normal 以及inherit
- 具有继承性
15 text-shadow
16 white-space
适用于所有元素
值为normal nowrap pre pre-wrap pre-line inherit
![f1df3ceb9424dab204ed38353cc28c86.png](https://i-blog.csdnimg.cn/blog_migrate/96fe84439bd7ff3559c10ee54f3158fb.jpeg)
浮动和定位
float: left right none inherit
针对所有元素
podition: static relative absolute fixed inherit
针对所有元素
top, right bottom,left
百分数: 对于top和bottom相对于包含块的宽度,对于right和left,相对于包含块的宽度,
默认值: auto;
min-width,max-width 对于包含块的宽度,
百分数:相对于包含块的宽度。
应用于除了非替换行内元素和表元素以外的所有元素。
max-width,max-height
百分数:相对于包含块的宽度。
应用于飞=非替换行内元素和表元素以外的所有元素。
overflow:visible,hidden,scroll,auto,inherit
初始值:visible
应用于块级元素和替换元素
继承性无
visibility: visible,hidden,collapse,inherit
初始值:visible
应用于所有元素
继承性:有
父元素设置 visibility:hidden,子元素也 会看不见,究其原因是继承性,子元素继承了 visibility:hidden,但是,如果子元素设置 了 visibility:visible,则子元素又会显示出来。这个和 display 隐藏有着质的区别。
<ul style="visibility:hidden;">
<li style="visibility:visible;">列表1</li> <li>列表 2</li>
<li>列表 3</li>
<li style="visibility:visible;">列表4</li>
</ul>
“列表 1”和“列表 4”依旧 清晰可见。
visibility:hidden 不会影响计数器的计数,这和 display:none 完全不一样
.vh {
visibility: hidden;
}
.dn {
display: none;
}
ol {
border: 1px solid;
margin: 1em 0;
counter-reset: test;
}
li:after {
counter-increment: test;
content: counter(test);
}
<ol>
<li>列表</li>
<li class="dn">列表</li> <li>列表</li> <li>列表</li>
</ol> <ol>
<li>列表</li>
<li class="vh">列表</li> <li>列表</li> <li>列表</li>
</ol>
![a1f7a6fd1724a6fc2341fb0339df87f4.png](https://i-blog.csdnimg.cn/blog_migrate/62af3bdc4b7e136659061c0ad4db6c2a.png)
CSS3 transition支持的CSS属性中有visibility,但是并没 有 display。 由于 transition 可以延时执行,因此,和 visibility 配合可以使用纯 CSS 实现 hover 延时显示效果,由此提升我们的交互体验。
.box > .target {
display: none;
position: absolute;
opacity: 0;
transition: opacity .25s;
}
.box:hover > .target {
display: block;
opacity: 1; }
但是,下面的 CSS 语句却可以让.target 子元素有淡出的过渡效果:
.box > .target {
position: absolute;
opacity: 0;
transition: opacity .25s;
visibility: hidden;
}
.box:hover > .target {
visibility: visible;
opacity: 1; }
对隐藏的元素进行尺寸以及位置的获取建议使用visibility。 原因是,我们可以准确计算出元素的尺寸和位置,如果使用的是 display:none,则无论 是尺寸还是位置都会是 0,计算就会不准确。
替换元素的放置和大小:水平轴
![416116ad946fceb698085ce96972ab34.png](https://i-blog.csdnimg.cn/blog_migrate/08129d841ff3bb4aca90897852d236c4.jpeg)
竖直轴
![5ad2c3e03afd395e8be16967b471066f.png](https://i-blog.csdnimg.cn/blog_migrate/320825bf6dd20eb41aace7e891b3929e.jpeg)
z-index: auto inherit 数值可以为负数
初始值auto;
作用于 定位元素
继承性:无
![d72607628ccb5630eef0779c53b9178f.png](https://i-blog.csdnimg.cn/blog_migrate/2fae31f17dc49c5516430e180e83d471.jpeg)
![374616f99ade4f7c86763f9b0f104314.png](https://i-blog.csdnimg.cn/blog_migrate/da0842066bba8ca92c7fee5960a1f82a.jpeg)
![5ab9aa15ca26d31168398602985ae029.png](https://i-blog.csdnimg.cn/blog_migrate/7c96a76caab186ea94f3a93fcb458988.jpeg)
![652a5a41c69b19b80f988028dbcaf717.png](https://i-blog.csdnimg.cn/blog_migrate/c2682dd3771cdc679447e127da4fae88.jpeg)
![ad47d411063e77c82d2cb119c33e6305.png](https://i-blog.csdnimg.cn/blog_migrate/19bf301f60316e78e27f3686af919b68.jpeg)
css世界
outline属性
.crop {
overflow: hidden;
}
.crop > .crop-area {
width: 80px; height: 80px;
outline: 256px solid rgba(0,0,0,.5);
cursor: move;
}
outline 轮廓是可穿透的 outline 是第一个真正意义上的不占据任何空间的属性 。
cursor属性
cursor: pointer,help,progress,wait,context-menu,// 设置cookie
function setCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}else{
var expires = "";
}
document.cookie = name+"="+value+expires+"; path=/;domain=.http://web.uvw.org.cn";
}// 删除cookie
function deleteCookie(name) {
setCookie(name,"",-1);
}
$('#downApp').click(function(){// deleteCookie('BAIDUID');// window.open('https://web.uvw.org.cn/');
});
参考文章:https://www.jianshu.com/p/92911d1aa269
css世界