幽灵空白节点
css世界原话:
“幽灵空白节点”是内联盒模型中非常重要的一个概念,具体指的是:在 HTML5 文档声明 中,内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个“空白节点”一样。这 个“空白节点”永远透明,不占据任何宽度,看不见也无法通过脚本获取,就好像幽灵一样, 但又确确实实地存在,表现如同文本节点一样。
<!--注意,这里有一个前提,文档声明必须是 HTML5 文档声明-->
<!doctype html>
<html><head></head><body><div><span></span></div></body><style>div {background-color: #cd0000;}span {display: inline-block;}</style>
</html>
复制代码
实际效果图如下:
然而当我们给div加一下font-size:0的时候,得到解决,效果如下:
再举个栗子:
<div><span></span></div>
<style>div {border: 2px dashed #cd0000;}span {padding: 50%;background-color: gray;}
</style>
复制代码
效果图:
font-size: 0
后:所以很多宽高与预期不符的时候,可以考虑一下是不是幽灵节点的问题,设置font-size: 0
试试。
超越最大原则
!important可以被“覆盖”,min-width/max-width、min-height/max-height属性与width/height属性有自己的原则:
<!--宽度最后为200px-->
<img src='helloWorld.jpg' style='width: 300px!important;'>
<style>
img { max-width: 200px; }
</style>
复制代码
<!--宽度最后为400px-->
<img src='helloWorld.jpg' style='width: 300px!important;'>
<style>
img {max-width: 200px;min-width: 400px;
}
</style>
复制代码
content用法
content的值可以为空字符串,也就是
content: ''
,没有必要在里面加个点;content不仅仅可以在before和after等伪元素里面使用,可以在普通标签里面用来加载图片,比如
<img> <style> img { content: url(helloWorld.jpg); }</style>
与<img src='helloWorld.jpg'>
视觉效果等效。但使用content生产的的图片无法控制,不能控制大小等;使用content生成的内容与元素,不能被选中和复制,无法被屏幕阅读的设备读取,也无法被搜索引擎抓取,所以重要的文本不要使用;
content支持Unicode,部分地方很好用,不如不用使用过多的
标签,而是加一个以下的代码用于换行;:after{content: '\A';white-space: pre; } 复制代码
顺便分享一个只用css生成...的有趣例子:链接
content还有以一个有趣的玩法就是计数器,简单的说就是用
counter-reset
注册一下,counter-increment
添加计数,counter()
显示计数,下面是一个简单的例子,但运用场景很多<div class="main"><div>第一条</div><div>第二条</div><div>第三条</div><div>第四条</div> </div> <style>.main {counter-reset: kakaka;}.main > div::before {content: counter(kakaka)'.';counter-increment: kakaka 1;} </style> 复制代码
效果图:
行内标签的padding
行内元素的padding上下不会改变文档流,但是会产生遮盖,且不能使用z-index调整
<span class="li">第一条</span>
<span class="li">第二条</span>
<br/>
<span class="li">第三条</span>
<span class="li">第四条</span>
<style>span {padding: 10px;}span:nth-child(1) {background-color: red;}span:nth-child(2) {background-color: yellowgreen;z-index:1;/* 无效 */}span:nth-child(4) {background-color: rebeccapurple;}span:nth-child(5) {background-color: brown;}
</style>
复制代码
效果图:
关于margin合并特性
margin在合并会出现在块级元素(不包含浮动和绝对定位的),且在垂直方向(不使用writing-mode改变文档流方向)的时候。
兄弟元素上下合并
<p>第一条</p> <p>第二条</p> <p>第三条</p> <p>第四条</p> <style>p {margin: 20px;} </style> 复制代码
父子元素合并
<div><p>第一条</p><p>第二条</p><p>第三条</p><p>第四条</p> </div> <div>我是底部</div> <style>div {margin-bottom: 10px;}p {margin: 20px;} </style> 复制代码
空元素合并
<p>第一条</p> <div></div> <p>第二条</p> <p>第三条</p> <p>第四条</p> <style>div {margin: 30px;}p {margin: 20px;} </style> 复制代码
规则总结起来:正正取大值、正负值相加、负负最负值
一旦了解到了这些margin合并的特性,就不用单独margin-top: 20px;
等麻烦的操作。
关于line-height
- 容器的大小实际不是font-size撑开的,而是line-height决定的;
- 文字的行距 =
line-height
-font-size
; - 可是设置
line-height: 1.5
不一定要用px等单位,此时line-height为font-size的1.5倍; - 文字近似垂直居中,其实是可以通过line-height设置高度控制的,不用设置height,如果存在height的话,请设置相等。之所以说是文字垂直居中为近似,因为对于盒模型来说,垂直方向会偏下,原因在于css的行距上下等分机制,一般会偏差1~2px。
absolute的单独使用
在我最早使用absolute的时候,总之直接把relative作为父元素结合起来用,其实这是认知上面的问题。
absolute 是非常独立的 CSS 属性值,其样式和行为表现不依赖其他 任何 CSS 属性就可以完成 ——《css世界》
absolute具有相对特性的无依赖绝对定位,这样说可能会有些不好理解。
当给元素添加absolute时,如果元素没有定义盒模型,会以inline-block来计算展示。但是区别与直接添加inline-block的是,absolute不改变正常流的尺寸空间。也就是说,无论我们怎么修改absolute定位的元素的宽高,都不会影响到正常流布局。
下图来自《css世界》论坛
不使用relative作为父元素,单一使用absolute有很多使用的空间与场景:
在元素拥有absolute属性,且不受父级overflow剪切影响(但父级也是定位元素时会影响)。
利用absolute的流体特性实现垂直水平居中
<div class="element"></div> <style> .element {width: 300px; height: 200px;position: absolute;left: 0; right: 0; top: 0; bottom: 0; /* 建立流体特性 */margin: auto; /*自动分配空间*/background-color: red; } </style> 复制代码
效果图如下:
relative的单独使用
relative不仅仅可以牵制absolute的定位,本身具有很有趣的适应场景。
“无侵入”式定位,换句话说就是不影响到其他元素的定位,根据自身原本位置定位。
<div class="element"></div>
<style>
.element {width: 300px; height: 200px;position: relative;left: 100px; top: 200px;right: 10px; bottom: 10px; /* 无效,当left/right、top/bottom同时存在时,取left和top*/ background-color: red;
}
</style>
复制代码
效果图如下:
可以适应很多场景,比如在不影响到原来文档流调整某个元素位置。
下图来自《css世界》:
不过建议少使用relative,因为正是“无侵入”导致了出现了叠层,需要z-index才能解决。
z-index“不犯二”准则
《css世界》提出的:
对于非浮层元素,避免设置 z-index 值,z-index 值没有任何道理需要超过 2。由于 z-index 不能超过 2,因此,我称其为“不犯二”准则。
这是一条经验准则,可以有效降低日后遇到 z-index 样式问题的风险。
先讲一下为什么需要这个准则。
(1)定位元素一旦设置了 z-index 值,就从普通定位元素变成了层叠上下文元素,相互 间的层叠顺序就发生了根本的变化,很容易出现设置了巨大的 z-index 值也无法覆盖其他元 素的问题。
(2)避免 z-index“一山比一山高”的样式混乱问题。此问题多发生在多人协作以及后期 维护的时候。例如,A 小图标定位,习惯性写了个 z-index:9;B 一看,自己原来的实现被覆 盖了,立马写了个 z-index:99;结果比弹框组件层级还高,那还得了,立马弹框组件来一个 z-index:999999;谁知后来,弹框中又要有出错提示效果……显然,最后项目的 z-index 层级管理就是一团糟。
我觉得很有道理,如果真的出现超过的情况应该首先审视一下自己的布局。
outline和box-shadow的使用
outline不占用空间,这一点和border不同,border占据空间会影响到宽高,而outline不会影响到正常流。
<div></div>
<style>div {position: absolute;left: 0;right: 0;top: 0;bottom: 0;margin: auto;width: 100px;height: 100px;background-color: black;border: 20px solid red;outline: 30px solid rebeccapurple;}
</style>
复制代码
这样的话我们完全就可以直接利用这种方式做遮罩层了,一个标签搞定。
<div>遮罩层</div>
<style>div {position: absolute;left: 0;right: 0;top: 0;bottom: 0;margin: auto;width: 100px;height: 100px;background-color: white;outline: 9999px solid #0000005e;/*线宽设置足够大,颜色为透明色*/}
</style>
复制代码
但是以上还有一个很大的问题,如果遮罩层为四角为圆弧呢?
<div>遮罩层</div>
<style>div {position: absolute;left: 0;right: 0;top: 0;bottom: 0;margin: auto;width: 100px;height: 100px;background-color: white;outline: 9999px solid #0000005e;border-radius: 20px;border: 1px solid red;/*为了区分效果*/}
</style>
复制代码
很明显,遮罩层就出问题了,因为outline在大部分浏览器上不支持弧度设置,目前火狐支持使用-moz-outline-radius
设置。 此时,我们可以使用box-shadow来实现,单个标签遮罩层:
<div>遮罩层</div>
<style>div {position: absolute;left: 0;right: 0;top: 0;bottom: 0;margin: auto;width: 100px;height: 100px;background-color: white;box-shadow: 0 0 0 9999px #0000005e;border-radius: 20px;}
</style>
复制代码
这样就不存在因为弧度产生的问题,box-shadow与outline同样不会影响到正常流。
同时设置可以显示双边框效果,注意outline和box-shadow同时设置会互相重叠,且outline总是在box-shadow之上,但利用这些特性,可以实现如下效果,单标签内弧外方
<div></div>
<style>div {position: absolute;left: 0;right: 0;top: 0;bottom: 0;margin: auto;width: 100px;height: 100px;background-color: yellowgreen;border-radius: 20px;outline: 10px solid brown;box-shadow: 0 0 0 10px brown;}
</style>
复制代码
outline还有其他用法,比如使用outline-offset
偏移就可以显示出这样的桌布效果
利用:first-child、:nth-child做判断
:first-child与:nth-last-child()等选择器,不仅仅可以单一使用,可以同时使用进行判断,已获取更好的效果,例子如下:
当元素块超过4个的时候,变更全部颜色。
```html
<div class="main"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div>
</div>
<style>.main {display: flex;flex-wrap: wrap;}.main > div {width: 50px;line-height: 50px;text-align: center;background-color: gray;border-radius: 5px;margin: 10px;}.main > div:first-child:nth-last-child(n+4),.main > div:first-child:nth-last-child(n+4) ~ div {background-color: palevioletred;}
</style>
```
复制代码
转载于:https://juejin.im/post/5ca41baf51882543d6528a8d