{"id":3829,"date":"2025-05-12T08:24:20","date_gmt":"2025-05-12T06:24:20","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=3829"},"modified":"2025-05-12T08:34:41","modified_gmt":"2025-05-12T06:34:41","slug":"mastering-modern-css-exploring-is-where-and-has-selectors","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2025\/05\/12\/mastering-modern-css-exploring-is-where-and-has-selectors\/","title":{"rendered":"Mastering Modern CSS: Exploring :is(), :where(), and :has() Selectors"},"content":{"rendered":"\n<p>CSS is constantly evolving, and with its latest updates, writing efficient and maintainable styles has never been easier. Among the most exciting features introduced are the <strong>:is()<\/strong>, <strong>:where()<\/strong>, and<strong> :has()<\/strong> pseudo-classes. These functions are game-changers, allowing developers to write cleaner, smarter, and more powerful CSS. Let\u2019s dive into how they work and why we should start using them today<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4> :is() Selectors<\/h4>\n\n\n\n<p>The :is() pseudo-class simplifies our CSS by grouping multiple selectors into one. This reduces repetition and makes our code cleaner and easier to maintain.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/Before: Repetitive Code\nh1, h2, h3 {\r\ncolor: blue;\r\n}\n\n.....\n\n\/\/ After: Cleaner with :is()\n:is(h1, h2, h3) {\r\ncolor: blue;\r\n}\n<\/code><\/pre>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-red-color\">Benefit:<\/span><\/strong><\/p>\n\n\n\n<ul><li>Reduces code duplication.<\/li><li>Improves readability and maintainability.<\/li><\/ul>\n\n\n\n<p>With :is(), we can group any number of selectors and apply styles to them in a single declaration.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><\/p>\n\n\n\n<h4>:where() Selectors<\/h4>\n\n\n\n<p>The <strong>:where() <\/strong>pseudo-class functions similarly to :<strong>is()<\/strong>, but with one key difference: it has zero specificity. This means it won\u2019t override more specific rules in our stylesheet.<br><\/p>\n\n\n\n<p>Example: Global Defaults with :where()<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>:where(h1, h2, h3) {\ncolor: red;\n}<\/code><\/pre>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-red-color\">Use Case:<\/span><\/strong><\/p>\n\n\n\n<ul><li>Perfect for defining global defaults.<\/li><li>Ensures these styles don\u2019t interfere with more specific rules elsewhere in your CSS.<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h4> :has() Selectors  <\/h4>\n\n\n\n<p>For years, developers have wanted a way to style parent elements based on their children. Enter :<strong>has()<\/strong>. This pseudo-class allows us to apply styles to a parent element if it contains a specific child.<br><\/p>\n\n\n\n<p>Example: Style a Parent Based on Its Child<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.card:has(img) {\nborder: 2px solid green;\n}<\/code><\/pre>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-red-color\">Real-World Use Case:<\/span><\/strong><\/p>\n\n\n\n<ul><li>Add a border to .card only if it contains an element<\/li><li>Highlight a form field\u2019s parent when it contains an invalid input.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>.form-group:has(input:invalid) {\nbackground-color: #ffe6e6;\n}<\/code><\/pre>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-red-color\">:is() <\/span><span class=\"has-inline-color has-black-color\">vs.<\/span><span class=\"has-inline-color has-vivid-red-color\"> :where()<\/span><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Feature<\/th><th>:is()<\/th><th>:where()<\/th><\/tr><\/thead><tbody><tr><td>Specificity<\/td><td>Normal specificity<\/td><td>Zero specificity<\/td><\/tr><tr><td>Use Case<\/td><td>Group selectors for shared styles<\/td><td>Define safe global defaults<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-red-color\">Why These Functions Are Game-Changers?<\/span><\/strong><\/p>\n\n\n\n<ul><li>Cleaner Code: Reduce repetition and improve readability.<\/li><li>Better Maintainability: Easier to update and manage styles.<\/li><li>Enhanced Power: Solve previously impossible challenges, like styling parents based on children.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>:is(h1, h2, h3):has(+ p) {\r\ncolor: purple;\r\n}\n\n:where(.default-button, .secondary-button) {\r\nbackground-color: lightgray;\r\n}<\/code><\/pre>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><br>Modern CSS tools and browsers now support these pseudo-classes, so there\u2019s no reason to wait. By incorporating :is(), :where(), and :has() into our workflow, we\u2019ll write smarter, more efficient styles and unlock new possibilities in our designs.<br>Happy coding! \ud83d\ude42 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>CSS is constantly evolving, and with its latest updates, writing efficient and maintainable styles has never been easier. Among the most exciting features introduced are the :is(), :where(), and :has() pseudo-classes. These functions are game-changers, allowing developers to write cleaner, smarter, and more powerful CSS. Let\u2019s dive into how they work and why we should [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3009,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[89],"tags":[1023,1021,1022,1025,1020,1026,921,1024,735],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3829"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=3829"}],"version-history":[{"count":3,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3829\/revisions"}],"predecessor-version":[{"id":3832,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3829\/revisions\/3832"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/3009"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=3829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=3829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=3829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}