Hacker News new | past | comments | ask | show | jobs | submit login

It’s beyond me why CSS has to be so hard to understand. I have made several attempts and got it right, but it feels like I have to start at zero every time.

I believe, it’s because CSS is not a programming language, but we are trying to do programming with it. Like: if screen is mobile then render divs stacked. I don’t know




I think CSS is "difficult to understand" because most people who do front-end don't want to spend a day learning it.

Ask some people who make the claim it's difficult: what is the box model, and what is selector specificity. I can almost guarantee they won't be able to answer those questions, because they haven't bothered to actually try to learn CSS. Their knowledge of CSS is built from a set of "how do I do X in CSS" searches and the resulting stylesheets are hobbled together messes.

If you learn the box model, if you learn the reasons behind selector specificity, and how cascading works, you'll really earn a true appreciation for CSS. It does not take long to learn, you just have to spend a day reading through the "boring" stuff.


> I think CSS is "difficult to understand" because most people who do front-end don't want to spend a day learning it.

Yeah, "html/css" is the object of our derision on HN as some sort of thing that's beneath us. As if someone who is an "html/css" designer isn't a real developer. Yet at the same time we complain that we have to learn it. That after pretending it was trivial all this time, we're annoyed that we can't just fake our way through it when the going gets tough.

But the other reason it's hard is that UI and clientdev is hard. There's this weird meme that UI is just bells and whistles and stakeholder pleasers instead of a human interface that demands a lot of forethought and expertise, and something that has to be functional and possibly even a joy for the user to use. You can see this when people here brag about being backend developers that never touch the client as if that's something to brag about.


> I think CSS is "difficult to understand" because most people who do front-end don't want to spend a day learning it.

I couldn't disagree more. There are a ton of reasons CSS really is hard, even when one understands the box model etc.

E.g.:

1. Hugely non-modular. An element's behavior always depends, to some extent, on styles applied to other elements. Systems full of entangled global state are inherently complex, separate from any other concern.

2. Highly magical. E.g. if you want to control how elements stack with z-index, you need to also know that z-index is ignored for elements that aren't positioned, which in turn means you need to set up your margins differently because positions disable margin collapsing. There's no one "model" to learn; it's a big morass of interconnected rules and edge cases.

3. Extremely fragile. Layout changes that a human user might consider minor often can't be done without significantly redesigning the page.

Of course, problems like these can all be mitigated to various extents. But that takes care and experience; it's not just a matter of reading some articles like you imply.


I've been writing CSS for about 10 years at nearly every professional job I've had. I don't get 'stuck' often and generally feel competent, but I am far from an expert or a master. I think CSS is difficult to understand because there are so many ways to accomplish a task, and so many of those ways lead to (sometimes) unforeseeable consequences, and nearly all of the APIs (possibly with the exception of css grid) don't feel very coherent... in my experience. I think it is difficult to learn because there's no real apparent holistic design to really grok.

I tried mdgriffith's elm-ui on a personal project and it was a breath of fresh air. It felt like an utterly excellent abstraction and I hope someone ports it to Typescript/React/JSX some day.


Yeah I think working with CSS is like working with Databases. There are a lot of ways in databases to get the job done. At first glance it seems to work the way you want and even survives early testing or even deployment. It doesnt fall apart until much later when you are trying to build upon it, scale it, etc.. This causes many people to learn the wrong way to do something because they might not stick around until it falls apart. The next time they have to do something they remember the way they got it to work last time and do it again, never realizing they are leaving a trail of tears for future developers to clean up the mess with.

CSS is very much the same way. I can't tell you how many times I have seen CSS files that are a house of cards. One wrong element gets added into a markup and the whole thing crumbles. Unnecessary use of !important, wildcards, overly specific, not specific enough, inconsistent media queries, desktop-first layouts (as opposed to mobile-first, or often times a mixture of the two depending on the element), and so on. At first glance, the stakes for bad CSS also seem pretty low (which is not the case with databases or backend code). This further causes developers to just hack at it until it works or is "close enough". It instills bad habits that last years or even entire careers.


The comparison with databases is an interesting one. I have observed in both that really diving into exploiting the domain in a language-native way (e.g. CSS or SQL) can lead to extremely powerful solutions, but ones which don't integrate very neatly into a broader system. So you usually find people inventing patterns, or restricting themselves to subset -- choosing to skip some of the power in favour of maintainability. You can build an entire system in just SQL and little-to-no other programming languages, but should you?


it also doesn't help that sometimes you have to whack-a-mole different browser implementations of the spec, and particularly if you're working on a bit of a website somebody else owns you have to be very careful about specificity, what styles other teams may be using, etc.


Pardon me, but I've read tens of technical references, rationales and getting started's in my life, but not a single one was so ritualistic and/or useless for practicing as everything about css. The reason is...

Their knowledge of CSS is built from a set of "how do I do X in CSS" searches

Because "box model and selector specificity" is light years away from how to do X. If you want an analogy, you are suggesting to win a chess tournament by thoroughly learning chess rules and figures. But you can not. It is okay for chess, where you build up your expertise for years and decades, but not for a rapid application development. Css is a bike with no front wheel, one pedal and it only turns left, unless you know that sit-backwards hack. There are better (more reason-enabling at least) layout systems out there, but cool web guys are digging in their heels on that "css" thing. And that would be okay, iff they made that damn bike at least complete, at least once in its lifetime.

Want a simple, trivial puzzle?

  (component1)
    .form
      label.a input
      label.b input
  .some-content
  (component2)
    .form
      label.c input
Make all labels of the same, non-fixed width, for these forms to look more aligned under different label localisations. Without recomposing layout elements. In constraint-based layout, it is a.w = b.w = c.w (priority:low). In gtk, you add (a,b,c) into the same SizeGroup. In css I'm doing it the wrong way, these requirements are strange, I should rethink my model, take a different/better approach, maybe it is okay for them to not be aligned, because awesome css at least solves a huge load of problems and the internet rests on it, bla-bla-blah.

That even may have an almost-css-only solution, but whatever it is, it will be yet another "recipe" with a pile of crutches as ingredients. Which is likely not compatible with rendering loops or a structure of a half of popular js/css frameworks.


CSS is a top-down language, not a constraint language. It is not surprising that you cannot construct things in the same way as you would in a constraint-based layout system.

I am sure I could discover an equal "simple" example that is easy in CSS but difficult/impossible in GTK.

That you cannot use a hammer in the same way as a crowbar, even though they are both blunt instruments, is not a condemnation of the hammer. So yes, you do need to evaluate what the right tool for the job is - like JS to do a quick width-match on the labels' natural widths - after the CSS did most of the rest. That is not "bla-bla-blah," that's just knowing the limits of your tools.

The frustration seems to be the impression that CSS should be able to solve any conceivable layout desire on the web, which isn't its charge: CSS is first and foremost made to style web documents, which by-and-large don't fit as easily into the constraint-based-layout box as a traditional desktop app would. Since this kind of desire often crops up in desktop-like SPAs, where JS use is endemic already, it's not wrong to use a little bit more JS to nudge the visual experience a little closer to what you'd see on a desktop app.

I guess my takeaway is, CSS doesn't promise the world, so if you come in expecting that, you'll walk away disappointed. Luckily there are many tools in the web dev toolkit to achieve your engineering desires, and it's not verboten to use them (aside from a philosophical desire to avoid JS, but if the biggest problem for your page when JS is disabled is that the labels are slightly different sizes, I think you're doing a great job already).


You just switched from blaming me for not knowing css to blaming me for not using the right tool, as if I had a clear way to do that. It is nothing new and was propheted in bla-blah paragraph. But if you ever tried to size-match in JS, you know that it is not a trivial task. First, an element must be temporarily placed into document.body for all styles to apply correctly. Second, it must repeat all of the hierarchy it was in, which requires to break/duplicate a component encapsulation in your code. Third, in a narrow-width situation you simply cannot guess what surrounding containers would do to the effective width/height based on an intrinsic geometry. Not even speaking of cpu/battery issues, these three alone make it possible only in theory. And no, there is no library for that to "just work" in your project.

I am sure I could discover an equal "simple" example that is easy in CSS but difficult/impossible in GTK.

I doubt it, really. I mean, you could find something for base gtk (which is already out of reach compared to css in ui geometry, because it was done for it), or for the fact that gtk is not a networking engine, but it is just a bunch of predefined containers, calculation phases and signals in C. It is easily extensible in a native way and hides no knowledge about how everything looks or works. Gtk is an example of how you expose distinct particles, pre-implement few useful combinations, and then users build a universe with them. Css is an example of ritualistic black box that hides almost everything about its geometry and requires a non-trivial effort for really basic things. E.g. in css, you have to struggle with dumbest things like a one-pixel vertical scroll in a single-line input. My complaint is not "css is not gtk-like", it is "css is incomplete and unreasoned AF in its own model".


> It is nothing new and was propheted in bla-blah paragraph.

I don't think we can have a reasoned discussion about this if you're going to write off any contention as "bla-blah," so I'm disengaging.


It was my bla-blah, so please read it as etc-etc, and if you feel offended by that and by my tone, I apologize. But it would be fair if you also excused my huge disappointment after following these exact ideas, spending days and finding out that they do not work or are completely non-viable in vivo. If any css loving guy implemented the puzzle above (and a half of other common issues) as a library that could be simply added to a job-grade project, they are welcome to share it (or sell, such an easy $$$). I've been in these discussions and done what was suggested, that's why I listed all these reasons word by word, before anyone had a chance to repeat them, and that's where my criticism comes from. I just cannot sit here and silently watch how they praise a thing that is not remotely as good as is claimed. How many man-centuries have to be spent until we all admit the undeniable?


> most people who do front-end don't want to spend a day learning it.

Can you link to some good resources? I've read "CSS The Definitive Guide" by Eric Meyer, "Eric Meyer on CSS" (also by Eric Meyer) and "CSS Zen Garden" and I still can't get CSS to do anything useful and always resort to table-based layouts because they work.


I don't know if there is a single perfect resource out there, but the thing that helped me the most was understanding CSS as a shift from programming with an imperative mindset to a declarative mindset. Treat CSS as a medium for expressing 'what you want' instead of 'what to do.' My guiding principle is that "less is more" and if you find yourself writing a ton of super-specific and messy CSS, it's one of two scenarios: there's an easier way to do it, or you have a very picky project manager who wants things to be pixel-perfect to the mock-up. If it's the latter, you have my sympathies.

Focusing on the box model is important because it sets the right overall mindset for working with CSS layout. At the risk of being too patronizing, I would highly encourage everyone to at least read the MDN article on CSS basics[0] just to set a baseline for CSS terminology, the idea of the box model, and a few other things.

You should then read more detailed documentation [1] on the box model and start to get a feel for how it works in depth. Most pedestrian "spacing issues" should be solved at the level of adjusting margins and padding.

The other arm I mentioned was specificity, and this tends to be where a lot of folks get caught asking why their rules aren't applying and those sorts of issues. The documentation is fairly 'academic' but worth a read-through[2].

MDN overall is a great resource for a motivated learner, but unfortunately I don't have any 'CSS the right way' sorts of articles in my hat at the moment. Maybe others will post some.

[0]: https://developer.mozilla.org/en-US/docs/Learn/Getting_start...

[1]: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_...

[2]: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity


css tricks has nice flexbox and grid guides that also have helpful pictures to show what the end result of CSS is:

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

https://css-tricks.com/snippets/css/complete-guide-grid/


You sound a lot like me. I'll use CSS for colors/fonts/theming/separation and then do layout with tables :) . None of the stuff I work on is really all that complicated, so "tables are slow" just doesn't come up because the pages aren't large at all so 5ms vs 50ms doesn't matter.


Using tables for things that aren't tables is terrible for accessibility.


This really deserves to be echoed. Accessibility just isn’t taken seriously by web developers in general and it makes me so sad. If it’s mentioned at all most of the time it’s an afterthought and they try to shoehorn it in on existing code as an afterthought which just makes things worse.

I want to implore everyone on HN to not be one of those people


Why is it so bad for accessibility? I don't know much about web design.


Browsers, and therefore things like screen readers, see table elements as collections of tabular data. Using these elements for layout or design will cause a confusing and useless interpretation for people using a screen reader or analogous tool.


I like doing short challenges to learn and solutions to peak at in case I get stuck.

Andy Bell posted front-end challenges for a while, here's the archive: https://piccalil.li/category/front-end%20challenges%20club/

Codepen hosts challenges every week. They aren't always CSS focused but many of them are. https://codepen.io/challenges


Which editions did you read?

Many of the css options that make complex layouts more palatable have only been commonly supported more recently. (flex-box:2015 , grid:2017, newer units:2010)


I don't remember the specific editions, but it was a long time ago - long before flex-box and grid were around. Still, back then, people could work magic with CSS using floats and positioning and such, and I couldn't make any sense of it. Maybe it's time to pick up a more up-to-date book on CSS and try again with the modern timesavers.


While I think this is definitely a useful foundation, things get a lot more complicated quickly once you jump into a large site's stylesheet(s).

Why isn't this element the size I specified? Or why is there a tiny amount of scroll overflow here when I specify overflow-x hidden? What does vertical-align do and how does it work when inline and inline-block boxes are in an inline flow? etc. etc.

So I would add that the next frontier after learning the proposed foundations is learning how the browser actually determines box sizes and layout, and I think this is difficult to understand, mainly because it jumps straight into the spec, or worse, your browser's layout engine specifics.

https://www.w3.org/TR/css-sizing-3/#auto-box-sizes for instance is a nontrivial subsystem that a CSS dev will easily run into when nesting flex containers, and I think the standard box model of yore wasn't really written to help grok these concepts.

Edit: one particularly hairy explanation from the spec I recently ran into while trying to deepen my understanding of the box model:

"Except for table boxes, which are described in a later chapter, and replaced elements, a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes."

Not saying this is relevant for the average use case, but I believe even something like the box model is a day-to-learn-lifetime-to-master kind of thing.


You could probably write an article that'd be very often read if you teach CSS from this perspective.


I've wanted to actually! It's become almost a meme that CSS is hard and a badge of honor to be ignorant of it, but it's not that bad. I will concede that there are some annoying design decisions (like margin collapsing) but overall, I think it's a well-designed and evolving solution that has stood the test of time. That we've been able to so easily add things like flexbox and Grid to it in response to the changing needs of the web is kind of a testament of how well CSS modelled the problem of layout. Learning box-model and cascading will let one solve 90% of common CSS problems people encounter just from first principles.


While I agree with the main thrust of this comment; I don't think I'll ever "earn a true appreciation for CSS". Even the most careful application of class naming guidelines eventually creeps into specificity battles, and you cannot predict exactly what a line of CSS will do until it's actually applied to an element.

However: it's unclear to me what a better solution would look like; and it's clear to me that nothing better would ever be so much better as to "beat" CSS.


Where is the best place to learn CSS from a more foundational/complete perspective? I took freeCodeCamp's responsive web dev course but still find myself googling a lot of "how to do x in CSS"


Yes, this exactly. Spend no time trying to understand something and then claim that something is hard to understand. No, sir, throwing stuff at the wall and hoping some will stick is not a good way to learn. Alas, this approach is becoming more and more prevalent with everything, not just CSS.


For me I think CSS is hard to understand mostly because the underlying concepts are low level and designed to accommodate ALL POSSIBLE rendering scenarios, not just "I'm putting a website on this laptop or phone screen".

CSS is able to target print and all manner of other different scenarios and needs. It's inherently complicated because it's very flexible and accounts for all kinds of use cases.

The problem is you don't need all that power most of the time, but it's there. To understand CSS you have to understand a lot of underlying concepts about layout and web page structure. People feel like "Why do I have to remember all these arbitrary rules?!". I sympathize - and sure a fair few things are arbitrary and never changed due to not breaking existing code - but most of the rules are not arbitrary, they just serve a bigger world than what we might be dealing with as web devs.

In the end I prefer to think of CSS as a powerful programming language that gives me lots of _primitives_, not a framework with a bunch of out of the box behavior that matches my narrow needs. If you want those, they are out there of course.

But yeah. CSS is hard and it takes study, practice, and time to be good at it. I think half of the time we struggle with CSS it's because we expect that it is "easy" and that it should cooperate without us investing time in learning it. It's written in short lines that look like plain English. It should do what we expect all the time, right?


CSS is able to target print

Only an old textual part of it, e.g. grids cannot page-breaks. It is far from "flexible" and just "out there if you want". May I ask, do you even media print? Because every time I have to do unusual un-mainstream thing in css, I can bet that it will not work and make a net profit.


CSS is able to target print: https://www.princexml.com/


I think it's because of the combinatorics of it and it's compounded by the specificity system, the size of the vocabulary, and no built-in compiler.

The combinatorics are tough for our lizard brains to reason out. If you don't have a strict set of rules for your CSS then you end up with a mixture of element rules, class rules, and id rules, and the combinations of these can get hard to hold in your head. Having compound styles doesn't help at all because it's easy to not realize you're setting a style accidentally.

Then what happens when there's a collision? The specificity system is supposed to sort that out, but without learning the rules there's just no way to intuit them. When I'm struggling with getting something just right and some library CSS is overriding my local CSS it's always the specificity rules that are at fault.

The vocabulary size is enormous. It's unclear exactly how many properties there actually are, but the most authoritative answer I could find was 522. That's a crazy number. And yes, that treats `margin` and `margin-left` as two separate properties, but they're still in there. By comparison there are 53 reserved words in Java and only 33 in Javascript. It's possible for a mere mortal to memorize these.

And finally there's no built-in compiler. Yes, I know about Sass, but that's not much more than a macro system; a useful macro system, but still just a macro system. A lot of us use compilers as our grammar and vocabulary checkers. If I do mis-spell a word in Java the compiler usually errors out and I'm forced to fix it. But if you mis-spell a property in CSS it's happy to just ignore it and you spend several minutes trying to figure out why your change did nothing.


> By comparison there are 53 reserved words in Java and only 33 in Javascript.

Where did you find these numbers? I'm trying to find them but I can only find the Ecmascript and the number appears way higher


For Java I used https://www.thoughtco.com/reserved-words-in-java-2034200 but Wikipedia lists 51. I'm too lazy to actually diff it.

For Javascript I used https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... and fudged the numbers a bit. There are future reserved words, but I didn't iinclude them because there's no point in memorizing them. Now that I look in detail that list also doesn't include "true", "false", and "null".


39 listed here https://tc39.es/ecma262/2020/#sec-keywords-and-reserved-word...

51 listed here https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.htm... with a bunch of non keywords listed below, of which true false and null are also reserved


I think it really has more to do with the fact that it was originally only designed with print flow in mind. Like laying out a magazine with columnar text.

When it was initially designed there was an expectation that structural layout would happen outside of it and then you'd flow your text and other inline/block objects within that.

Most everything since then has just been about trying to get css back to the structural flexibility people had in 1996 with tables, while still trying to keep the flow flexibility css brought (and then, as you say, adding on media-type flexibility). It's not a surprise this turned out ugly.


CSS is declarative and not imperative. A lot of people have issues with a different kind of programming.

Also the "cascading" nature of CSS makes it hard to reason about.


The differences in how different engines/platforms behave definitely does not help when doing any non-trivial layout.


I think a _lot_ of this is standardised now in the vast majority of browsers people use.


Depending on what space you work in and what consumers you have “majority” is not acceptable.

Safari and IE are the big bugbears in my experience.


True - I'm lucky not to have to consider versions of IE prior to 11 on most projects I work on, and I can usually get things working there, although there's a flexbox thing that I always forget with IE11 that catches me out.

I stand by my comment if you don't have to do IE < 11 though.


Even just IE11 is pretty bad given the state of grid and flexbox on IE11.


Yeah, grid is pretty much not worth it imo, as you have to do so much differently. You can make flexbox work though.


The environment for CSS isn't nearly as "standard" as you might think. Even though WebKit and Blink are the majority engines on mobile there's tons of combinations of versions, screen sizes, and aspect ratios. Trivial layouts are easy but more complicated layouts can be very difficult to get working right, let alone looking right, across browsers/platforms.

The problems are often solvable but not necessarily easy. The difficulty is compounded by the heterogeneity of the Android space.

It's great the majority browser engines follow the CSS standards but a lot of problems aren't bounded by the accuracy of the implementation.


Without wanting to diminish what you're saying, which makes a lot of sense - I feel like we should be trying to avoid complex layouts on mobile - at least in the browser.

And you're right that screen sizes can mess stuff up, Firefox/chrome mobile view on devtools doesn't always tell the full story... Got something working there and it was broken on my actual phone.


This is me. My brain chucks it in the bitbucket as soon as the project over. 95% of my time is in firmware with the occasional web page/javascript to update and I google and It All Starts Making Sense, and then the project is over and I don't touch it again for 2 years :)


One reason it is hard is that the effect of CSS rules depends on their order. Imagine if in your JavaScript you write 5 functions, and depending on the order you write them in causes them to have a different effect.

https://medium.com/@panuviljamaa/why-css-is-difficult-a2cdf0...




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: