Modern CSS Code Snippets: Stop writing CSS like it's 2015

20 hours ago (modern-css.com)

These look like some interesting css options, though I'll comment that adding grid placement options is less new, and more just minor syntactic sugar. Plus, basic grid layout styling being added to css will rarely do what we actually want them to do.

Accounting for scrollbar appearance and auto-updtating the width of the frame/window is pretty useful, though. Not having the horizontal scroll bar suddenly appear when a vertical bar is needed due to dynamic elements is highly preferable.

CSS in 2025: Let's write html inlined styles as if it was 2005 and separation of formatting/representation was never invented. I talk of tailwind, of course.

  • Are we still complaining about Tailwind? This ship has sailed. The world is so much better than the old BEM/LESS hell, it is wonderful. UnoCSS is even greater in empowering frontend developers.

  • The deadest horse in web development is the myth of “separation of concerns”

    • I was recently doing some very specific web scraping of some very public very static documents. About 25% of them use a soup of divs with hashes for class names. Not a <main> or <article> or <section> in sight. I am fine with the idea of what tailwind does but like at least using semantic tags where appropriate could be a thing.

      19 replies →

    • I don't think "separation of concerns" is entirely dead. Ideally, the CSS is readable and maintainable, and that implies structure. If you have a bunch of (co-)related components, you don't want to find/replace tailwind class names when you need to change the layout. So you separate that part of the layout in classes based on (layout!) functionality. You can see that as "concerns."

    • I don't use Tailwind, it's a solution to a problem I don't have.

      I can understand how it might be useful for certain types of web development, e.g. landing pages where the content and styles are tightly coupled.

      So as a technology, it's OK. But my god its userbase is toxic and obnoxious.

      1 reply →

    • SoC is how all maintainable software is built. A function for A, a class for B, DDD-spec'd modules and features, databases on separate machines, API definitions, queuing systems, event systems, load balancing, web servers.

      You don't even need to think of the web to see how content and presentation are different. Try editing a text file with hard line breaks in and you'll quickly understand how presentation and content are orthogonal.

      1 reply →

    • You can separate concerns without violating locality of behavior, and that’s exactly what tailwind does.

      It admittedly does not do a good job at being very DRY but I think that’s poorly applied to HTML/CSS in general, and the most DRY css is often over abstracted to the point of becoming nigh uninterpretable.

      5 replies →

  • HTML vs. CSS is a separation of technologies. If HTML was really only about the content and the CSS was only about styling, we wouldn't have to write div soups to style our websites (.container-wrapper .container .container-inner { /* "separation" */ }) and we wouldn't have to adjust our HTML when we change the layout.

  • Yeah. There is no need to obfuscate your code, just use Tailwind.

    • Obfuscate? I can learn tailwind and use it in dozens of projects. I can use tailwind in my project and onboard dozens of developers immediately. I can learn your CSS conventions and use them in exactly one project.

      3 replies →

  • I do not work frontend and yet, I always end up having to do some CSS here and there.

    I have never been happy on how I manage CSS. With tailwind, I am still unhappy about my styles but I can make my ugly UIs faster.

  • Yeah let's do that. You have everything related to your component on place instead of jumping between files.

  • Tailwind is a direct response to how the "C" in "CSS" actually sucks, so there's no surprise that it's so popular.

    • The "C" (Cascade) in CSS doesn't suck, the education about it sucks.

      People don't know how it works, then things go wrong so they learn to work around it.

      That's what led to things like div + class soup that you get with the BEM naming convention or Tailwind.

      The cascade is actually awesome, super powerful and if you know how to use it, it can greatly simplify your code.

      Education is the problem and the solution.

      ---

      To anyone outside the CSS space, this is the closest analogy I can find:

      In the American education system, there was a recent-ish change where children are "taught" to read using a method of just learning the shape of every word (e.g. "thermally" has a th at the start and ly at the end, so it must be the word "thermally", despite other similar looking words like thematically).

      The method was disproven but the American education system still uses it.

      Now illiteracy rates are climbing where almost 1/4 Americans (USA) can't read.

      It's basically the same thing with CSS, where developers don't know what the code they're reading/writing is actually going to do.

      4 replies →

    • I mean, the cascade really doesn't suck though does it. You really want to set font families and sizes on every p tag?

  • Yeah and it's a really good idea. You can't really 'separate layout from style.' The layout and the style are both parts of the UI. HTML isn't the content, it's the layout.

    Even if you believe separation of concerns is the eleventh commandment, HTML and CSS are the same kind of 'concern' anyway. They're both at representation layer. Pretending you can decouple them is just burying the head in the sand.

  • Wait until you see React & JSX...

    At least html and CSS are both presentation. React/JSX now confuses presentation and business logic.

I dislike the examples here where the "old" way works in all browsers, but the "new" way only works in Chrome/Edge. IMO, it's irresponsible to include such examples, since it makes the Blink monoculture worse.

In case the author happens to read these - final statement in native CSS nesting is no longer true.

"The only small difference from Sass: for element selectors you need the & prefix. In Sass you could write a { color: red } inside a parent, but native CSS requires & a { color: red }."

It was true for a bit, but fixed within 2-3 releases iirc. You can now freely nav { a { color: red; } }

My top list of recent CSS improvements:

1) Nested selectors.

2) :has(...).

3) :is(...), before you had to write :not(:not(...)).

4) :where(...), similar to :is(...), but the selector weight inside :where becomes 0. Useful when you need deep/complex selectors without increasing the selector weight.

  • big +1 on #1.

    As a tip - most LLMs are unaware it exists due to either knowledge cutoff or not having enough training data for it.

    As a recommendation, include some examples of it in your AGENTS.md. Here's what I use:

    --------------------------------------

    ## CSS nesting (required) When writing CSS (including component `css()` strings and `soci-frontend/soci.css`), *use modern CSS nesting* where it improves readability and reduces repetition.

    - Prefer nesting with the `&` selector for pseudo-classes / pseudo-elements and compound selectors. - Avoid duplicating the parent selector when nesting can express it once. - Reference: [MDN `&` nesting selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/S...)

    ### Quick reference

    #### Pseudo-classes / no-whitespace attachment

    ```css .button { color: var(--text);

      &:hover {
        color: var(--text-secondary);
      }

    } ```

    #### Pseudo-elements

    ```css .fade { position: relative;

      &::after {
        content: '';
        position: absolute;
        inset: 0;
      }

    } ```

    #### Descendant nesting (whitespace implied)

    ```css .card { padding: 12px;

      .title {
        font-weight: 600;
      }

    } ```

    #### “Reverse context” (`.featured .card`) using `&`

    ```css .card { .featured & { border-color: var(--brand-color); } }

  • Mine is text-box: trim. Twenty years of trying to explain to graphic designers why it’s next to impossible possible to get the top of a capital letter to a box, I feel free like a bird.

  • I like 2-4 but I despise nested selectors. They make selectors ungreppable.

    • Why/how do you grep selectors? Seems overly optimistic to be able to guess the particular rule pattern that is applying a style. Browser tools are much more reliable.

      2 replies →

Stop pinning things to the edges of the screen and window. Some sites have literally over 50% of the viewable area taken up by irrelevant static elements. Let the content scroll, like god intended.

I didn’t pay close attention to the domain and I thought it was the other one:

https://moderncss.dev/

One of the best educational resources for modern CSS.

BTW, one of the reasons I love modern CSS is front-end performance. Among other things, it allows you to make smaller DOMs.

I talk about a modern CSS technique that does that here:

https://op111.net/posts/2023/08/lean-html-markup-with-modern...

It is an idea I started playing with when custom properties landed in browsers, around 2016 or 2017? Around 2021 I started using the technique in client sites too.

Now I want to write a 2026 version of the post that talks about container queries too. The technique becomes more powerful if you can rely on container queries and on the cqw unit. (You cannot always. That stuff is still new.)

For an example of the convenience cqw offers if you can rely on it, see the snippets I have in this:

https://omnicarousel.dev/docs/css-tips-know-your-width/

Me: cool, let's be creative, I love 2026.

Browsers: Yeah, but beware of limited availability, most of those creative examples are in the 40-50% browsers support range.

  • In the past this was a major issue that meant useful features were only ever usable after IE/Safari finally supported them half a decade later, but it has seriously gotten better. Sadly as a result of Chromium's overbearing presence, but it's a helpful outcome at least.

    https://wpt.fyi/interop-2025

    • Problem with safari though is that it’s tied to OS updates that many people just defer for insanely long periods of time. So unlike the other browsers, it’s not evergreen, so if you need to support any iOS users or Mac users who don’t use chrome etc, you’re out of luck

  • > most of those creative examples are in the 40-50% browsers support range.

    Not if you filter the examples. Click "widely available".

    • First widely available one I saw was this: https://modern-css.com/staggered-animations-without-nth-chil...

      That would actually fix some ugly CSS I have. The demo works. Neat.

      Except... the demo doesn't use either the old syntax or the new syntax. The browser support is wrong (Firefox doesn't support it, the site says Firefox 16+; it says Chrome 43+ but in reality it's much newer: Chrome 148+). It says "Since 2018" but the spec was introduced in 2024.

      So maybe an interesting overview of things that might be available or might not, but the filtering and data on the site doesn't seem to be useful.

      3 replies →

  • It takes time. Browser vendors add support for those features now, in the hope that they will become widely available one day.

I'm confused, many of these examples state that they don't work in my browser (Firefox) - but the live demo works fine? Are the demos poly-filled?

  • Their labeling of feature availability is messed up. It says sibling-index() is widely available when it's not even available in Firefox yet.

  • No, it says: "Limited availability".

    These green percentage points at the bottom left show how many of the Web audience (IDK by what measurements) runs a browser supporting this feature. A ton of them are even below 50%.

    So I suppose it's not "modern CSS", but more like "latest Chrome CSS". Best viewed in Internet Explorer 5.

    • Absolutely. So no thank you, I won't stop writing CSS like it's 2015 if those features aren't at least supported by all latest browsers.

t’s interesting how different CSS approaches end up shaping completely different mental models: utility classes, semantic blocks, scoped styles — each tool pushes the architecture in its own direction.

Live demo for input:user-invalid does not work on my phone.

It'd always been the same: those ugly patches of JavaScript were being added to maintain compatibility with all the browsers... That's why the newest CSS tricks were always out of reach for us

  • yeah, it doesn't work on desktop Firefox or desktop Chrome-based browser either.

    That one is a dud. Most others work for me, though.

So where are we at with utility libs (tailwind/tachyon) vs inline css in js vs preprocessors (sass/scss) vs vanilla modern css?

  • Wherever you want to be.

      Tailwind works for your team? Go for it.
      Inline CSS for your solo project? By all means.
      Still stuck on SASS? It'll keep working just fine.
      All in on modern CSS? More power to ya!

Great resource! Browser support tables make it production-ready. How does it compare to CSS-Tricks almanac for edge cases?

Congratulations to the creator of this site and thank you so much for posting it !

I have to (unwillingly) do frontend work so I recently read up on CSS quite a bit. I have always thought that using computed numbers for styling is bonkers. Its better to use CSS that uses logical values. The site seems to emphasize that style.

The color lightening/darkening is new to me. I have a bunch of older sites that still accomplish the same thing with Sass and Compass, but the Compass toolchain has been fiddly to keep running. Nice to see that as a new creature comfort.

Well it's flat out wrong about some things, like `field-sizing: content`. Doesn't work in any version of Firefox, let alone Firefox 130+! It even links to caniuse, which says the same thing.

The "new" version doesn't even have the handle to manually expand the box - the old version does!

Random pet peeve... it annoys me when people have old browser-specific aliases to standardized CSS properties. For example, -o-tab-size and -moz-tab-size instead of just tab-size. Those properties haven't done anything on Opera/Firefox for a decade!

I've been doing this webdev things too long. Many of these "old" examples are news to me.

Ironically the website is locked to dark mode and doesn’t use the (not so) modern prefers-color-scheme.

CSS and JavaScript are like two dysfunctional law enforcement agencies fighting over jurisdiction.

  • All web standards are like this, and then the battle continues when it comes to browser implementation.

I hate how it's still not possible to properly style the numbers in ordered lists.

I use them for code snippets with automatic line numbers, but it's literally impossible to space the numbers (relative to the code) while keeping them aligned to the right. ¯\_(ツ)_/¯

https://jsfiddle.net/89t1rd2u/

Funny how half of the shit there does not work for me, even though I'm using latest Chrome (Helium)

...and start writing it like you're an LLM!

This looks generally good but sadly also stylistically is similar to the default "modern" output of Claude Code. Just a thought.

The first example of not using absolute positioning isn't a good example because sometimes you do need to absolutely position things, like a modal.

Also you can just use display: flex with justify-content: center and align-items: center for non absolutely positioned elements.

Just because it uses CSS grid does not make it more "correct" than flexbox.

I also only see one usage of custom @property properties here, which has been one of the most useful things to happen to CSS in years. They have many different use cases, particularly for complex animations.

  • Modal containers should be position: fix; with their own internal flexbox or grid btw.

Is it just me or gradients and tile grid with specific hover effects are AI generated stuff giveaways? Maybe it's old people yelling at clouds, but I'm very reluctant to trust the site, when I see these signs.

  • AI got it from people though.

    I too am saddened by the instant-polish marketing pages everyone and their grandma deploys to Render, but also some people at some point in time really did make these effects. And they are nice. HTML based UIs will always have a place in my heart.

    Btw: actually I think webflow did more to pump this stuff out to the masses. The animate on scroll being the biggest offender. It's so good, but not for every literal text paragraph on your local bakery's website.

  • You’re right not to trust it, it’s wrongly calling sibling-index() widely available. And that’s the first example I checked.

CSS is the only thing from browsers we actually need. The rest can be done in a terminal. Contemporary terminals could even render the UI with way less memory. The browser is a nightmare because it wasn’t architected to run applications.

  •   > The rest can be done in a terminal. (...) The browser is a nightmare because it wasn’t architected to run applications.
    

    Neither were terminals, which were not even designed with a screen in mind.

  • > The browser ... wasn’t architected to run applications.

    Could you explain this? What prevents the browser from running applications? How should it have been architected otherwise if running applications was the goal?

2015 is good enough.

For example instead of grid center, one can use flex and margin auto.

If you are building really nation-wide products, there are still a lot of guys in corporate with old windows (where even chrome stopped updating like win7). Or, you know, old or poor people with PC from 2008.

Also don’t forget guys with mobile phones: not like one could easily install a browser there. Especially on phones which no longer receive updates.

So writing CSS like it is 2015 is great. Not because it feels great but because it is what caring about your users (and business) is.

Otherwise you’ll get humbled by your clients soon enough. And in corporate they won’t even be your clients unless you support old stuff: IE 11 is a great target if you really want to shine.

  • I dare you to find any analytics, anywhere, that show any IE 11 usage.

    It would be utterly negligent to still be running IE in a corporate environment. It’s a huge security risk.

    • Just recently I stumbled on some god forsaken pc hooked up to a projector in some conference room.

      It had Windows 7 with guess what browser built-in. It had Chrome also, thank god (that’s how I know it is no longer updated by Google under 7).

      But that’s not the point. The thing is 2015’s state of affairs is good enough for dare I say most UI.

      Yeah, grid is not there, but there are very specific UIs that need what flex cannot provide.

      PostCSS takes care for most other legacy things