CSS选择器和样式隔离
CSS选择器
一、基本选择器
1.通用选择器:*
选择所有元素。(可选)可以将其限制为特定的名称空间或所有名称空间。
例子:*
将匹配文档的所有元素。
2.标签选择器:标签名称
按照给定的节点名称,选择所有匹配的元素。
例子:<input>
匹配任何<input>
元素。
3.类选择器:.类名
按照给定的 class 属性的值,选择所有匹配的元素。
例子:.index
匹配任何 class 属性中含有 “index” 类的元素。
4.ID选择器:#id名
按照 id 属性选择一个与之匹配的元素。需要注意的是,一个文档中,每个 ID 属性都应当是唯一的。
例子:#toc
匹配 ID 为 “toc” 的元素。
5.属性选择器:
按照给定的属性,选择所有匹配的元素。
例子:p[class="test"]
选择类名为test的p元素
二、分组选择器
1.并集选择器:,
将不同的选择器组合在一起的方法,它选择所有能被列表中的任意一个选择器选中的节点。
示例:div, span
会同时匹配span元素和div元素。
2.后代选择器:空格
选择前一个元素的所有后代节点。
例子:div span
匹配所有位于任意div元素之内的span元素。
3.直接后代选择器:>
选择前一个元素的所有直接子代的节点。
例子:ul > li
匹配直接嵌套在ul元素内的所有li元素。
4.兄弟选择器:~
同一父节点的前一个元素后的所有后一个元素
例子:p ~ span
匹配同一父元素下,p元素后的所有span元素。
5.紧邻兄弟选择器:+
后一个元素紧跟在前一个之后,并且共享同一个父节点。
例子:h2 + p
会匹配紧邻在h2元素后的第一个p元素。
三、伪选择器
1.伪类选择器::
支持按照未被包含在文档树中的状态信息来选择元素。
动态伪类:
-
a:link
超链接未被访问的状态。 a:visited
超链接访问过的状态。a:hover
鼠标悬停在元素上的状态。-
a:active
元素激活的状态。 input:focus
获取焦点的元素。
结构伪类:
:first-child
所有兄弟元素中的第一个。:last-child
所有兄弟元素中的最后一个。:nth-child(n)
所有兄弟元素中的第 n 个。:first-of-type
所有同类型兄弟元素中的第一个。:last-of-type
所有同类型兄弟元素中的最后一个。:nth-of-type(n)
所有同类型兄弟元素中的 第n个 。
2.伪元素选择器:::
用于表示无法用 HTML 语义表达的实体。
例子:p::first-line
匹配所有p元素的第一行。
样式隔离方案
一、BEM
以 .block__element--modifier
或者说block-name__element-name--modifier-name
形式命名,命名有含义,也就是模块名 + 元素名 + 修饰器名
如.dropdown-menu__item--active
优点:
- 人为严格遵守BEM规范,可以解决无作用域样式污染问题
- 可读性好,一目了然是那个dom节点,对于无用css删除,删除了相应dom节点后,对应的css也能比较放心的删除,不会影响到其他元素样式
缺点:
- 命名太长(个人开发习惯、部分人会觉得,我认为命名长提高了可读性,能解决一些问题,也不叫缺点),至于体积增大,gzip可忽略
二、CSS module (目前使用)
依赖webpack css-loader,配置如下,现在webpack已经默认开启CSS modules功能了
{
test: /.css$/,
loader: "style-loader!css-loader?modules" //简写方式
}
//todo:详细配置讲解
我们先看一个示例:
将CSS
文件style.css
引入为style
对象后,通过style.title
的方式使用title
类:
import style from './style.css';
export default () => {
return (
<p className={style.title}>
I am KaSong.
</p>
);
};
对应style.css
:
.title {
color: red;
}
打包工具会将style.title
编译为带哈希的字符串
<h1 class="_3zyde4l1yATCOkgn-DBWEL">
Hello World
</h1>
同时style.cs
s也会编译:
._3zyde4l1yATCOkgn-DBWEL {
color: red;
}
这样,就产生了独一无二的class,解决了CSS模块化的问题
使用了 CSS Modules 后,就相当于给每个 class 名外加加了一个:local
,以此来实现样式的局部化,如果你想切换到全局模式,使用对应的 :global
。
:local
与 :global
的区别是 CSS Modules
只会对 :local
块的 class 样式做 localIdentName
规则处理,:global
的样式编译后不变
.title {
color: red;
}
:global(.title) {
color: green;
}
可以看到,依旧使用CSS,但使用JS来管理样式依赖,最大化地结合现有CSS
生态和 JS
模块化能力,发布时依旧编译出单独的 JS
和 CSS
三、CSS in JS (以前使用)
核心思想是把CSS直接写到各自组件中,也就是说用JS去写CSS,直接使用行内样式,而不是单独的样式文件里,例如:
<h1 style="color:red;font-size:46px;" onclick="alert('Hi')">
Hello World
</h1>
上面的例子使用 React 改写如下
const style = {
'color': 'red',
'fontSize': '46px'
};
const clickHandler = () => alert('hi');
ReactDOM.render(
<h1 style={style} onclick={clickHandler}>
Hello, world!
</h1>,
document.getElementById('example')
);