你有了解过原生css的scope?
最近再看公司项目源码中发现:scope
被用来选择元素很常见,于是就去了解了一下关于原生css的作用于问题。mdn介绍
从mdn中我们可以了解到:scope
可以在css和js中进行使用,下面我们来介绍一下他的详细用法。
:scope
直接在style
标签中使用
:scope直接在style标签中使用他将作用于html元素。不管style标签在哪里编写。
<div class="div1">
<style>
:scope {
border: 1px solid green;
}
</style>
div1
<div>
<span>内部</span>
</div>
<span>直接</span>
</div>
<div class="div2">
div2
</div>
:scope
配合@scope, scoped
使用
按道理讲scoped
等价于@scope不加任何修饰
,都表示作用于当前style标签的父元素之内的元素。并且可以使用:scope
伪类选择父元素。但是现在浏览器不支持style
标签中的scoped
属性了,所以即使在style
中写了scoped
也是作用于全局。
@scope
完整语法@scope (scope root) to (scope limit)
作用范围不包含limit内的元素。
当我们不指定root, limit
时,他将作用于style
标签的直接父元素。并且我们使用:scope
伪类就可以选择当前@scope
作用的根节点。在@scope
中编写的css只会作用于当前:scope
匹配的根节点内。
<div class="div1">
<style>
/* 如果不设置作用范围,那么它将以style标签的父元素作为作用域 */
@scope {
/* 选中根,给根设置样式 */
:scope {
border: 1px solid green;
}
/* 作用于根内部 */
span {
background: red;
}
}
</style>
div1
<div>
<span>内部</span>
</div>
<span>直接</span>
</div>
<div class="div2">
div2
</div>
其实上面的内容等价于这个,但是由于scoped
不被支持了,所以就不生效了对于现代浏览器来说。
<style scoped>
/* 作用域当前父元素。但是浏览器不支持了。所以也是作用于全局 */
:scope {
background: red;
}
/* 作用于根内部 */
span {
background: red;
}
</style>
如果将上面的style
标签中的内容放在head内部,将不会起任何作用。因为当前head中没有被匹配到对应的选择器。除非设置root, limit
内容。
下面我们来看看@scope
中设置root, limit
的效果。只要加上@scope
语法的范围,style不管在哪编写,其中的css都会作用于当前范围内的元素。
<div>
<p>
p标签
<b>
<style>
@scope (div) to (b) {
:scope {
background: red;
}
span, p {
color: yellow;
}
/* 这个b设置无效,因为 @scope 范围不包括 b */
b {
color: blue;
}
}
</style>
span标签
</b>
</p>
</div>
<div class="div1">
div1
<div>
<span>内部</span>
</div>
<span>直接</span>
</div>
<div class="div2">
div2
</div>
我们还可以使用&
代替:scope
,:scope
表示匹配的范围根,而&
表示用于匹配范围根的选择器。因此,可以&
多次链接。但是,您只能使用:scope
一次。
<div>
<p>
p标签
<b>
<style>
@scope (div) to (b) {
/* 但是:scope :scope是不被允许的 */
& & {
background: red;
}
span, p {
color: yellow;
}
b {
color: blue;
}
}
</style>
span标签
</b>
</p>
</div>
<div class="div1">
div1
<div>
<span>内部</span>
</div>
<span>直接</span>
</div>
<div class="div2">
div2
</div>
:scope
在js中使用
当在 DOM API 调用(例如 querySelector()、querySelectorAll()、matches() 或 Element.closest())中使用时,:scope 匹配调用此类方法的元素。所以我们就很容易的选中当前元素的直接子元素。
const div1 = document.querySelector(".div1")
const span = div1.querySelectorAll(":scope > span") // [span]
const _div1 = div1.querySelector(":scope") // null
// 虽然_div1为null,但是 div1.querySelectorAll(":scope > span")就是可以选择内容的
const spanAll = div1.querySelectorAll(":scope span") // [span, span]
const _document = document.querySelectorAll(":scope") // [html]
const spanEmpty = document.querySelectorAll(":scope > span") // []
console.log(_div1, span, spanAll, _document, spanEmpty)
参考文章
往期年度总结
往期文章
专栏文章
结语
本篇文章到此就结束了,欢迎在评论区交流。
🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论, 支持一下博主~