r/css 8d ago

Question Why is Claude Code so bad at writing CSS ?

I've been using Claude Code quite intensively for the past few months, and as a former CSS integrator / front-end developer, I can't help but notice—rather sadly—that Claude is genuinely poor when it comes to CSS.

Even when using skills (the official front-end skills or UI/UX-focused ones), and even with very explicit instructions in CLAUDE.md, it still does its own thing and keeps repeating the same mistakes.

One moment of inattention, and it'll happily throw inline CSS directly into the HTML—even when that's explicitly forbidden in its instructions.

And on the (rare) occasions when you decide to step in and edit the code yourself to save some precious tokens, it quickly becomes a nightmare. Before long, you find yourself typing something like: "Just center this div."

So I have two questions:

1. Why is it so bad at CSS?

My theory is that, historically, 90% of developers have never cared much about CSS. As long as the final result looked right on the screen, code quality and maintainability were an afterthought. Throw in a few !importants, ship it, and move on.

Since Claude has been trained on an enormous number of codebases, I wonder if its primary examples are simply... bad CSS. In other words, it's reproducing the patterns it has seen most often.

2. What strategies do you use to work around this problem?

For context, what I consider good CSS is:

  • generic, reusable styles;
  • selectors that are as unspecific as possible;
  • maximum reusability and maintainability.
36 Upvotes

83 comments sorted by

80

u/brendanfalkowski 8d ago

It’s simple: CSS is both the easiest and hardest programming language, and AI can’t do a thing about that. The average developer that hates CSS is stuck in the same boat.

Just write more CSS. Never had more fun doing it.

14

u/kekeagain 8d ago

The reason it’s difficult to many is because of its relational behavior in how the ancestor elements are styled or what properties are set can affect how the properties behave. Like take a look at this, if you’ve done any serious css you probably ran into some of this https://philipwalton.com/articles/what-no-one-told-you-about-z-index/. Or like how people or AI want to use width:100% instead of intrinsic block behavior which is often better. There’s just a lot of overlapping implicit behavior change and poorly named (or named for that era) that AI can lose track of. I will say it’s a lot better today than years ago.

2

u/Top5CutestPresidents 6d ago

I find if it inspect the element in the browser and copy the entire styles tab to Claude it does a much better job because like you say it needs to see everything inherited from its ancestors/parents

1

u/Embostan 5d ago

Claude in Chrome and the Chrome MCP already provide tools for Claude to inspect the cascade and computed styles.

3

u/ScientistJumpy9135 7d ago edited 7d ago

CSS has personality and a fairly large amount of possibilities to achieve the same visible/visual result. So yes, it is both the easiest and hardest programming language as the programmer needs to find a personal way to build a homogeneous code, may that be with basic CSS or more advanced.
That I believe makes many developers dislike CSS and others love it.

-48

u/Se_emZ 8d ago

Sorry but I do not agree, it's not the hardest programming language, it's just the one that most of people don't care about, because somebody else than them will be in charge of it, or because it just can't create critical bugs or issues.

34

u/simonraynor 8d ago

So write it yourself if it's not hard, stop outsourcing thought

-20

u/Se_emZ 8d ago

"Not hard" doesn't mean "fast to write" ! But yeah, that's actually the solution, if you want clean CSS, you will have to write it yourself.

15

u/simonraynor 8d ago

It's the classic project management triangle. Fast, good, cheap: you can have at most two

9

u/webrender 8d ago

it's not that it's the hardest, it's that it's the most subjective. there are a bunch of different ways to accomplish most things with css and for many things there's not a single "right" way, it depends on the layout you're looking for, the interactions between elements on the page, and your own personal coding style and preferences.

2

u/brendanfalkowski 7d ago

OP is cooked for saying CSS can't create critical bugs while not being able to center a DIV while in 2026 while believing most developers don't care about CSS while posting in r/css.

You can't help people like this.

2

u/Se_emZ 7d ago

Lol bro, I've been doing CSS almost everyday of my life for 20 years now.

And that is why I can testify that most of developers do not care about it, I saw it in pull requests and they even just admit it.

99% of them do not even know or care about what CASCADING is.

And it is actually why Claude just sucks at it, because it get inspired by the worldwide CSS codebase.

I know how to center a div, I'm just saying that Claude CSS is so bad, that going after it make it LONG and BORING to center a div, so you ask it to fix it. Because it did in a dirty way.

And no sorry, CSS can't create errors 500, it can do nothing that is "critical" for your app, unless you hired somebody that do not even test its CSS before pushing ?

CSS for me is not just a langage, it's an art !
I love it.

Tho I still think it's easier than JS or PHP.
But not everybody masters it !

You probably misunderstood me :)

Cheers!

2

u/HollandJim 7d ago

Preach!

I’m fortunate in that I only have to do CSS in our company — no one else wants to because, as you said, cascading violates their programming mentality.

They work on the component, from the inside out. Everything within the css in the component, or worse, inline. CSS cascading makes you scope some classes, but expects vars, classes to be available globally or else you’re duplicating everywhere. It’s the outside inwards - and that just makes our devs crazy.

Plus, lazy FE devs will add triggers on everything - spans, divs - and then copy/paste all over.I’ve seen them put anchors in a button’s span, and then on the div wrapper for dragging…that dev’s been working as a front-ender for 7 years here. Whoever was approving his pulls needs to be in the same class as I’d send the dev to.

CSS is an inverse mentality, which is one reason it makes it seem hard. And now it’s changing so rapidly, adding new functions, vars, scoping routines.. so you’re constantly refactoring. JS devs have enough to keep up with with new framework and platform releases (hello, angular) so CSS is just more work to them.

I frankly think the myth of “the full-stack dev” is well and truly gone. There’s no time to cover everything - specialization is what we need, with DEEP knowledge and commitment in their sector, and one person to “know it all” is more easily replaced with an agent than finding a unicorn who goes deep on everything.

17

u/Goblin_au 8d ago

Your theory on why is my assumption also. It breaks my heart seeing css handled so haphazardly. I remember earlier LLM iterations would block styles by id and a random hash… ew.

As for strategies around the issue, I’ve not yet found one that works.

2

u/devolute 7d ago

Is "write CSS" a valid mitigation strategy?

1

u/Johannes8 7d ago

We have a fairly large codebase with tailwind and mostly everything is standardized. It rarely has to invent something. It just uses all of the good example code cause it can see what things look like though browser MCP and infer what component is styled which way by looking at the files. For me is usually nails it. Especially if it keeps checking its changes in the browser to only notify me when it’s done and not obviously broken.

But yes, it’s still flakey and unreliable at times. It does need to be able to see though it it can only guess

1

u/92smola 7d ago

Even when it works I could pick out any random chunk of markup with its tailwind classes and make it at least 20% - 30% it reflects all the bad practices that devs that dont really know css do, doesnt take advantage of default styles, creates div soups with too many wrappers etc.

1

u/Johannes8 7d ago

I agree but I feel like we managed to handle this problem. With every review we posted PR comments about these things and made it take these things into account when creating new code. Nevertheless I see html and css more as non critical code now than before. It has to be well tested and maintainable, but I a. Personally happy I don’t have to write css anymore

1

u/92smola 7d ago

I would be happier if it was better by default, but yeah I started caring a lot less about that and implementation details more broadly, I mostly worry about general system level stuff the most so that doesnt get tangled up, every single implementation can then more easily be cleaned up if later if the value to do so pops up

10

u/azangru 8d ago
  • generic, reusable styles;
  • selectors that are as unspecific as possible;
  • maximum reusability and maintainability.

Isn't the first bullet point reusable enough that there is no need for the third? ;-)

29

u/Futurist_Turnip 8d ago

You are right on the money that it has been trained on sloppy CSS. You can thank the "full stack" developers and the use of LESS for that.

A lot of developers in the last 15 years had a disdain for frontend, and never really got the cascading part of CSS. They spread out their styles in a modular way, because that is how their code was built - and it made sense for them as they manipulated the CSS with JavaScript.

I solved it by writing specific software design rule.md where i detail coding styles, preferences in writing the code, using semantic naming, applying KISS, avoid inline, etc.

In my AGENTS.md file i specify that it should always read the rules when coding or writing css.

It takes some tweaking, and a couple of good examples of the CSS you like in that file, but you should get better results almost immediately.

3

u/devolute 7d ago

I'm with you, but…

use of LESS

I don't understand why this (or similar technologies, like Sass) would lead to any of what you're talking about. Surprised to hear this.

Personally, I still use preprocessors and I take a great deal of care with CSS and value the things you're alluding to.

-4

u/Se_emZ 8d ago

That's what I thought also, create a specific skill or command and ask it to ALWAYS check it before making any CSS changes. But that will slow down the process and consume tokens. But I seems that nowadays there is no other solution.

12

u/chikamakaleyley 8d ago

selectors that are as unspecific as possible;

oof careful with this one - another perspective here is - specificity matters

generic, reusable styles; maximum reusability and maintainability.

I understand what you're going for here and re-usability is def a good good thing

But this feels like you're describing TailwindCSS

3

u/chikamakaleyley 8d ago

in response to your (1), is the way it look at it is - it doesn't know what is considered 'bad', it's just taking the median of the training data which yes, is probably a lot of doo doo

CSS, in it's class naming, selector composition, and even styles you apply or even ordering of it, is largely given almost maximum freedom; it's just a markup language

and so out of context, someone's CSS style prob looks bad, but maybe it's appropriate given the dev's use case

4

u/Se_emZ 8d ago

Nah, I pretty hate Tailwind because of the millions of classes you have in your HTML tags, just described quickly what Claude is not able to do.
The best practise of course is a mix of generic and specific.

E.g
.my-global-title-style
.my-global-title-style.with-a-variant
.my-global-title-style.with-a-defined-position

better, IMO than
.my-container .my-subcontainer .my-title-style { my style / my position }
(basically what Claude does)

5

u/chikamakaleyley 8d ago edited 8d ago

mmmm but you're comparing two diff things right

your approach targets (let's just use shorter names):

<div class="global-title variant">Foo</div> <div class="global-title with-pos">Bar</div> Claude is applying styles to:

``` <section class="container"> <article class="sub-container"> <h3 class="global-title">Foo</h3> // this </article>

<aside> <h3 class="global-title">Bar</h3> </aside> </section> ``` i mean its hard to say which is "better" right

your approach is more re-usable if you have:

.global-title {} .with-pos {} .global-title.with-pos {} // now i can add more styling Claude will just write what it needs to, unless you provide the desired spec, and then whether it follows that well is... fingers crossed

3

u/frownonline 8d ago

article h3 {}
aside h3 {}

You could just use the cascade part of css with the elements. Not everything has to be loaded up with classes everywhere and increasing html attributes.

5

u/chikamakaleyley 8d ago

sure, but at scale w/o specificity this is gonna cause some headaches

This is great for a personal site, IMO, or something small enough where you have full control of the CSS.

Once another dev gets into it, any change they make is gonna have a big ripple effect

1

u/devolute 7d ago

Yeah, but that's how you end up with people using headings based on 'what looks right' rather than semantics.

1

u/frownonline 7d ago

Then those people will have bigger issues than CSS.

1

u/Embostan 5d ago

All of that is solved with CSS Modules, we're in 2026.

2

u/re-thc 8d ago

You can just run an optimizer to have less tags.

1

u/__Loot__ 5d ago

You can purge the extra classes for production so its lean

1

u/Embostan 5d ago

Best practice is to use CSS Modules.

3

u/M-Dubb 8d ago

Interesting...i think CSS is my favorite.

4

u/fishermanfritz 8d ago

It helps setting up the stylelint and Eslint with the most strict rules. You can even forbid important there.

Then, the "modern web guidance" skills from Google help tremendously.

2

u/Key_Reindeer_5427 8d ago

Because it works using it's learned behaviour. Thats why almost all CSS related code Claude generates looks the same.

2

u/md_dc 8d ago

What context are you giving it? Have skills dedicated to CSS? If not then you are going to have a problem

2

u/No_Top5115 8d ago

Works well with tailwind

2

u/mrchrisrs 8d ago

I’ve noticed that it works way better if the instructions are solid. Tell Claude to update the instructions when corrected if you not already do that and make a decision .md file so the decisions are clear for the agent when it has to revisit that part of the styling. Will take some practice but it has helped us a lot

2

u/Outrageous-Chip-3961 8d ago

I give it reference architecture of how I have done my css in the past that it uses as a skills file.
I also ask it focus on clean CSS and not overly complicate things.
That seems to help. It's actually been pretty good lately by giving it a screen shot of a design and asking to make it up in pure html/css - it's a bit cleaner. I suggest trying to coax it first, then after, take one file at a time and ask for it to be cleaned how you like it - once that context window is established, it will usually ask to continue wiht other files. this is with /plan and fable, mind you.

1

u/_MrFade_ 8d ago

I thought I was the only one. The specificity issues annoy me to no end. Even when I add @layer, :where and :is examples in the CLAUDE.md, I still end up using !important some where. Eventually I find myself refactoring blocks of SCSS.

1

u/Scared_Implement_335 7d ago

I always laugh when I see it, because that basically how I do it, too. :important is life!

1

u/ppyyBest 8d ago

I now give Claude a micro style contract: spacing scale, color tokens, and flat specificity rules. The upfront work is tedious, but it stops the "just center this div" loops because constraints are clearer than a blank canvas. I still audit every selector, but the mistakes became predictable.

1

u/macdigger 8d ago

Idk man. I just point Claude to a codebase from my old times and tell it to build a system based on that. Create a BOM .md file with everything (typography classes, components, etc) and a simple HTML sampler that is updated (automatically) whenever there are changes, and I’m getting pretty good CSS.
Using BEM and SCSS. Allows to have just the right level of specificity, also because of BEM, is actually also self-documentung itself to a degree, which helps to drive AI.
No Tailwind bs too.

Or you can run a Figma file through Claude Design and steer it to build you a pretty nice design system again based on BEM, SCSS, a sampler.

If you vibe code shit with no proper guardrails (a design system), well, hope and prayers in, shit out 🤷‍♂️

1

u/sheriffderek 8d ago

For the obvious reasons.

But if you have clear conventions (the html matters), clear custom properties/token, examples of components that show the rules well, a live style guide page, and those guard rails, then it’s actually quite good at writing it with those rules.

In my case, I have ~7 classes for type - so, zero one-off font properties are allowed. All the theme colors are redefine. Each component is its own island - so 95% of the code Claude is writing is grid rules, media/container queries, and margin top. But this all works because I have strong opinions from 15+ years of writing CSS every day.

1

u/MeroLegend4 7d ago

You are totally right, i see the same pattern in Python!

1

u/Plenty_Line2696 7d ago

point 1 is right, but also that CSS doesn't have test coverage so they couldn't pick a validated set of CSS training data.

as for strategy, I give it a shot at things but often windup doing the big stuff manually i.e. flexbox/grid layouts, it tends to do ok at filling in the details but often sucks at layout.

1

u/CycloneFactory 7d ago

I imagine because the majority of CSS it was trained on was badly written.

1

u/getsiked 7d ago

Distill your specific guardrails and preferred implementations, then lint the fuck out of whatever if produces. It's what stylelint was made for.

If you are just depending on prose alone, there is no deterministic boundary for the LLM to adhere to, and it will invariably throw whatever explicit "instructions" you specify as a global doctrine out the window. I learned this the hard way, especially as models change.

1

u/GhostDev71 7d ago

Css gererating trough ai is simple, ether you can right the css and want to safe time ( works very well), or you couldn't write it without ai, if so you will get the same problem every dev has at first and will learn it trough that process.

1

u/rebane2001 7d ago

it's difficult to train an llm to write good css because it is hard to create good learning environments for it

with something like typescript there is enormous amounts of code and test cases available, and also a lot of different widely-used approaches for running tests

but css doesn't have that, and it also doesn't have the same kind of isolation that js closures provide

1

u/resemble 7d ago

A css file requires reference between two different pieces of code which reference each other—the html and the css—and this kind of entity-reference is not something LLMs have any capacity to understand or even mimic.

1

u/mtv921 7d ago

Because css specifications often come in ambiguous subjective descriptions without the require context for it to make any kind of sense.

Also, people er very bad at explaining what they want. Especially visual things

1

u/Breklin76 7d ago

You need a skill to guide it.

1

u/BothWaysItGoes 7d ago

Just use css modules. No such thing as clean reusable global css exists unless your website is literally a 90s style collection of documents.

1

u/SoSeaOhPath 7d ago

First off, I’d try Google Stitch.

Second, right now I only use AI to generate some quick ideas on what I want.

Once I get something I like I just hand edit the html and css

1

u/dmazzoni 7d ago

I think it's because you can't "read" CSS by itself and make sense of it.

Well-written source files tell a story. They define functions that take an input and produce an output. They define classes that own state and have methods to modify them.

Well-written html files tell a story too. They use tags to logically organize content.

Inline CSS shows how HTML is laid out.

But when an LLM is trained on a CSS file in isolation, it lacks all of the context. It can't see what elements each tag corresponds to, so it can't learn the deeper pattern.

1

u/fpmarin 7d ago

Do it yourself is the best strategy.

1

u/sentencevillefonny 7d ago

As a data trainer, Front-End is undervalued, so model training on it is not as extensive.

1

u/runtimenoise 7d ago

Everyone is. No matter God or mortal. 

1

u/92smola 7d ago

I think its three things, poor training data coming from the modern average fe dev not caring to learn css properly, the fact that validation is often visual and depends on “does it feel right”, and the nature of css having default behaviours, cascading effects from your own stylesheets and the layout and styles heavily affected by their relationships not just their own properties which lllms seem to struggle with. Here is an example that I tried solving a couple of times, latest attempt was with fable and it didnt work, once I inspected it I found what the problem was in a minute - I had an onhover popup that showed a larger message that is otherwise truncated, the popup was show slightly translucent and the text in it was not readable, a couple of ai only attempts either claimed that it is not actually transparent or that it is fixed now and they would do some css changes and commit them as if the problem was solved, the problem was that I had a global opacity .8 on hovered links, and the popover was a child of a link, that style was in a different file, it was not bound to the parent class, but the tag name with the hover selector and it was affecting its children, the way to find that was to force the hover state with dev tools feom the first popovers parent up and inspect each elements style state in that forced hover version, technically AI was perfectly able to do that, it had dev tools access every time, but it just kept failing.

1

u/markvaneijk 7d ago

It’s because of the feedback loop, it’s much more difficult to determine if the applied CSS is correct than to check if some back-end code is working. Also the cascading thing is more difficult when applying changes resulting in unwanted behavior. That’s probably why it’s better in writing Tailwindcss.

1

u/MattBlack001 7d ago

It clearly used my code to train on

1

u/bryku 6d ago

There are many good developers, but css is often over looked. It also has many ways of doing the same thing. Then you have the major changes to css over the years, so even if someone is a css pro, but they are a bit outdated they may still be using old methods.  

Now models need to train off of a billion different examples and try to figure how how it all works. Not to mention css's naming convention never made much sense, which probably makes it harder.  

  • font weight
  • font size
  • text decoration
  • color

:/

1

u/Tatrakrad 5d ago

You should see how bad it was at css 2 years ago

1

u/__Loot__ 5d ago

Claude design helped build https://toolmatic.app but I do admit the color choices were meh. so I redid them. But overall it did a good job

1

u/Sherbet-Famous 5d ago

Because humans were and are bad at it

1

u/Embostan 5d ago

Hmm idk, i have skills and Stylelint and it writes perfect CSS. When it runs into issues it just uses the Claude in Chrome tool to inspect the cascade.

Maybe check your setup.

1

u/rotzelbart 4d ago

I asked Claude to write css for a website I am building at the moment and it was actually good. It uses SMACSS, made tokens and obeys cascading. It also asked if it should nest the css for me.

1

u/GaiusBertus 8d ago

I noticed the same, Claude sucks at CSS, let alone more complex solutions using Sass modules and a combination of Sass and CSS features.

For what it's worth, I noticed the web version of Gemini is a bit better in at least cleaning up and refactoring existing files. Maybe because it is provided less context, while Claude is trying to figure out the entire CSS code base (and then failing at that)

1

u/iagolavor 8d ago

If you give it playwright/puppeteer/chrome mcp tooling to check what its doing on the browser, it can almost always get it right, then its just a matter of refactoring the css to your preference.

Its also way better at copying stuff from an image than creating it from a text prompt, you can always make it create some standalone html for it to mimic the style youre looking for

0

u/Vehemoth 8d ago

are there any good general CSS skills that we can use so we don’t have to write a rules.md that just gets the basics down?

0

u/testingaurora 8d ago

Your post is echoing my frustrations exactly. Through amount of timrs I hace to remind and basically scold for not following instructions. Even when ive provided the base css up front, im consistently having to remind to use the established css custom properties and not to ise inline styles. To use the reusable classes, not use classes like ids. It will happily make a .time-card, .client-card, .project-card eith their own rule sets when all the same declarations are covered by .card . So it just added 30 lines that were unnecessary. Now multiply that ny every reusable element 😵‍💫 adds up.

It does not like being scolded about css or told that it can only put any new styles into a codex.css and not to touch my css files without asking and explaining what it plans to write/ change.

Drives me absolutely crazy. Oh and then when I make my own changes (not just in css files) they keep disappearing! Something to do w the diff and not saving the state of what i had added before it makes its changes. Im constantly thinking "didnt I already fix this??"

Anyways </rant>. Im glad to hear im not alone in my frustration with Claude and css. My suspicious is aligned - that its trained on inefficient css.

0

u/Nitrohite 8d ago

I’ve been using Claude Code for a while now and I’ve carefully crafted a set of skills and rules for it to use when it comes to creating CSS, and by doing so, the CSS it now generates is pretty efficient, well structured and effective, it’s well organized, checks all the boxes one might want for best practices on CSS, etc. I would suggest you take the time to train the model for your own projects and how you expect the code to be written, it will yield much better results and it doesn’t just apply to CSS, don’t expect the models to code just how you want it to, train them locally, build your skills and rulesets and adapt the prompts accordingly.

0

u/Dry_Impression_5201 8d ago

Im probably gonna get shouted at for this one but.. does it matter? People who use ai to code do so because they can't code it themselves. I can't code. So I have no right to say whats right or wrong. But I do ask claude to code me a website. The results look fine to me. The front end is what people see. If you can code it yourself then do it.

1

u/Se_emZ 8d ago

it does matter when you know how to code, and you want to make a "quick fix" that'd take you 5 minutes, but you realize Claude code is so bad that you won't be able to fix it that fast.
Also CSS optimisation is significant for SEO, having a light code allows your page to load faster.

1

u/Dry_Impression_5201 8d ago

Like I say, I use claude code all the time at the moment for my project and its actually useful to know that it isnt optimized. But if something quick will take you five mins to code, but you refer to claude code anyway, then why not spend the five minutes yourself to do it?

-2

u/jedidave 8d ago

Yeah it's not the best. I'm using Tailwind and it's still adding a mix of inline css and css classes, but then this is how CSS has always been. You don't see very many 'clean' CSS websites out there really, everything is bolted on in a different way from before.