{"id":376858,"date":"2023-08-14T12:48:12","date_gmt":"2023-08-14T11:48:12","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=webstorm&#038;p=376858"},"modified":"2023-08-14T13:48:15","modified_gmt":"2023-08-14T12:48:15","slug":"css-nesting","status":"publish","type":"webstorm","link":"https:\/\/blog.jetbrains.com\/webstorm\/2023\/08\/css-nesting\/","title":{"rendered":"Exploring the Power of CSS Nesting: Simplifying Styling and Enhancing Readability"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Imagine you\u2019re making a navigation menu \u2013 a panel with some boxes. Some of the styling goes in the panel (the parent), while some goes in the menu item (the child.) As easy as it is to describe this parent-child relationship verbally, it\u2019s surprisingly difficult to describe it in CSS code.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Well, not any more<\/span>! With <a href=\"https:\/\/www.w3.org\/TR\/2023\/WD-css-nesting-1-20230214\/\" target=\"_blank\" rel=\"noopener\">CSS Nesting<\/a>, <span style=\"font-weight: 400;\">nested styling is now powerful, easy, and native. Let\u2019s take a look at this new capability and how you can use it in the latest version of WebStorm.<\/span><\/p>\n<h1 id=\"background\">Background<\/h1>\n<p><span style=\"font-weight: 400;\">You might be wondering why CSS Nesting sounds familiar to you, and why you feel like you\u2019ve used it before.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Indeed, popular CSS-preprocessor tools like SCSS and LESS have supported this feature for quite some time. Now, CSS Nesting is not only supported by separate tools, it is even an officially recognized feature in the <\/span><a href=\"https:\/\/www.w3.org\/TR\/2023\/WD-css-nesting-1-20230214\/\" target=\"_blank\" rel=\"noopener\">CSS Specification<\/a>. <span style=\"font-weight: 400;\">The specification was not only motivated by the popularity of this feature in tools like SCSS and LESS, but also because it vastly reduces duplication and heavily improves the readability and maintainability of CSS code.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CSS Nesting support landed in Chrome Stable in March 2023, and WebStorm introduced support for it with its next major version, 2023.2. Since this feature is relatively new, we want to discuss the capabilities of CSS Nesting and what it lets you do as a developer.<\/span><\/p>\n<h1 id=\"what_is_css_nesting\">What is CSS Nesting?<\/h1>\n<p><span style=\"font-weight: 400;\">As the name suggests, this feature lets you nest CSS selectors and, therefore, group related styling. Let\u2019s assume we want to style a button and we also want to style the hover effect of that button.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Usually, you would write CSS rules as separate scoped definitions, based on a given selector. Adding a hover effect to the already-styled element requires you to reselect that given element and add the pseudo-class:<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/CSS-Nesting-Example-without-Nesting.png\" alt=\"CSS code styling a class called 'my_button' and then reselecting the 'my_button' class to apply a hover effect.\" width=\"800\"><\/p>\n<p><span style=\"font-weight: 400;\">But CSS Nesting lets you repurpose the element selector and nest the hover selector. This enables you to write your code more like this:<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/CSS-Nesting-Nesting-Example.png\" alt=\"CSS code styling the 'my_button' class applying the same styles as in our former example but using CSS nesting.\" width=\"800\"><\/p>\n<p><span style=\"font-weight: 400;\">No more redundantly specifying the parent selector! Using CSS Nesting lets us group the styling and, therefore, implicitly refer to the parent selector.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Want to go further? You can also nest your CSS code deeper, allowing more style specificity. Obviously, with great power comes great responsibility, so don\u2019t overdo it. By default, the SASS Linting rule suggests keeping the maximum depth of nesting to 2, which is a good practice to follow.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In some cases, nesting <\/span><i><span style=\"font-weight: 400;\">might<\/span><\/i><span style=\"font-weight: 400;\"> also give a big reduction in code size. Instead of specifying the parent element over and over, nesting lets you remove that part from your code. <\/span> Looking at <a href=\"https:\/\/www.w3.org\/TR\/css-nesting-1\/#example-df188c81\" target=\"_blank\" rel=\"noopener\">example 1<\/a> and <a href=\"https:\/\/www.w3.org\/TR\/css-nesting-1\/#example-aecb8796\" target=\"_blank\" rel=\"noopener\">example 2 <\/a><span style=\"font-weight: 400;\">we can see that nesting lets us write more concise CSS code.<\/span><\/p>\n<h1 id=\"limitations\">Limitations<\/h1>\n<p><span style=\"font-weight: 400;\">As of version 1 of the spec, you cannot have an element selector directly nested inside another selector:<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/CSS-Nesting-Element-Selector-Quirk.png\" alt=\"Error message that that is shown when using an element selector inside CSS nesting. The error says Nested selector can't start with an identifier or a functional notation.\" width=\"800\"><\/p>\n<p><span style=\"font-weight: 400;\">For this particular use case, the CSS Nesting Specification introduced <\/span> the <a href=\"https:\/\/www.w3.org\/TR\/2023\/WD-css-nesting-1-20230214\/#nest-selector\" target=\"_blank\" rel=\"noopener\"><code>&amp;<\/code> selector<\/a>. The following characters indicate a nested selector to the CSS parser.<\/p>\n<blockquote>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&amp; @ : . &gt; ~ + # [ *<\/pre>\n<\/blockquote>\n<p><span style=\"font-weight: 400;\">This is why you don\u2019t need a special character when you nest classes, for instance, yet you do need one for HTML elements. But don\u2019t worry: If you forget, WebStorm and other JetBrains products have you covered. If you happen to run into this particular scenario, your IDE will suggest applying the `&amp;` prefix, as you can see in the screenshot above. Note that at the time of writing this blog post, <\/span>there is an open <a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=1464756&amp;q=css%20nesting&amp;can=2\" target=\"_blank\" rel=\"noopener\">bug<\/a> that requires the <code>&amp;<\/code> selector when using the universal selector <code>*<\/code>.<\/p>\n<p><span style=\"font-weight: 400;\">There is one more limitation, though. With CSS preprocessors, you can use nesting to concatenate selectors with the <code>&amp;<\/code> selector:<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/CSS-Nesting-SCSS-Comparison.png\" alt=\"Image Taken from Sass Documentation\" width=\"800\"><br \/>\nImage Taken from <a href=\"https:\/\/sass-lang.com\/documentation\/style-rules\/parent-selector\/#adding-suffixes\" target=\"_blank\" rel=\"noopener\">Sass Documentation<\/a>.<\/p>\n<p><span style=\"font-weight: 400;\">This feature is extremely useful when using methodologies like Block Element Modifier<\/span> (<a href=\"https:\/\/getbem.com\/\" target=\"_blank\" rel=\"noopener\">BEM), <\/a><span style=\"font-weight: 400;\">for instance. On the other hand, it\u2019s very ambiguous. It would be difficult for a parser to differentiate between a concatenated selector or a nested element selector, which could in theory also reference a custom element. Ensuring compatibility with existing web standards prevented this feature from landing in the specification.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Version 2 of the specification is already being discussed, and this future update could further enhance the developer experience.<\/span><\/p>\n<h1 id=\"browser_support\">Browser Support<\/h1>\n<p><span style=\"font-weight: 400;\">For a feature whose official specification was released only 6 months ago, we already have decent browser support for CSS Nesting, particularly if you are targeting modern browsers. As of now, some mobile browsers still lack support, but always make<\/span> sure to consult <a href=\"https:\/\/caniuse.com\/css-nesting\" target=\"_blank\" rel=\"noopener\">canIuse <\/a><span style=\"font-weight: 400;\">for the latest in supported browser information.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/CSS-NEsting-Browser-Support.png\" alt=\"Screenshot from canIuse showing more than 72% Global browser support for CSS Nesting. Particular modern browser are well supported, but some mobile browsers are still lacking the feature.\" width=\"800\"><\/p>\n<h1 id=\"summary\">Summary<\/h1>\n<p><span style=\"font-weight: 400;\">CSS Nesting is a great way to get more expressive in the way you write and structure your CSS code. Given its already decent browser support, I highly recommend you give it a try. WebStorm 2023.2 can support you as necessary. And don\u2019t forget the corner cases, where you\u2019ll have to use the <a href=\"https:\/\/www.w3.org\/TR\/2023\/WD-css-nesting-1-20230214\/#nest-selector\" target=\"_blank\" rel=\"noopener\"><code>&amp;<\/code><\/a> selector when nesting element selectors.<\/span><br \/>\nHappy Coding!<\/p>\n<p><em>The WebStorm Team<\/em><\/p>\n","protected":false},"author":1424,"featured_media":380191,"comment_status":"closed","ping_status":"closed","template":"","categories":[6711],"tags":[199,8211,1731,8118],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/webstorm\/376858"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/webstorm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/types\/webstorm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/users\/1424"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/comments?post=376858"}],"version-history":[{"count":11,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/webstorm\/376858\/revisions"}],"predecessor-version":[{"id":412851,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/webstorm\/376858\/revisions\/412851"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media\/380191"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media?parent=376858"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/categories?post=376858"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/tags?post=376858"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/cross-post-tag?post=376858"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}