css的复合选择器

html-css011

css的复合选择器,第1张

在CSS中,可以根据选择器的类型把选择器分为基础选择器和复合选择器,复合选择器是建立在基础选择器之上,对基本选择器进行组合形成的。

复合选择器可以更准确、更高效的选择目标元素(标签)。

复合选择器是由两个或多个基础选择器,通过不同的方式组合而成的。

常用的复合选择器包括:后代选择器、子选择器、并集选择器、伪类选择器等等。

后代选择器又称为包含选择器,可以选择父元素里面的子元素。其写法就是把外层标签写在前面,内层标签写在后面,中间用空格分隔。当标签发生嵌套时,内层标签就成为外层标签的后代。

语法:

元素1 元素2 {样式声明}

上述语法表示选择元素1里面的所有元素2(后代元素)。

例如:

元素1和元素2中间用空格隔开。

元素1是父级,元素2是子级,最终选择的是元素2。

元素2可以是儿子,也可以是孙子等,只要是元素1的后代即可。

元素1和元素2可以是任意基础选择器。

子元素选择器(子选择器)只能选择作为某元素的最近一级子元素。简单理解就是选亲儿子元素。

语法:

上述语法表示选择元素1里面的所有直接后代(子元素)元素2。

例如:

元素1和元素2中间用大于号(>)隔开。

元素1是父级,元素2是子级,最终选择的是元素2。

元素2必须是亲儿子,其孙子、重孙之类都不归他管。也可以叫他亲儿子选择器。

并集选择器、伪类选择器等等。

并集选择器可以同时选择多组标签,同时为他们定义相同的样式。通常用于集体声明。

并集选择器是各选择器通过英文逗号(,)连接而成,任何形式的选择器都可以作为并集选择器的一部分。

语法:

上述语法表示选择元素1和元素2。

元素1和元素2中间用逗号隔开。

逗号可以理解为和的意思。

并集选择器通常用于集体声明。

伪类选择器用于向某些选择器添加特殊的效果,比如给链接添加特殊效果,或选择第1个,第n个元素。

伪类选择器书写最大的特点是用冒号(:)表示,比如:hover、:first-child。

因为伪类选择器很多,比如有链接伪类、结构伪类等,所以看这里先给大家讲解常用的链接伪类选择器。

1.为了确保生效,请按照 LVHA 的循顺序声明::link-:visited-:hover-active。

2.因为a链接在浏览器中具有默认样式,所以我们实际工作中都需要给链接单独指定样式。

二链接伪类选择器实际开发中的写法:

:focus伪类选择器用于选取获得焦点的表单元素。

焦点就是光标,一般情况<input>类表单元素才能获取,因此这个选择器也主要针对于表单元素来说。

CSS Modules 不是官方规范或浏览器中的实现,而是构建步骤中的一个过程(在 Webpack 或 Browserify 的帮助下),它改变了类名和选择器的作用域(即有点像命名空间)。

目的: 解决 CSS 中全局作用域的问题

在 React 中默认开启了 CSS Module,样式表文件需要以 xxx.module.sass/less/css 命名

我们也可以通过配置 webpack 来开启 CSS Module

webpack.config.js

localIdentName 可以定义生产的哈希类名,默认是 [hash:base64]

详细配置见: css-loader

localIdentName 选项的占位符有:

默认 CSS 的规则是全局生效的,任何一个组件下的 CSS 样式,都会影响其他组件中使用相同类名的地方。

style.css

App.js

Header.css

Header.js

index.js

此时我们的页面上展示的就是绿色的 Header 组件 和 Hello World

因为定义了两个相同的 title class,虽然是在不同的组件中导入,但是他们的类名是一样的,最终都会在全局作用域下生效,因为这两个组件都渲染在了页面上。

至于为什么会显示成绿色,因为 Header 组件是后导入的,所以 Header 的 title 样式就覆盖了 App 的 title 样式,这就是 CSS 层叠样式的概念了,此处不再赘述。(如果导入顺序换一下,那么就是红色了)

答案: 产生局部作用域的唯一方法,就是使用一个独一无二的 class 的名字,不会与其他选择器重名。这就是 CSS Modules 的做法。

这里就拿 React 项目来进行解释

在 React 中,默认是开启 CSS Module 的。但是对于样式表文件的命名一个约束。需要以 .module.less/css/sass 结尾

随意我们就可以这样改造一下 Header 组件,来使用 CSS Module 的功能。

效果: Header 组件 展示为绿色; Hello World 展示为红色。可以看到 Header 中相同类名的样式并没有影响到我们的 App 组件

此时在控制台中查看 HTML,发现我们 Header 组件中的 h2 标签上的 class 类名变成了 <h2class="_src_Header_module__title">Header 组件</h2>

同理在样式表文件中也变成了

App 组件

随机的 className 是可以配置的:通过 webpack.config.js 中配置 css-loader 的 localIdentName 选项来定义生成的随机类名

通常在我们的日常开发中有这种场景:

我们有一个自己的组件,但是这个组件使用了一些第三方的组件库,对于我们使用的第三方组件我们又想修改一下它的样式。

如果此时,我们直接在当前组件的样式文件中,通过定义一个和第三方组件相同类名的类(比如说 antd button 的 antdr-btn 类),然后写自己的样式:

Button.module.css

然后我在组件中导入

Button.js

此时我们会发现我们的修改并没有生效,为什么呢?原因就是最后我们导入的类名会被 css-loader 处理成一个随机的值,所以导致不再是 antdr-btn 。

那么我们如何实现在自定义组件中修改第三方组件的样式呢?

需要不对第三方组件的类名进行哈希,保留原始类名,才能起到样式覆盖的作用 :global

:global(.className)那么此时这个 className 即使是在组件的样式表中定义的也不会被添加 hash 值,所以就可以影响全局所有类名为 className 的样式

注意:

此时组件中对该类的样式修改会影响全局所有使用该类名的地方,所以为了将样式修改限制到本组件,一般推荐将:global 使用在组件自定义类名范围下,然后添加这个自定义类名到组件中

CSS Modules 还提供一种显式的局部作用域语法:local(.className),等同于.className(直接在样式文件中写.className)该类名在编译后会被添加 hash 值

在 CSS Modules 中,一个选择器可以继承另一个选择器的规则,这称为"组合"。

在 Header.module.css 中,让.title 继承.back 。

Header.module.css

Header.js

编译后

CSS

HTML

选择器也可以继承其他 CSS 文件里面的规则。

other.module.css

Header.module.css

注意:

导入的类名需要和被导入文件中的类名相同

编译之后的效果和 composes 同一个文件中的 class 效果相同

CSS中的行为——expression;

下面是定义container容器的宽度,如果<725就为自己的宽度,否则就等于725,相当于max-width:725px。

<style type="text/css" media="screen">

#container { width: expression((documentElement.clientWidth <725) ? "725px" : "auto" )}

</style>