<p><img src="/static/imghw/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>Core points</strong></p>
<ul>
<li>PostCSS provides a variety of plugins that provide polyfills for the latest CSS features, allowing developers to try out new features even if they lack extensive browser support. </li>
<li>
<code>postcss-nesting</code> The plug-in implements style rules nesting according to the W3C nested module proposal, introducing a new <code>&amp;amp;</code> nested selector, referring to the parent selector. </li>
<li>
<code>postcss-custom-selectors</code> Plugin allows defining duplication selectors in variables, reducing code duplication and improving code maintenance. </li>
The <li>
<code>postcss-custom-media</code> and <code>postcss-media-minmax</code> plugins improve media queries to make them easier to use and reduce duplication in style sheets. </li>
</ul>
<p>The latest changes to the CSS specification introduce some interesting features. Unfortunately, some of these features are still in the draft stage, while others lack extensive browser support. Often, new suggestions take some time before they are reviewed, accepted and implemented by the browser. However, we can save waiting time and try some of these features using PostCSS. </p>
<p>PostCSS has various plug-ins designed to implement polyfills for the latest CSS features. Because these plugins are very wide, it is difficult to cover all plugins in one article. Instead, we will focus on plugins that focus on adding new features to selectors and media queries. Many plugins will allow us to significantly improve the structure of the stylesheet, while others may just add some clean syntactic sugar to the top. </p>
<p>This article will not introduce the configuration and installation of PostCSS in detail. This has been described in "Begin with PostCSS" and "Improving CSS Quality with PostCSS". As a quick reference, you can also check out the PostCSS page on GitHub. </p>
<h2>Rules nesting</h2>
<p>Let's start with the most basic functionality—certainly familiar to every preprocessor user—Nesting. <code>postcss-nesting</code> Plug-in implements style rules nesting according to W3C nested module proposals. </p>
<p>The proposal introduces a new <code>&amp;amp;</code> nested selector that references the parent selector. Contrary to Less or Sass, this selector is required by specification and must be the first basic selector in the selector chain to enable nesting. Any selector that does not contain nested selectors will be ignored. For example: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333;
&amp;amp;amp;.popular {
background: #DDD;
}
&amp;amp;amp; .title {
font-weight: bold;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p> will be converted to: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p> Please note that the following code is invalid because it does not use the <code>&amp;amp;</code> selector as specified. </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.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;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p> To allow the parent selector to be inserted anywhere in the selector (not just at the beginning), the proposal defines an alternative syntax to use nested at-rule <code>@nest</code> . We can fix the <code>.latest &amp;amp;amp;</code> selector in the previous example by: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333;
@nest .latest &amp;amp;amp;amp; {
border: 1px solid red;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p>This will compile to: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333
}
.latest .article {
border: 1px solid red
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p><code>@nest</code> The grammar is also more expressive than <code>&amp;amp;</code>. </p><h2>Custom selector</h2>
<p>When writing CSS, we tend to write many duplicate selectors. This could be a simple boilerplate code that selects all links or any buttons, or a more complex selector that requires repeated repetitions. This may introduce many code duplications and all related code maintenance issues. The new CSS extension specification introduces a way to store selectors in variables and reference them from other parts of the stylesheet. Therefore, a repeat selector needs to be defined only once and then it can be safely reused elsewhere. </p>
<p>PostCSS has a <code>postcss-custom-selectors</code> plugin that implements this feature. Here is a simple example that defines all title element selectors: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333;
&amp;amp;amp;.popular {
background: #DDD;
}
&amp;amp;amp; .title {
font-weight: bold;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p>It will compile to: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p>Custom selectors are implemented as pseudo-classes, so the syntax looks weird <code>:--</code>. </p>
<p>Custom selectors can be used effectively with basic selectors. For example: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.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;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p>Compiled to: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333;
@nest .latest &amp;amp;amp;amp; {
border: 1px solid red;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p>You can even combine multiple custom selectors into a single selector for more complex arrangements. </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333
}
.latest .article {
border: 1px solid red
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p> Will generate: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>@custom-selector :--heading h1, h2, h3, h4, h5, h6;
:--heading {
font-weight: bold;
}</pre><div class="contentsignin">Copy after login</div></div>
<p>This example may be a little overblown, but it demonstrates the power of this feature very well. </p>
<h2>New pseudo-class</h2>
The selector level 4 specification introduces a bunch of new pseudo-classes, but due to the dynamic nature of most pseudo-classes, only a few are available as PostCSS plug-ins. <p>
</p><h3> Pseudoclass<code>:matches()</code>
The </h3><p> plugin implements a new <code>postcss-selector-matches</code> pseudo-class. It is a function class that filters only elements that match the selector in the parameter. If you pass multiple selectors, the elements must match at least one of them. In short: <code>:matches()</code>
</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: bold;
}</pre><div class="contentsignin">Copy after login</div></div>Compiled to: <p>
</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article :--heading .author {
color: blue;
}</pre><div class="contentsignin">Copy after login</div></div><h3> Pseudoclass<code>:not()</code>
</h3><p> Pseudo-class filtering elements that do not match any given parameter. It is implemented in the <code>:not()</code> plugin. <code>postcss-selector-not</code>
</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article h1 .author,
.article h2 .author,
.article h3 .author,
.article h4 .author,
.article h5 .author,
.article h6 .author {
color: blue;
}</pre><div class="contentsignin">Copy after login</div></div>The result is: <p>
</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>@custom-selector :--links a, a:focus, a:visited, a:hover, a:active;
article :--heading :--links {
color: #333;
}</pre><div class="contentsignin">Copy after login</div></div><h3> Pseudoclass<code>:any-link</code>
</h3><p> plugin implements the <code>postcss-pseudo-class-any-link</code> pseudo-class. It was introduced to help resolve confusion around the <code>:any-link</code> pseudo-class. Unlike the latter, it matches all links – including those visited. <code>:link</code>
</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>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;
}</pre><div class="contentsignin">Copy after login</div></div>Compiled to: <p>
</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>button:matches(:hover, :focus) {
color: red;
}</pre><div class="contentsignin">Copy after login</div></div>Media Query Improvement<h2>
</h2>There are plugins in the library for PostCSS to make media queries easier to use. They are <p> and <code>postcss-custom-media</code>. <code>postcss-media-minmax</code>
</p>Custom Media<h3>
</h3>Writing media queries creates the same problems as regular selectors - they are often repeated in style sheets. Probably more frequent than normal selectors. Fortunately, there is a solution similar to a custom selector. <p> The plug-in implements a custom media query specification that increases the ability to save media queries into variables. <code>postcss-custom-media</code>
</p>The syntax is very similar to a custom selector. Here is a simple example: <p>
</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>button:hover, button:focus {
color: red;
}</pre><div class="contentsignin">Copy after login</div></div>Compiled to: <p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333;
&amp;amp;amp;.popular {
background: #DDD;
}
&amp;amp;amp; .title {
font-weight: bold;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p> Of course, you can use multiple custom media queries at once: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p> Will generate: </p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>.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;
}
}</pre><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div><div class="contentsignin">Copy after login</div></div>
<p>As you can see, it is now much easier to change the definition of "medium viewport" and find any relevant CSS code. </p>
<h3>Minimum and Maximum Syntax</h3>
<p> Although media queries are a great thing, the minimum and maximum grammars have received a lot of criticism from the community. W3C responds by introducing a more intuitive syntax using comparison operators. <code>postcss-media-minmax</code> Plugin adds support for <code>></code>, <code>>=</code>, <code><</code>, <code><=</code>, </p>. <p>
</p>(The rest of the article has been omitted due to the length of the article, but the image link remains unchanged)
The above is the detailed content of The PostCSS Guide to Improving Selectors and Media Queries. For more information, please follow other related articles on the PHP Chinese website!