empty html怎么创建,CSS伪选择器::empty vs :blank

前段时间@Zell Liew的博客深入的介绍了CSS中伪选择器:empty和:blank相关的知识。那么:empty和:blank究竟有什么作用,又在什么场景下使用呢?今天我们来一起看看,它们怎么使用,更应该应用在哪个场景之下呢?

使用场景

我们平时做项目的时候,时常会使用一些CSS Frameworks,比如说有名的Bootstrap,在这种情况之下,使用的一些选择器,是带有一些默认样式。有的时候元素中并没有任何内容,那么在页面上显示的效果就有点怪异。比如下面这样的一个场景,你的页面上有两个.alert的div应用,其中一个有内容,另外一个任何内容都没有(就一个空div)。比如:

Success Alert

如果你的页面中引用了bootstrap.css的话,这个时候看到的效果将会是这样:

css-empty-and-blank-.png

对于这样的效果,估计没有人能接受。那么为什么会这样呢?来看一下代码,不难发现.alert有一个默认的样式:

.alert {

position: relative;

padding: .75rem 1.25rem;

margin-bottom: 1rem;

border: 1px solid transparent;

border-radius: .25rem;

}

元素中主要有一个padding,撑大了元素容器,就算元素没有任何内容,该元素也有一定的大小。就如上面看到的效果。那么我们有没有别的方法能处理呢?毕竟很多场景我们是不好控制元素的。

既然标题提到了:empty和:blank,估计有同学想到了解决方案是不是和这两个伪元素有关呢?如果感兴趣的话,可以接着往下阅读,在介绍相应的解决方案之前,咱们先来了解一下:empty和:blank。

:empty 和 :blank

首先,:empty是什么?:blank`又是什么?

简单的说,** :empty 和 :blank 都是CSS的伪选择器。其中:empty可以让你选择 空元素 。空元素是指没有任何内容的元素,甚至空格都不行。即:

空元素可以有注释,只要注释填满了整个元素:

最上面的一行代码,虽然div中有注释,但

之间没有任何内容,甚至是空格都没,那么他就是一个空元素,但下面三个div,虽然包含的也是注释,但是里面含有空格。所以说,这三个div不是空元素。

:blank较:empty为灵活。它可以让你选择有空白的元素:

没有子节点

仅有空的文本节点

仅有空白符的文本节点

比如:

不过从字面上来理解,他们都指的是 空。在实际的运用之中,不管是:empty和:blank都是有用的,比如说:

给空元素添加样式

创建空的状态

空元素的样式

比如我们一个操作,只有接口正常的时候才有数据输出,当接口失败的时候,没有数据输出。另外拿大家最为熟悉的一个示例来举例: 表单控件:

当表单验证失败的时候,div.block-help才有数据输出。在这里,我们对.block-help有一个样式的设置,特别是,当这个.block-help带有物理尺寸相关的样式时,就会直接影响页面的效果,比如文章开头提到的那个示例。在没有:empty和:blank的时候,我们需要给这个div添加一个类名或通过HTML的属性来控制。比如:

.block-help {

padding: .5em;

display: none;

}

.block-help.success {

display: block

}

如果使用:empty就不需要添加额外的类名或HTML元素属性。甚至display属性都可以省了。比如,文章最开头的.alert示例:

.alert:empty {

padding: 0;

border: none;

}

3156d84b54e66299e79914c39f2dfc47.gif

再来看另一场景,稍微复杂一顶点,假设我们的项目中有这样的一个效果:

10a577a3dbe2858eeffd976e96393bd9.png

这个场景相对于文章开头的示例要复杂一些。

当div.lime有内容的时候,div.red距离div.blue更远(margin-top),而当div.red如果没有字段输出的时候,div.red距离div.blue更近。处理这样的两个场景,:empty能灵巧的多了。

/* 实现左图的效果 */

.blue{

width: 750px;

height: 50px;

border: 5px solid blue;

}

.lime {

width: 100px;

height: 50px;

border: 5px solid lime;

}

.red {

width: 750px;

height: 300px;

border: 5px solid red;

margin-top: 30px;

}

/* 实现右图的效果 */

.lime:empty {

display: none;

}

.lime:empty + .red {

margin-top: 10px;

}

是不是觉得轻松多了。

创建空状态

在@Zell Liew的文章中举了一个待办事项列表。当你的用户第一次看到待办事项列表时,他们可能会看到没有任何待办事项。当没有任何待办事项,显示另一个效果向你的用户展示。而这个没有任何待办事项的状态就是我们所说的空状态。

写这样的效果,其结构可以像下面这样:

  • Item 1
  • Item 2
  • Item 3

没有任何待办事项,对应的结构就变成这样了:

那么这个时候,我们也可以使用上例的方法来做相应的效果。使用:empty伪选择器和相邻的兄弟选择器E + F或后续的兄弟选择器E ~ F来对.empty-state做样式上的处理:

.empty-state {

display: none;

}

ul:empty + .empty-state {

display: block;

}

@Heydon的写的ToDoList组件就运用了这方面的技术。感兴趣的阅读@Heydon写的文章。

:empty足够了?

既然:empty这么优秀,是不是:empty就足够了呢?事实上并非如此。原因有二:

糟糕的开发者体验

需要借用JavaScript手动清理元素中的空白

第一条还无所谓,但第二条为什么呢?

不知道大家是否有注意到,很多时候我们使用JavaScript框架来控制数据输出时,有可能造成元素内容是空的,但有可能无法确定里面有没有包含空格。或者写HTML结构的时候,手抖了一下,元素中包含了空格符。面对这样的场景,:empty就歇菜了。

还是拿@Zell Liew文章的待办事项来举例。

示例的结构如下:

  • Item 1

为了让:empty可以正常工作,我们需要从ul中删除所有的li。实现这样的效果并不难,使用JavaScript的removeChild就可以达到我们所要的需求:

const ul = document.querySelector('ul')

const li = ul.children[0]

ul.removeChild(li)

removeChild是可以将元素删除,但它却会生成包含空格的HTML(即使它可能不会在浏览器的检查器中显示)。我们可以使用childNodes属性来检查文本节点是否存在。可以在浏览器模拟一下这样的场景:

61a250650c10bc9ef8728f3c10841bd3.gif

因此在ul.children.length === 0的时候,使用ul.innerHTML=''清理

  • 中的空格。整个代码如下所示:

const ul = document.querySelector('ul')

const li = ul.children[0]

ul.removeChild(li)

if (ul.children.length === 0) {

ul.innerHTML = ''

}

最终效果如下:

:blank来解围

就上面这个示例的场景而言,如果:blank得到浏览器支持的话,咱们就无需借助JavaScript来实现,完全可以使用:blank来完成:

ul + div {

display: none;

}

ul:blank + div {

display: block;

background: hsl(240, 50%, 80%);

padding: 0.5em 0.75em;

}

总结

:empty和:blank可以让你轻松地设计空元素样式并生成空状态。

:blank要比:empty更好,因为它为我们提供更有好的开发体验。只不过到写这篇文章为止,:blank还没有得到浏览器的支持。不过:empty已经足够好了。也足够我们使用了,只不过有的场景之下,我们要确保元素是真的空元素,不包括空格符哟。

文章中只是举了几个简单的示例,其实还有其他的使用场景,如果你有这方面的经验,欢迎在下面的评论中与我们一起共享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值