<p><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174010351218537.jpg" class="lazy" alt="The PostCSS Guide to Improving Selectors and Media Queries "></p>
<p><strong>核心要点</strong></p>
<ul>
<li>PostCSS 提供各种插件,为最新的 CSS 功能提供 polyfill,允许开发者尝试新功能,即使它们缺乏广泛的浏览器支持。</li>
<li>
<code>postcss-nesting</code> 插件根据 W3C 嵌套模块提案实现样式规则嵌套,引入新的 <code>&amp;amp;</code> 嵌套选择器,引用父选择器。</li>
<li>
<code>postcss-custom-selectors</code> 插件允许在变量中定义重复选择器,减少代码重复并改进代码维护。</li>
<li>
<code>postcss-custom-media</code> 和 <code>postcss-media-minmax</code> 插件改进了媒体查询,使其更易于使用并减少样式表中的重复。</li>
</ul>
<p>CSS 规范的最新变化引入了一些有趣的功能。不幸的是,其中一些功能仍处于草案阶段,而其他功能则缺乏广泛的浏览器支持。通常情况下,新的建议需要一段时间才能被浏览器审查、接受和实现。但是,我们可以节省等待时间,并使用 PostCSS 尝试其中一些功能。</p>
<p>PostCSS 有各种插件旨在为最新的 CSS 功能实现 polyfill。由于这些插件的范围很广,在一篇文章中涵盖所有插件是困难的。相反,我们将关注那些专注于为选择器和媒体查询添加新功能的插件。许多插件将允许我们显著改进样式表的结构,而其他插件可能只是在顶部添加一些简洁的语法糖。</p>
<p>本文不会详细介绍 PostCSS 的配置和安装。这已在“PostCSS 入门”和“使用 PostCSS 提升 CSS 质量”中介绍过。作为快速参考,您也可以查看 GitHub 上的 PostCSS 页面。</p>
<h2>规则嵌套</h2>
<p>让我们从最基本的功能开始——对每个预处理器用户来说肯定都很熟悉——嵌套。<code>postcss-nesting</code> 插件根据 W3C 嵌套模块提案实现样式规则嵌套。</p>
<p>该提案引入了一个新的 <code>&amp;amp;</code> 嵌套选择器,它引用父选择器。与 Less 或 Sass 相反,根据规范,此选择器是必需的,并且必须是选择器链中的第一个基本选择器才能启用嵌套。任何不包含嵌套选择器的选择器都将被忽略。例如:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
&amp;amp;amp;.popular {
background: #DDD;
}
&amp;amp;amp; .title {
font-weight: bold;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>将被转换为:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>请注意,以下代码无效,因为它没有按照规定使用 <code>&amp;amp;</code> 选择器。</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
/* no nested-selector */
.popular {
background: #DDD;
}
/* the nested selector is not the fist selector in the chain */
.latest &amp;amp;amp;amp; {
border: 1px solid red;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>为了允许将父选择器插入选择器中的任何位置(而不仅仅是开头),该提案定义了使用嵌套 at-rule <code>@nest</code> 的替代语法。我们可以通过以下方式修复上一个示例中的 <code>.latest &amp;amp;amp;</code> 选择器:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
@nest .latest &amp;amp;amp;amp; {
border: 1px solid red;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>这将编译成:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333
}
.latest .article {
border: 1px solid red
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p><code>@nest</code> 语法也比 <code>&amp;amp;</code> 更具表现力。</p>
<h2>自定义选择器</h2>
<p>编写 CSS 时,我们倾向于编写许多重复的选择器。这可能是选择所有链接或任何按钮的简单样板代码,或者需要反复重复的更复杂的选择器。这可能会引入许多代码重复以及所有相关的代码维护问题。新的 CSS 扩展规范引入了一种将选择器存储在变量中并从样式表的其他部分引用它们的方法。因此,重复的选择器只需定义一次,然后就可以安全地在其他地方重复使用。</p>
<p>PostCSS 有一个 <code>postcss-custom-selectors</code> 插件实现了此功能。这是一个定义所有标题元素选择器的简单示例:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
&amp;amp;amp;.popular {
background: #DDD;
}
&amp;amp;amp; .title {
font-weight: bold;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>它将编译成:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>自定义选择器作为伪类实现,因此语法看起来很奇怪 <code>:--</code>。</p>
<p>自定义选择器可以有效地与基本选择器一起使用。例如:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
/* no nested-selector */
.popular {
background: #DDD;
}
/* the nested selector is not the fist selector in the chain */
.latest &amp;amp;amp;amp; {
border: 1px solid red;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>编译成:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
@nest .latest &amp;amp;amp;amp; {
border: 1px solid red;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>您甚至可以将多个自定义选择器组合到单个选择器中以实现更复杂的排列。</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333
}
.latest .article {
border: 1px solid red
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>将产生:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;@custom-selector :--heading h1, h2, h3, h4, h5, h6;
:--heading {
font-weight: bold;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>此示例可能略微夸张,但它很好地演示了此功能的强大功能。</p>
<h2>新的伪类</h2>
<p>选择器级别 4 规范引入了一堆新的伪类,但由于大多数伪类的动态特性,只有几个可作为 PostCSS 插件使用。</p>
<h3>
<code>:matches()</code> 伪类</h3>
<p><code>postcss-selector-matches</code> 插件实现了新的 <code>:matches()</code> 伪类。它是一个函数类,仅筛选与参数中选择器匹配的元素。如果您传递多个选择器,则元素必须至少匹配其中一个。简而言之:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: bold;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>编译成:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article :--heading .author {
color: blue;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<h3>
<code>:not()</code> 伪类</h3>
<p><code>:not()</code> 伪类筛选不匹配任何给定参数的元素。它在 <code>postcss-selector-not</code> 插件中实现。</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article h1 .author,
.article h2 .author,
.article h3 .author,
.article h4 .author,
.article h5 .author,
.article h6 .author {
color: blue;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>结果是:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;@custom-selector :--links a, a:focus, a:visited, a:hover, a:active;
article :--heading :--links {
color: #333;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<h3>
<code>:any-link</code> 伪类</h3>
<p><code>postcss-pseudo-class-any-link</code> 插件实现了 <code>:any-link</code> 伪类。引入它是为了帮助解决围绕 <code>:link</code> 伪类的混淆。与后者不同,它匹配所有链接——包括已访问的链接。</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;article h1 a,
article h2 a,
article h3 a,
article h4 a,
article h5 a,
article h6 a,
article h1 a:focus,
article h2 a:focus,
article h3 a:focus,
article h4 a:focus,
article h5 a:focus,
article h6 a:focus,
article h1 a:visited,
article h2 a:visited,
article h3 a:visited,
article h4 a:visited,
article h5 a:visited,
article h6 a:visited,
article h1 a:hover,
article h2 a:hover,
article h3 a:hover,
article h4 a:hover,
article h5 a:hover,
article h6 a:hover,
article h1 a:active,
article h2 a:active,
article h3 a:active,
article h4 a:active,
article h5 a:active,
article h6 a:active {
color: #333;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>编译成:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;button:matches(:hover, :focus) {
color: red;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<h2>媒体查询改进</h2>
<p>PostCSS 的库中有一些插件旨在使媒体查询更易于使用。它们是 <code>postcss-custom-media</code> 和 <code>postcss-media-minmax</code>。</p>
<h3>自定义媒体</h3>
<p>编写媒体查询会产生与常规选择器相同的问题——它们在样式表中经常重复。可能比普通选择器更频繁。幸运的是,有一个类似于自定义选择器的解决方案。<code>postcss-custom-media</code> 插件实现了自定义媒体查询规范,该规范增加了将媒体查询保存到变量中的能力。</p>
<p>语法与自定义选择器非常相似。这是一个简单的例子:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;button:hover, button:focus {
color: red;
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>编译成:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
&amp;amp;amp;.popular {
background: #DDD;
}
&amp;amp;amp; .title {
font-weight: bold;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>当然,您可以一次使用多个自定义媒体查询:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>将产生:</p>
<pre class="brush:php;toolbar:false">&amp;amp;lt;code class=&amp;amp;quot;language-css&amp;amp;quot;&amp;amp;gt;.article {
color: #333;
/* no nested-selector */
.popular {
background: #DDD;
}
/* the nested selector is not the fist selector in the chain */
.latest &amp;amp;amp;amp; {
border: 1px solid red;
}
}&amp;amp;lt;/code&amp;amp;gt;</pre>
<p>如您所见,现在更改“中等视口”的定义以及查找任何相关的 CSS 代码都容易得多。</p>
<h3>最小值和最大值语法</h3>
<p>尽管媒体查询是一件很棒的事情,但最小值和最大值语法受到了社区的很多批评。W3C 通过使用比较运算符引入更直观的语法来回应。<code>postcss-media-minmax</code> 插件增加了对 <code>></code>, <code>>=</code>, <code><</code>, <code><=</code> 的支持。</p>
<p>(文章剩余部分由于篇幅过长,已省略,但图片链接保持不变)</p>
以上是PostCSS改进选择器和媒体查询指南的详细内容。更多信息请关注PHP中文网其他相关文章!