幽灵空白节点

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用法

  1. content的值可以为空字符串,也就是content: '',没有必要在里面加个点;

  2. content不仅仅可以在before和after等伪元素里面使用,可以在普通标签里面用来加载图片,比如<img> <style> img { content: url(helloWorld.jpg); }</style><img src='helloWorld.jpg'>视觉效果等效。但使用content生产的的图片无法控制,不能控制大小等;

  3. 使用content生成的内容与元素,不能被选中和复制,无法被屏幕阅读的设备读取,也无法被搜索引擎抓取,所以重要的文本不要使用;

  4. content支持Unicode,部分地方很好用,不如不用使用过多的
    标签,而是加一个以下的代码用于换行;

    :after{content: '\A';white-space: pre;
    }
    复制代码

    顺便分享一个只用css生成...的有趣例子:链接

  5. 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改变文档流方向)的时候。

  1. 兄弟元素上下合并

    <p>第一条</p>
    <p>第二条</p>
    <p>第三条</p>
    <p>第四条</p>
    <style>p {margin: 20px;}
    </style>
    复制代码

  2. 父子元素合并

    <div><p>第一条</p><p>第二条</p><p>第三条</p><p>第四条</p>
    </div>
    <div>我是底部</div>
    <style>div {margin-bottom: 10px;}p {margin: 20px;}
    </style>
    复制代码

  3. 空元素合并

    <p>第一条</p>
    <div></div>
    <p>第二条</p>
    <p>第三条</p>
    <p>第四条</p>
    <style>div {margin: 30px;}p {margin: 20px;}
    </style>
    复制代码

规则总结起来:正正取大值正负值相加负负最负值

一旦了解到了这些margin合并的特性,就不用单独margin-top: 20px;等麻烦的操作。


关于line-height

  1. 容器的大小实际不是font-size撑开的,而是line-height决定的;
  2. 文字的行距 = line-height - font-size;
  3. 可是设置line-height: 1.5不一定要用px等单位,此时line-height为font-size的1.5倍;
  4. 文字近似垂直居中,其实是可以通过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有很多使用的空间与场景:

  1. 在元素拥有absolute属性,且不受父级overflow剪切影响(但父级也是定位元素时会影响)。

  2. 利用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

返回
顶部