{"id":1013,"date":"2024-03-26T07:53:40","date_gmt":"2024-03-26T13:53:40","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=1013"},"modified":"2025-09-26T17:43:21","modified_gmt":"2025-09-26T22:43:21","slug":"what-you-need-to-know-about-modern-css-spring-2024-edition","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/what-you-need-to-know-about-modern-css-spring-2024-edition\/","title":{"rendered":"What You Need to Know about Modern CSS (2024 Edition)"},"content":{"rendered":"\n<p>My goal with this bookmarkable guide is to provide a list of (frankly: incredible) new additions to CSS lately. There is no hardline criteria for this list other than that these things are all <em>fairly<\/em> new and my sense is that many people aren&#8217;t aware of these things. Or even if they are, they don&#8217;t have a great understanding of them and could use a <strong>plain language<\/strong> explanation of what it is, <em>why they should care<\/em>, and a bit of reference code. Maybe that&#8217;s you.<\/p>\n\n\n\n<p>I&#8217;d like to work on our collective muscle memory on these features. <a href=\"https:\/\/twitter.com\/chriscoyier\/status\/1757826338722058444\">Like I said<\/a>, &#8220;even if you <em>know<\/em> about this stuff, it takes time to build the muscle memory around it.&#8221;<\/p>\n\n\n\n<p class=\"learn-more\">There is quite a bit more syntax, detail, and nuance to these things than I am presenting here. I want you to know what&#8217;s possible, reference the most basic usage and syntax, then dig deeper when you need to. <\/p>\n\n\n\n<div class=\"wp-block-group feature-group ticss-09a6e651\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Container Queries <span>(Size)<\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What are Size Container Queries?<\/h3>\n\n\n\n<p>Container Queries allow you to write styles that apply to the children of a container element when that container matches certain media conditions, typically a width measurement.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"element-wrap\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"element\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.element-wrap<\/span> {\n  <span class=\"hljs-attribute\">container<\/span>: element \/ inline-size;\n}\n<span class=\"hljs-keyword\">@container<\/span> element (<span class=\"hljs-attribute\">min-inline-size:<\/span> <span class=\"hljs-number\">300px<\/span>) {\n  <span class=\"hljs-selector-class\">.element<\/span> {\n    <span class=\"hljs-attribute\">display<\/span>: flex;\n    <span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>If you&#8217;ve ever thought: I wish I could make styling decisions based on the size of <em>this<\/em> element, not the entire page like <code>@media<\/code> queries force me to do. Then using <code>@container<\/code> queries are for you! People who work on design systems or heavily component-based websites will probably <em>mostly<\/em> use Container Queries to style things based on size, because the size of the entire page is a poor proxy for the size of a component. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-container-queries\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Potentially \u2014 if it&#8217;s not critical what you are styling, then yes.<\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/github.com\/GoogleChromeLabs\/container-query-polyfill\">Yes<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Demo of Usage<\/h3>\n\n\n\n<p>Use the resizer in the middle to see the calendar change layout depending on how much space it has. It has three breakpoints of its own.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_jOeBzNN\" src=\"\/\/codepen.io\/anon\/embed\/jOeBzNN?height=450&amp;theme-id=1&amp;slug-hash=jOeBzNN&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed jOeBzNN\" title=\"CodePen Embed jOeBzNN\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Container Queries <span>(Style)<\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What are Style Container Queries?<\/h3>\n\n\n\n<p>Container Style Queries allow you to apply styles when a given Custom Property has a given value. <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.container<\/span> {\n  <span class=\"hljs-attribute\">--variant<\/span>: <span class=\"hljs-number\">1<\/span>;\n\n  &amp;.variant2 {\n    --variantl 2;\n  }\n}\n\n<span class=\"hljs-keyword\">@container<\/span> style(<span class=\"hljs-attribute\">--variant:<\/span> <span class=\"hljs-number\">1<\/span>) {\n  <span class=\"hljs-selector-tag\">button<\/span> { } <span class=\"hljs-comment\">\/* You can't style .container, but can select inside it *\/<\/span>\n  <span class=\"hljs-selector-class\">.other-things<\/span> { }\n}\n\n<span class=\"hljs-keyword\">@container<\/span> style(<span class=\"hljs-attribute\">--variant:<\/span> <span class=\"hljs-number\">2<\/span>) {\n  <span class=\"hljs-selector-tag\">button<\/span> { }\n  <span class=\"hljs-selector-class\">.whatever<\/span> { }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>Have you ever wanted a mixin in CSS? As in, you set one property but get multiple properties. <a href=\"https:\/\/sass-lang.com\/documentation\/at-rules\/mixin\/\">Sass made mixins<\/a> fairly popular. You can do that with a Style Container Query. But just like how Sass had variables then CSS variables turned out to be more powerful and useful, Style Container Queries are likely to be more powerful and useful, because they respect the cascade and can be calculated and such.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-container-queries-style\">Browser Support<\/a><\/td><td>\u2705 Chrome &#8216;n&#8217; Friends<br>\ud83d\udd1c Safari<br>\u274c Firefox<br><br>(Late 2025 update): Same :\/<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Potentially \u2014 It depends on what you&#8217;re doing with the styles, but let&#8217;s say <em>not really.<\/em><\/td><\/tr><tr><td>Polyfillable<\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Demo of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_oNOBZMN\" src=\"\/\/codepen.io\/anon\/embed\/oNOBZMN?height=450&amp;theme-id=1&amp;slug-hash=oNOBZMN&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed oNOBZMN\" title=\"CodePen Embed oNOBZMN\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Container Units<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What are Container Units?<\/h3>\n\n\n\n<p>Container Units (literally units, like <code>px<\/code>, <code>rem<\/code>, or <code>vw<\/code>) allow you to set the size of things based on the current size of a container element. Similar to how with viewport units <code>1vw<\/code> is 1% of the browser window width, <code>1cqw<\/code> is 1% of the width of the container (although I&#8217;d recommend you use <code>cqi<\/code> instead, the &#8220;logical equivalent&#8221;, meaning the &#8220;inline direction&#8221;).<\/p>\n\n\n\n<p>The units are <code>cqw<\/code> (&#8220;container query width&#8221;), <code>cqh<\/code> (&#8220;container query height&#8221;), <code>cqi<\/code> (&#8220;container query inline&#8221;), <code>cqb<\/code> (&#8220;container query block&#8221;), <code>cqmin<\/code> (smaller of <code>cqi<\/code> and <code>cqb<\/code>), and <code>cqmax<\/code> (larger of <code>cqi<\/code> and <code>cqb<\/code>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>If the sizing of anything in an element feels as if it should be based on the current size of the container, container units are essentially the only way. An example of this is typography. A typical Card element may deserve a larger header text when it happens to be rendered larger, without something like a class name needing to be added to control that. (I&#8217;m a fan of <a href=\"https:\/\/codepen.io\/scottkellum\/details\/jOwmOZE\">this demo<\/a>.) Even a container query is clunky comparatively.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-container-query-units\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes \u2014 you could list a declaration using fallback units right before the declaration using container query units.<\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/github.com\/GoogleChromeLabs\/container-query-polyfill\">Yes<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Demo of Usage<\/h3>\n\n\n\n<p>This element uses container query units for not only the <code>font-size<\/code>, but the <code>padding<\/code>, <code>border<\/code>, and <code>margin<\/code> as well.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_wvZdPZb\" src=\"\/\/codepen.io\/anon\/embed\/wvZdPZb?height=450&amp;theme-id=1&amp;slug-hash=wvZdPZb&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed wvZdPZb\" title=\"CodePen Embed wvZdPZb\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">The <code>:has()<\/code> Pseudo Selector<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is the <code>:has()<\/code> selector?<\/h3>\n\n\n\n<p>The <code>:has()<\/code> selector allows you to conditionally select an element when elements deeper in the DOM tree of the original element match the selector you put inside <code>:has()<\/code>. <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">figure<\/span><span class=\"hljs-selector-pseudo\">:has(figcaption)<\/span> {\n  <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">1px<\/span> solid black;\n  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0.5rem<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>If you&#8217;ve ever wanted a &#8220;parent&#8221; selector in CSS, <code>:has()<\/code> can do that, but it&#8217;s more powerful than that, as once you&#8217;ve selected the parent you want, you can again drill back down. Jhey Tompkins once called it <a href=\"https:\/\/developer.chrome.com\/blog\/has-m105\/\">a &#8220;family selector&#8221;<\/a> which a nice way to think about it. You can also combine it with <code>:not()<\/code> to build a selector when an element <em>doesn&#8217;t <\/em>&#8220;have&#8221; a matching element inside.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-has\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Depends on what you&#8217;re doing with the styles, but let&#8217;s say <em>not really.<\/em><\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/github.com\/jplhomer\/polyfill-css-has\">For the JavaScript side only<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Demo of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_MWRJmzW\" src=\"\/\/codepen.io\/anon\/embed\/MWRJmzW?height=500&amp;theme-id=1&amp;slug-hash=MWRJmzW&amp;default-tab=result\" height=\"500\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed MWRJmzW\" title=\"CodePen Embed MWRJmzW\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">View Transitions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What are View Transitions?<\/h3>\n\n\n\n<p>There are two types of View Transitions:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Same-Page Transitions (Require JavaScript)<\/li>\n\n\n\n<li>Multi-Page Transitions (CSS Only)<\/li>\n<\/ol>\n\n\n\n<p>They are both useful. A same-page transition involves and animation when the DOM is changed without the page changing, like a list being sorted. A multi-page transition is for animating elements between page loads, like a video thumbnail transitioning into a video element. This is the basic syntax for a same-page transition:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-built_in\">document<\/span>.startViewTransition) {\n  updateTheDOM();\n} <span class=\"hljs-keyword\">else<\/span> {\n  <span class=\"hljs-built_in\">document<\/span>.startViewTransition(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> updateTheDOM());\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>For multi-page transitions: you need this meta tag:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"view-transition\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"same-origin\"<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Then any element you want to transition between pages you make sure has a totally unique <code>view-transition-name<\/code> applied in the styles, on both the outgoing page and incoming page. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>Users can understand an interface better if an element moves to a new position rather than instantly being there. There is an animation concept called <em>tweening<\/em> where the animation is automatically created based on a starting and ending state. View Transitions are essentially tweening. You can control aspects of the animation, but for the most part the animation is automatically created based on the starting and ending state of the DOM, rather than you having to be really specific about the animation details.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/view-transitions\">Browser Support<\/a><\/td><td>\u2705 Chrome &#8216;n&#8217; Friends<br>\u274c Safari<br>\u274c Firefox<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes \u2014 the transitions can just not run, or you could provide a fallback animation. <\/td><\/tr><tr><td>Polyfillable<\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Demo of Usage<\/h3>\n\n\n\n<p>This is an example of a same-page view transition:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_BaPLzGq\" src=\"\/\/codepen.io\/anon\/embed\/BaPLzGq?height=450&amp;theme-id=47434&amp;slug-hash=BaPLzGq&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed BaPLzGq\" title=\"CodePen Embed BaPLzGq\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Nesting<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is nesting?<\/h3>\n\n\n\n<p>Nesting is a way of writing CSS that allow you to write additional selectors within an existing <strong>ruleset<\/strong>.  <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-selector-class\">.card<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><mark class='shcb-loc'><span>  &gt; h2:first-child {\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">margin-block-start<\/span>: <span class=\"hljs-number\">0<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><mark class='shcb-loc'><span>  <span class=\"hljs-selector-tag\">footer<\/span> {\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">border-block-start<\/span>: <span class=\"hljs-number\">1px<\/span> solid black;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>Nesting is mostly a CSS authoring convenience, but the fact that it can group related CSS nicely together and prevent you from having to repeat writing a selector can mean avoiding mistakes and making the CSS easier to read. Nested CSS can also be something of a footgun in that may encourage writing CSS that matches the nesting of HTML in an unnecessary way, increasing the specificity and decreasing the reusability of some CSS. <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-selector-class\">.card<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">container<\/span>: card \/ inline-size;\n<\/span><\/span><span class='shcb-loc'><span>  \n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">display<\/span>: grid;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  \n<\/span><\/span><mark class='shcb-loc'><span>  @container (<span class=\"hljs-attribute\">min-inline-size<\/span>: <span class=\"hljs-number\">250px<\/span>) {\n<\/span><\/mark><span class='shcb-loc'><span>    gap: <span class=\"hljs-number\">2rem<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The only major difference from Sass-style nesting is that you can&#8217;t combine the <code>&amp;<\/code> directly. <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.card<\/span> {\n  body.home &amp; { <span class=\"hljs-comment\">\/* totally fine *\/<\/span> }\n  &amp; <span class=\"hljs-selector-class\">.footer<\/span> { <span class=\"hljs-comment\">\/* totally fine, don't even need the &amp; *\/<\/span>\n  &amp;__big { <span class=\"hljs-comment\">\/* nope, can't do this *\/<\/span> }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-nesting\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>No<\/td><\/tr><tr><td>Polyfillable<\/td><td>You could use a processor like LightningCSS, Sass, Less, etc.<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Scroll-Driven Animations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What are Scroll-Driven Animations?<\/h3>\n\n\n\n<p>Any animation that is tied to the scrolling of an element (often the page itself) can now be done in CSS rather than needing to bind DOM scrolling events in JavaScript. They come in two varieties:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The scroll progress of the element. (<code>animation-timeline: scroll()<\/code>)<\/li>\n\n\n\n<li>An element&#8217;s current viewable position within the element. (<code>animation-timeline: view()<\/code>)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>Imagine a reading progress indicator bar that fills from 0% to 100% as the user scrolls down the page. That can be done with an animation moving the <code>background-position<\/code> of an element tried to the overall scroll position of the page. Doing this in CSS instead of JavaScript is <a href=\"https:\/\/developer.chrome.com\/blog\/scroll-animation-performance-case-study\/\">good for performance<\/a>.<\/p>\n\n\n\n<p>The other major use case covered by scroll-driven animations is to run an animation as an element enters (or leaves!) the viewport. You have lots of control over the details, like when the animation starts and ends based on how visible the element is.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/mdn-css_properties_animation-timeline_scroll\">Browser Support<\/a><\/td><td>\u2705 Chrome &#8216;n&#8217; Friends<br>\u274c Safari<br>\ud83d\udd1c Firefox<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes \u2014 these effects tend to be visual flair, not required functionality.<\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/github.com\/flackr\/scroll-timeline\">Yes<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<p>This is the demo from when we looked at <a href=\"https:\/\/frontendmasters.com\/blog\/background-size-zooming-with-scroll-driven-animations\/\">image zooming and page scrolling<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_MWxaxVQ\/1dbc568d8f8404b5c9ba2fe6388bca0d\" src=\"\/\/codepen.io\/anon\/embed\/MWxaxVQ\/1dbc568d8f8404b5c9ba2fe6388bca0d?height=450&amp;theme-id=47434&amp;slug-hash=MWxaxVQ\/1dbc568d8f8404b5c9ba2fe6388bca0d&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed MWxaxVQ\/1dbc568d8f8404b5c9ba2fe6388bca0d\" title=\"CodePen Embed MWxaxVQ\/1dbc568d8f8404b5c9ba2fe6388bca0d\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Anchor Positioning<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is Anchor Positioning?<\/h3>\n\n\n\n<p>Anchor positioning allows you to place items relative to where another element is. Seems pretty obvious when put like that, but that&#8217;s what it is. You declare an element an anchor and give it a name, then can position elements to the top\/right\/bottom\/left (or center, or the logical equivalents) of the anchor.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>Once you can use this freely, you&#8217;ll have to care less about exact DOM positioning of elements (aside from accessibility concerns). The way it is now, the element you want to position relative to another has to be a <em>child<\/em> element and for there to be a positioning context to work within. This can dictate where elements go in the DOM, whether or not that makes sense. <\/p>\n\n\n\n<p>The big use cases are going to be tooltips and custom context menus. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-anchor-positioning\">Browser Support<\/a><\/td><td>\ud83d\udd1c Chrome &#8216;n&#8217; Friends<br>\u274c Safari<br>\u274c Firefox<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Possibly \u2014 if you can tolerate a totally different position for elements.<\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/github.com\/oddbird\/css-anchor-positioning\">Yes<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<p>At the time I&#8217;m publishing this, this only works in Chrome Canary with the &#8220;Experimental Web Platform Features&#8221; flag enabled.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_jORmvLr\" src=\"\/\/codepen.io\/anon\/embed\/jORmvLr?height=450&amp;theme-id=47434&amp;slug-hash=jORmvLr&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed jORmvLr\" title=\"CodePen Embed jORmvLr\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Scoping<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is Scoped CSS?<\/h3>\n\n\n\n<p>Scoping in CSS is in the form of an <code>@scope<\/code> at-rule that declares a block of CSS to only apply to the given selector. And optionally, <em>stop<\/em> applying at another given selector. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>You can also scope CSS by applying a class and nesting within that class. But <code>@scope<\/code> has a few tricks up it&#8217;s sleeve that can make it interesting. The &#8220;donut scope&#8221; option is a unique ability it has:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@scope<\/span> (.card) to (.markdown-output) {\n  <span class=\"hljs-selector-tag\">h2<\/span> {\n    <span class=\"hljs-attribute\">background<\/span>: tan; <span class=\"hljs-comment\">\/* stop doing this when we get to the Markdown *\/<\/span>\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>More logical proximity styling is another useful feature. This is a bit tricky to explain but once you see it you can&#8217;t unsee it. Consider theming. You have a <code>.dark<\/code> selector and a <code>.light<\/code> selector. If you only ever use one on the entire page, that&#8217;s fine, but if you end up <em>nesting<\/em> them at all, because they have the same specificity, whichever one you define later is technically a bit more powerful, and can win out even if it doesn&#8217;t make sense to. Minimal example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.purple-paragraphs<\/span> <span class=\"hljs-selector-tag\">p<\/span> { <span class=\"hljs-attribute\">color<\/span>: purple; }\n<span class=\"hljs-selector-class\">.red-paragraphs<\/span> <span class=\"hljs-selector-tag\">p<\/span> { <span class=\"hljs-attribute\">color<\/span>: red; }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"purple-paragraphs\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"red-paragraphs\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"purple-paragraphs\"<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>some text<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You might think the paragraph element in there would have the color purple, but it <a href=\"https:\/\/codepen.io\/chriscoyier\/pen\/oNOpqJK\">will actually be red<\/a>. That&#8217;s just awkward, but it <a href=\"https:\/\/codepen.io\/web-dot-dev\/pen\/MWZqazx\">can be fixed with <code>@scope<\/code><\/a>. When scoped selectors match, <a href=\"https:\/\/developer.chrome.com\/docs\/css-ui\/at-scope\">as Bramus says<\/a>, &#8220;it weighs both selectors by proximity to their scoping root&#8221;, and since &#8220;light&#8221; is closer here, it would win.<\/p>\n\n\n\n<p>My favorite though is the ability to drop in a <code>&lt;style&gt;<\/code> tag in the DOM and have it apply scoped styles only to that bit of the DOM, without having to name anything.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"my-cool-component\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style<\/span>&gt;<\/span><span class=\"css\">\n    <span class=\"hljs-keyword\">@scope<\/span> {\n      <span class=\"hljs-selector-pseudo\">:scope<\/span> { <span class=\"hljs-comment\">\/* selects the div above, without having to select it by class or anything *\/<\/span>\n      }\n      <span class=\"hljs-selector-class\">.card<\/span> {\n      }\n    }\n  <\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">article<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"card\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">article<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-cascade-scope\">Browser Support<\/a><\/td><td>\u2705 Chrome<br>\u2705 Safari<br>\u274c Firefox<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>No<\/td><\/tr><tr><td>Polyfillable<\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_XWQRovY\" src=\"\/\/codepen.io\/anon\/embed\/XWQRovY?height=650&amp;theme-id=47434&amp;slug-hash=XWQRovY&amp;default-tab=result\" height=\"650\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed XWQRovY\" title=\"CodePen Embed XWQRovY\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Cascade Layers<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What are Layers?<\/h3>\n\n\n\n<p>Cascade Layers in CSS are an extremely powerful syntax that affects the styling strength of a chunk of styles. You can optionally name and order layers (if you don&#8217;t explicitly order them, they order in source order). Styles in higher layers automatically beat styles in lower layers, <strong>regardless of selector strength.<\/strong> Styles <em>not<\/em> within layers are the most powerful. <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"home\"<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-code-table\"><mark class='shcb-loc'><span><span class=\"hljs-keyword\">@layer<\/span> base {\n<\/span><\/mark><span class='shcb-loc'><span>  <span class=\"hljs-selector-tag\">body<\/span><span class=\"hljs-selector-id\">#home<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-number\">#eee<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-selector-tag\">body<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attribute\">background<\/span>: white;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>We&#8217;re used to thinking that <code>body#home<\/code> is a <em>much<\/em> more powerful selector, thus the background will be <code>#eee<\/code>. But because there are unlayered styles here, that will win, making the background <code>white<\/code>. <\/p>\n\n\n\n<p>You may have as many layers as you like and can order them upfront. I think layering is likely to become a best practice on new greenfield projects, and take shape something like:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@layer<\/span> reset, default, themes, patterns, layouts, components, utilities;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>One gotcha is that <code>!important<\/code> rules on <em>lower<\/em> layers are actually <em>more <\/em>powerful.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>One clear way you get a lot of value out of CSS layers if you work on a project that uses a third-party styling library. You can put that library on a lower layer than the styles that your team writes, and you won&#8217;t have to worry about <strong>fighting<\/strong> the third-party library in terms of selector strength. Your styles on a higher layer will always win, which is likely to create cleaner and more maintainable CSS.<\/p>\n\n\n\n<p>For example, put all of Bootstrap on a lower layer just using the <code>layer<\/code> keyword and then any styles you write after that will win, even if Bootstrap itself uses a higher power selector.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@import<\/span> url(<span class=\"hljs-string\">\"https:\/\/cdn.com\/bootstrap.css\"<\/span>) layer;\n\n<span class=\"hljs-selector-tag\">h5<\/span> {\n  <span class=\"hljs-attribute\">margin-bottom<\/span>: <span class=\"hljs-number\">2rem<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-cascade-layers\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>No<\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/www.oddbird.net\/2022\/06\/21\/cascade-layers-polyfill\/\">Yes<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_PogmVqN\" src=\"\/\/codepen.io\/anon\/embed\/PogmVqN?height=450&amp;theme-id=47434&amp;slug-hash=PogmVqN&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed PogmVqN\" title=\"CodePen Embed PogmVqN\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Logical Properties<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What are Logical Properties?<\/h3>\n\n\n\n<p>Logical properties are alternatives to properties that specify a direction. For example, in a left-to-right language like English, the <code>inline<\/code> direction is horizontal and the <code>block<\/code> direction is vertical, so <code>margin-right<\/code> is equivalent to <code>margin-inline-end<\/code> and <code>margin-top<\/code> is equivelant to <code>margin-block-start<\/code>. In a right-to-left language like Arabic, <code>margin-inline-end<\/code> changes to the equivalent of <code>margin-left<\/code>, because that is the end side of the inline flow of elements. There are <em>a lot<\/em> of CSS properties and values that have a directional component like this (border, padding, offset, set), so the trick is understanding <code>inline<\/code> and <code>block<\/code> flow and using the correct <code>start<\/code> or <code>end<\/code> value.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>Often when you are declaring directional information in CSS, what you <em>mean<\/em> is &#8220;in the inline direction of text&#8221;. That might sound strange, but imagine a button and the space between an icon and the text. If you apply <code>margin-right<\/code> to the icon to space it away from the text, but then the page is translated to a right-to-left language, that spacing is now <em>on the wrong side<\/em> of the icon. What you meant was <code>margin-inline-end<\/code> on the icon. If you code your side using logical properties in this way,<strong> it will automatically translate better without writing any additional conditional code. <\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-logical-props\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>You&#8217;d have to use <code>@supports<\/code> and <code>unset<\/code> to remove the fallback value and reset using a logical property, <a href=\"https:\/\/adactio.com\/journal\/19487\">but it&#8217;s possible<\/a>.<\/td><\/tr><tr><td>Polyfillable<\/td><td>I can&#8217;t vouch for it, but there is <a href=\"https:\/\/github.com\/erickskrauch\/postcss-logical-properties-polyfill\">a processing option<\/a>. <\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_YzMVJBG\" src=\"\/\/codepen.io\/anon\/embed\/YzMVJBG?height=450&amp;theme-id=47434&amp;slug-hash=YzMVJBG&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed YzMVJBG\" title=\"CodePen Embed YzMVJBG\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">P3 Colors<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is the Display P3 Color Space?<\/h3>\n\n\n\n<p>We&#8217;re largely used to the sRGB color space on the web. That&#8217;s what hex colors use, and the <code>rgb()<\/code>, <code>hsl()<\/code>, and <code>hsb()<\/code> functions.  Many displays these days are capable of display a much <a href=\"https:\/\/webkit.org\/blog\/10042\/wide-gamut-color-in-css-with-display-p3\/\">wider range of colors<\/a> than sRGB is capable of describing, so being limited to that color space sucks. The Display P3 color space is about 50% wider than sRGB, expanding in the direction of more rich and vibrant colors. New CSS functions, which can even use different color <em>models<\/em> that have their own useful properties, allow us to declare colors in this space.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>If you want to use colors that are quite vibrant, you&#8217;ll need to tap into colors in the P3 Color Space. Using newer color models (and functions) can do this, and are very useful for a variety of other things.<\/p>\n\n\n\n<p>For example, the <code>oklch()<\/code> function (and thus <a href=\"https:\/\/oklch.com\/#61.88,0.286,342.4,100\">OKLCH color model<\/a>) can display any color any other method can (plus P3), has a similar human readability in common with <code>hsl()<\/code>, and has \u201cuniform perceived brightness\u201d, so that the first number (lightness) behaves way more predictably than it does in <code>hsl()<\/code>. That&#8217;s awfully nice for color on the web. But it&#8217;s not the only new color model and function! I find the <code>oklab<\/code> color model generally best for gradients.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>Browser Support<\/td><td>Full (e.g. <a href=\"https:\/\/caniuse.com\/mdn-css_types_color_oklab\">oklab<\/a>)<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes \u2014 you can declare fallback colors and displays that can&#8217;t display the color you declare will come back down into range.<\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/www.npmjs.com\/package\/@csstools\/postcss-oklab-function?activeTab=readme\">Yes<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<p>You can edit these <code>&lt;style&gt;<\/code> blocks because I made them <code>display: block;<\/code> and <code>contenteditable<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_RwOVqrZ\" src=\"\/\/codepen.io\/anon\/embed\/RwOVqrZ?height=950&amp;theme-id=47434&amp;slug-hash=RwOVqrZ&amp;default-tab=result\" height=\"950\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed RwOVqrZ\" title=\"CodePen Embed RwOVqrZ\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Color Mixing<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is <code>color-mix()<\/code>?<\/h3>\n\n\n\n<p>The <code>color-mix()<\/code> function in CSS allows you to, <em>wait for it<\/em>, mix colors. This kind of thing has been baked into CSS processing tools for a long time, and as typical of CSS evolution, now that it&#8217;s in native CSS, it&#8217;s more thoughtful and powerful than it ever was in a processor. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When you should care?<\/h3>\n\n\n\n<p>Have you ever wanted to darken or lighten a color you already have on the fly? That&#8217;s one of the things <code>color-mix()<\/code> can do. Color mixing can happen <em>in a specific color model<\/em> which means you can take advantage of how that models works. For example, the perceptually uniform brightness of OKLCH makes it sensible to use for adjusting brightness. <a href=\"https:\/\/developer.mozilla.org\/en-US\/blog\/color-palettes-css-color-mix\/\">You can make whole color palettes<\/a> using <code>color-mix()<\/code>. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Browser Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/?search=color-mix\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes, you could declare fallback colors.<\/td><\/tr><tr><td>Polyfillable<\/td><td>Could be but I don&#8217;t know of one.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_ZEZKqvq\" src=\"\/\/codepen.io\/anon\/embed\/ZEZKqvq?height=450&amp;theme-id=47434&amp;slug-hash=ZEZKqvq&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed ZEZKqvq\" title=\"CodePen Embed ZEZKqvq\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Margin Trim<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is <code>margin-trim<\/code>?<\/h3>\n\n\n\n<p>The <code>margin-trim<\/code> property removes any margin in the direction specified from the selected container <em>at the end of that direction.<\/em> Imagine you have five blocks in a row that all have right margin on them in a container. You might select the <code>:last-child<\/code> to remove the right margin. With <code>margin-trim<\/code> you can ensure that margin is removed from the parent element itself.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.container<\/span> {\n  <span class=\"hljs-comment\">\/* prevent \"extra\" margin at the end of the element *\/<\/span>\n  <span class=\"hljs-attribute\">margin-trim<\/span>: block-end;\n\n  <span class=\"hljs-comment\">\/* an element like this might be the culprit, but it could be anything *\/<\/span>\n  &gt; p {\n    <span class=\"hljs-attribute\">margin-block-end<\/span>: <span class=\"hljs-number\">1rem<\/span>;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>You know how the <code>gap<\/code> property of flexbox and grid is&#8230; awesome? It only puts spacing <em>between<\/em> elements. Well, if you need to apply spacing between elements but you&#8217;re in a position where you can&#8217;t use <code>gap<\/code>, <code>margin-trim<\/code> is awfully nice as it means you apply directional margin to all the children and not worry about an additional fancy selector to select the first or last one and remove that unneeded final margin. It might end up <a href=\"https:\/\/chriscoyier.net\/2023\/06\/12\/margin-trim-as-a-best-practice\/\">a best practice<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/mdn-css_properties_margin-trim\">Browser Support<\/a><\/td><td>\u2705 Safari<br>\u274c Chrome<br>\u274c Firefox<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes. A little extra space likely isn&#8217;t a major problem.<\/td><\/tr><tr><td>Polyfillable<\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<p>The last paragraph here is a notorious situation where the bottom margin on it creates more space at the bottom than any of the other edges. With <code>margin-trim<\/code> we can ensure it&#8217;s sliced off without having to select that last paragraph and manually remove it.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_eYoWPRP\" src=\"\/\/codepen.io\/anon\/embed\/eYoWPRP?height=650&amp;theme-id=47434&amp;slug-hash=eYoWPRP&amp;default-tab=result\" height=\"650\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed eYoWPRP\" title=\"CodePen Embed eYoWPRP\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Text Wrapping<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is <code>text-wrap<\/code>?<\/h3>\n\n\n\n<p>The <code>text-wrap<\/code> property likely isn&#8217;t in your long term CSS memory. It&#8217;s capable of <code>text-wrap: nowrap;<\/code>, but we generally think of <code>white-space: nowrap;<\/code> for this. But now, <code>text-wrap<\/code> has two new tricks up it&#8217;s sleeve:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>text-wrap: balance;<\/code> \u2014 Attempt to make equal-width lines when text wraps.<\/li>\n\n\n\n<li><code>text-wrap: pretty;<\/code>  \u2014 Avoid orphans.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>A headline with one word orphaned onto the next line just looks really awkward and could be considered poor typography. There wasn&#8217;t a great way to solve this before, short of somewhat awkward tricks like inserting a <code>&amp;nbsp;<\/code> instead of a normal space between the last two words. <em>Balancing <\/em>a headline prevents this, but goes further in making the multiple lines of text generally the same width. Using <code>pretty<\/code> is more focused just on orphan prevention alone, making it more appropriate for body text.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-text-wrap-balance\">Browser Support<\/a><\/td><td>Depends on which value. <code>balance<\/code> has decent support with all browsers ready or coming soon. <code>pretty<\/code>, <a href=\"https:\/\/caniuse.com\/css-text-wrap-balance\">less-so.<\/a><\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes. While slightly less aesthetic, widows and orphans are not that big of a problem, so if this property doesn&#8217;t work, it&#8217;s no big deal.<\/td><\/tr><tr><td>Polyfillable<\/td><td><a href=\"https:\/\/github.com\/adobe\/balance-text\">Yes.<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_gOyWZRN\" src=\"\/\/codepen.io\/anon\/embed\/gOyWZRN?height=450&amp;theme-id=47434&amp;slug-hash=gOyWZRN&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed gOyWZRN\" title=\"CodePen Embed gOyWZRN\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group feature-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h2 class=\"wp-block-heading\">Subgrid<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is Subgrid?<\/h3>\n\n\n\n<p>Subgrid is an optional part of using CSS grid that is relevant when you are nesting gridded elements. By setting <code>grid-template-columns: subgrid;<\/code> or <code>grid-template-rows: subgrid;<\/code> on a grid-level element, you&#8217;re saying &#8220;inherit these columns or rows from my parent grid, where relevant&#8221;. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When should you care?<\/h3>\n\n\n\n<p>The point of using grids for layout is generally <em>lining things up<\/em>. Without <code>subgrid<\/code>, it means that child elements of a grid don&#8217;t have access to the grid lines of the parent grid, and thus lack the opportunity help line things up. Subgrid fills that gap. When DOM nesting is important for functionality or accessibility, like in a <code>&lt;form&gt;<\/code>, subgrid can help <a href=\"https:\/\/codepen.io\/chriscoyier\/pen\/YzxqJap\">ensure things line up sensibly<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Support<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><a href=\"https:\/\/caniuse.com\/css-subgrid\">Browser Support<\/a><\/td><td>Full<\/td><\/tr><tr><td>Progressive Enhancement?<\/td><td>Yes. You can fall back to defining your own grid lines that are workable if not perfect.<\/td><\/tr><tr><td>Polyfillable<\/td><td>No. There is <a href=\"https:\/\/github.com\/FremyCompany\/css-grid-polyfill\">a grid polyfill<\/a> but it doesn&#8217;t do subgrid.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Example of Usage<\/h3>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_bGRXmEe\" src=\"\/\/codepen.io\/anon\/embed\/bGRXmEe?height=450&amp;theme-id=47434&amp;slug-hash=bGRXmEe&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed bGRXmEe\" title=\"CodePen Embed bGRXmEe\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n<\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Things to keep an eye on&#8230;<\/h2>\n\n\n\n<p>The speed of CSS development doesn&#8217;t seem to have slowed down. There is plenty to continue to watch for and look forward to.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/css.oddbird.net\/sasslike\/mixins-functions\/\">CSS Mixins &amp; Functions<\/a> \u2014 <em>actual<\/em> mixins and functions that take parameters<\/li>\n\n\n\n<li><a href=\"https:\/\/developer.chrome.com\/blog\/css-relative-color-syntax\">Relative Color Syntax<\/a> \u2014 a way to manipulate the parts of colors in an intuitive and powerful way.<\/li>\n\n\n\n<li><a href=\"https:\/\/webkit.org\/blog\/14955\/the-web-just-gets-better-with-interop\/\">Interop 2024<\/a> \u2014 All the things that we can essentially bet on for being cross-browser compatible soon, including the relative color syntax above.<\/li>\n\n\n\n<li><a href=\"https:\/\/developer.chrome.com\/docs\/css-ui\/css-field-sizing\">The CSS property <code>field-sizing<\/code><\/a> should help the long-standing difficult issue of auto-resizing form elements like textareas and input to the content they contain. <\/li>\n\n\n\n<li><a href=\"https:\/\/open-ui.org\/prototypes\/selectmenu\/\"><code>&lt;selectmenu&gt;<\/code> in HTML<\/a> is essentially a fully CSS styleable <code>&lt;select&gt;<\/code>, which is wild. <\/li>\n<\/ul>\n\n\n\n<p>That&#8217;s just a few things to watch. You might as well <a href=\"https:\/\/frontendmasters.com\/blog\/feed\/\">subscribe to our feed<\/a> as we&#8217;ll be doing the watching for you and then you&#8217;ll catch the next one.<\/p>\n\n\n\n<p>Did I miss a relatively new favorite of yours? Let me know.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My goal with this bookmarkable guide is to provide a list of (frankly: incredible) new additions to CSS lately. There is no hardline criteria for this list other than that these things are all fairly new and my sense is that many people aren&#8217;t aware of these things. Or even if they are, they don&#8217;t [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1409,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[7],"class_list":["post-1013","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-css"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/03\/css2024-thumb.jpg?fit=1000%2C500&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1013","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=1013"}],"version-history":[{"count":121,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1013\/revisions"}],"predecessor-version":[{"id":7293,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1013\/revisions\/7293"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/1409"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=1013"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=1013"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=1013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}