Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: Is it just me, or is CSS too damn hard?
499 points by napsterbr on Jan 28, 2019 | hide | past | favorite | 340 comments
Hey HN,

I'm a seasoned backend developer and systems administrator, with over 10 years of full-time programming experience. I've worked with anything from Assembly, C, Rust all the way to Python, Erlang, Elixir, PHP, Haskell, Lisp, Clojure.

When it comes to frontend, I have used React, Vue.js, ReasonML, Clojurescript and Elm extensively, and I know my way around web technologies in general. However, ever since I first started programming, I was NEVER able to get the gist behind CSS. I can't center my divs properly. I can't say "hey, CSS, this is the parent div, and all child divs must obey its size". I can't do anything basic on CSS without turning for help.

Incidentally, but very likely related, I always failed to have any glimpse into how design works. I have no idea which colors "go" with which ones, and pretty much all fonts look like the same for me.

I'd like to know the experience from fellow programmers. Is CSS an "art" thing? Is it common for other developers to have issues with it, or is it just me? Is there any material out there that made CSS "click" for you?

1) CSS is for implementing designs; being able to use it doesn't require design sense for things like colors

2) I'm fascinated by the fact that so many of my fellow programmers - often the smartest ones - have so much trouble with CSS. I'm not sure exactly what the reason for that is, though I did write an article hoping to address it in some capacity: https://css-tricks.com/css-is-awesome/

I think part of the problem is that many programmers, who like things to be orderly, see CSS as arbitrary and chaotic. Here's the biggest point that I think has to click: CSS isn't a programming language, it's a constraint language. The browser has lots of default, complex behaviors that drive layout, and whereas in a traditional programming language you tend to "build up" from nothing, CSS is more about paring down and guiding that automatic engine with as few statements as necessary. You tell the browser exactly what your layout requires, and the browser figures out how to flesh that out into various contexts and situations.

Personally I think CSS is beautiful: it's stateless and declarative, and it allows you to talk about huge swaths of entities in very general terms, gently paring down their avenues of expansion until the possibility space aligns with what your application requires. It's incredibly elegant once you get the hang of it; I sometimes find myself wishing I could use a similar paradigm for talking about objects in other contexts.

CSS is not a real constraint language. If it really were a constraint language, it would be better. There's no constraint solver. Just a bunch of rules applied sequentially.

I'd like to have a real constraint system, like the one in Autodesk Inventor sketch mode. You select two things and apply a constraint - parallel, tangent, horizontal, collinear, etc - and the constraint system enforces those constraints. The layout GUI tells you if you've created a conflict. CSS solves an easier problem, and not very well. It's such a mess that no one can attach a decent GUI to it.

Amusingly, tables came back. But they're called "layout tables" now, to avoid embarrassment. Trying to do 2D layout with 1D constructs (the "float" and "clear" era) was just silly.

> Amusingly, tables came back. But they're called "layout tables" now, to avoid embarrassment.

I'm not really sure what you're talking about. Tables were bad because they were too rigid and weren't designed for layout purposes; they do still get used when you want to display an actual table. Maybe you meant CSS Grid?

> Trying to do 2D layout with 1D constructs (the "float" and "clear" era) was just silly.

The float era was certainly a dark time, and I'm glad I came into the field on the tail end of it. It was a hold-over from CSS' document-focused origins. Today we have flex-box, which quite elegantly serves 90% of people's layout needs, and CSS Grid which fills in the rest. For the record, flex-box is a 1D construct for doing 2D layouts, and it does the job fantastically.

Your Autodesk comparison belies a fundamental misunderstanding about the nature of the DOM - it is, to its great advantage, a 1D space which flows into a 2D shape. In fact, this was the great flaw with using tables for layout in the first place. By making the content fundamentally 2D, all it could do to respond to different screen sizes and different browser window resizes is stretch. But you don't actually want your layout to be totally percentage-based. You want your content to wrap and flow to make the best use of the available space that it can, with no assumptions about screen size or ratio. The web is 1D because text is 1D. As text flows in lines, within containers which may be different shapes and sizes, so does the entire document model. This is profoundly powerful. Modern CSS gives you the tools to make select aspects of your layout work differently - yes, even in 2D ways - but they're best used to shape and guide that fundamental flow instead of replacing it.

> Tables were bad because they were too rigid and weren't designed for layout purposes; they do still get used when you want to display an actual table.

And when you have to implement a email design someone gave you who think it’s more important to have it look a certain way then to implement it reliable.

That’s because the rendering engines in email software are crap, not due to a deficiency in CSS - I think Outlook still uses Word’s HTML renderer and even Gmail doesn’t support everything.

In all fairness that's probably a good thing. God forbid if emails today were like the rest of the web, hijacking the scrollbar, constant popups to register, like and subscribe.

I like my emails like I like my actual mail; text and maybe the odd image.

> hijacking the scrollbar, constant popups to register, like and subscribe.

Those are JS related, I don't think anyone is asking for renderers to allow that. But proper CSS support would be nice.

I've got to disagree. Your preference for text emails doesn't mean those who do want rich-text or HTML should have to put up with crappy rendering that requires specialist developers.

I don't understand why HTML payloads can't just be loaded in a (streamlined) browser pane?

They are; it just tends to be a really crappy browser pane that isn't based on (and therefore kept up to date with) any major browser, so writing the HTML and CSS is like being transported back to 2004

Dunno why Gmail doesn’t support everything. It’s in a modern browser already!


Agreed. Rendering HTML and CSS in a vaguely standards-compliant way is surely a solved problem by now.

Javascript should stay firmly blocked though.

The DOM is actually a tree. I'm not sure if it's correct to call that 1D. Similarly, the web is a graph, definitely not 1D.

I'd even go as far to say the text on most webpages isn't even linear. It's either a tree (like this comment page) or a fragmented collection of text chunks.

The webpage that strictly consists of one linear stream of text is very much the exception. And it also happens to be the exception that CSS never had problems with.

What you seem to be saying is that paragraphs are 1D (which get wrapped and flowed in layout), therefore entire webpages are 1D (no) and therefore the web is 1D (definitely not).

Or maybe you could say that most viewport representations, scrolling vertically, are 1D. In which case CSS should be the tool that converts the tree or graph of content into this semi-1D viewing representation.

I agree that this mismatch is where CSS finds a lot of problems.

You know your comment in hacker news is rendered as a table :)

> Your Autodesk comparison belies a fundamental misunderstanding about the nature of the DOM - it is, to its great advantage, a 1D space which flows into a 2D shape.

What's the advantage? The screen is 2D space. Layouting is a 2D problem. Images are two-dimensional. It's simpler to start from 2D and make 1D content fit that space than the other way around.

> The web is 1D because text is 1D.

That made sense in the very early days of the web, now it's just a historical crutch. I fully understand why things are the way they are, but that's orthogonal.

> What's the advantage?

The same content reflows to different 2D spaces

Flow-like layout is just a sub-problem of 2D Layouting. Having it as the only way to do layouting (besides tables) has proven a nightmare to work with. That's why you got Flexbox (and now Grid).

Flexbox is a layout system for 1D content. CSS Grid is for 2D content, but it's designed in such a way that it can remain responsive to different container sizes, unlike <table>. This actually makes it pretty complicated and unwieldy, because - once more for the people in the back - doing a responsive layout in explicitly 2D terms is a very weird thing to be doing and usually isn't what you actually want.

> Flexbox is a layout system for 1D content.

An individual flexbox container is one dimensional. To get a 2D layout, you nest rows and columns.

> ...doing a responsive layout in explicitly 2D terms is a very weird thing to be doing and usually isn't what you actually want.

I have no idea how you would come to that conclusion. To me, a "responsive" layout is one that adapts to the viewport size. The viewport is 2D. This is a 2D layouting problem.

A subset of that problem is concerned with fitting content of a fixed viewport width to a variable height, i.e. your classic web site. That's what you may call "1D content". Once you're trying to get a layout that adapts to both viewport width and height (i.e. an ordinary application), CSS can get quite ugly.

> a "responsive" layout is one that adapts to the viewport size

Precisely. More often than not, accomplishing this requires more than just squishing and stretching. Panes have to wrap around at certain points and the layout has to shift. You can do this with a bunch of special cases, but the better way is to let the rules of flow work for you. For example, you can have a flex child "grow to fill available space but have minimum size", so that if less than that minimum size is available it wraps around to the next line. You want to talk about your layout in terms of a series of sections, not a fixed grid. This was impossible with <table>; CSS Grid provides tools for special-casing these things, but it's still way more obtuse than letting them occur naturally.

Humans can only focus on a single thing at a time. As your focus goes through any content, it necessarily follows a 1D path. HTML, eint Text, is also one-dimensional.

CSS, as said before, transfers this 1D information into the 2D representation on a scree, or a printout. Or it leaves it allone, or rearranges the 1D stream, for a different 1D representation to a screen reader.

This has nothing to do with being a “historical artifact”. It’s a fundamental idea of communication theory. But maybe it helps you to see its value if I just mention that thinking a bit about such theory will make it far easier to you to create designs on the vastly different devices, from smart watches to Times Square screens connected too the internet now.

> As your focus goes through any content, it necessarily follows a 1D path

No. Not at all. Almost never. Your brain is a chiefly parallel processing device, no matter how much you delude yourself that "you read text in the order it was written" and other such nonsense...

It's widely known that this is not even how people read text. Even when you listen to music, and nothing is more 1D than sound, your brain chops it up and rearranges in multiple concurrent variants trying to "do the shazam thing" of identifying what else it may be even a bit similar to even if you don't realize it...

"Following a 1D path" through content is what you do when you either want (1) to reliably communicate at the lowest imaginable common denominator with people with unknown and presumed low skill and intelligence (eg. "talk to a customer" or "talk to the bank teller") or with people so mentally different from you that they are close to being a different species (eg. "talk to an accountant or lawyer" or "send a binary encoded message to maybe be received and decoded by an alien civilization"), or (2) you actually want to force a particular interpretation of the sequence and causality of things to people (eg. "explaining history to people" or "telling an educational story" or "manipulating people" or... "selling stuff to people").

All the other communication, and more like the only part of interpersonal communication that I find interesting is non sequential, it's about working with information that can be rearranged in multiple equally valid sequences and interpretable in multiple possible causality graphs. Think maps and painting. Or a textual description of a stack of maps etc.. Or computer code as it actually gets executed on an even slightly parallel machine (not "as it stays written code in a text file", that's also a "lowest common denominator representation" bc human and computer brains are so different).

This one dimensional curve of focus throughout a 2D page will be different on each viewing and for different people.

That's why the 2D layout is important because it can help assist or guide the creation of this path. For many pages there is no fixed "proper" path through the content even though the DOM is necessarily in some order.

> Amusingly, tables came back. But they're called "layout tables" now, to avoid embarrassment

I'm not sure exactly what you are referring to, but there have been some misunderstandings regarding tables. Before CSS, <table>-tags were there only way to control the layout, but since CSS 2, it have been possible to achieve the same kind of layout which display:table in CSS without having to abuse <table>-tags. But there is nothing wrong with using <table> when they are semantically appropriate.

Recently CSS have gotten display:grid which is way more powerful than table layout ever was.

Float and clear was never intended for general layout. They were invented by Netscape back in the day to allow text to float around images. Float/clear-hacks became a necessary evil in the dark age before IE supported display:table.

You cant really blame CSS for IE not supporting critical parts of the spec, since this was part a deliberate strategy by MS to "kill the web". Luckily this strategy failed and MS changed their minds.

>Before CSS, <table>-tags were there only way to control the layout //

As an historical aside: that's not quite true to my recollection.

p-elements had width, height (and possibly other attributes, margin, border?). And empty <p>, hr, br(?), were used for rudimentary layout? Then there was color, bgcolor attributes; and font tags. Not sure when <center> came out?

This https://www.w3.org/Style/CSS20/history.html is probably much better than my recollection. I started making webpages/email-circulars about 1994-95.

I think you remember wrong regarding P. P never supported width or height or margin before CSS. With FONT-tags and other presentational html you could control colors and typography to some extent, but the only way to control white-space and sizes and margins before CSS was to use tables, typically combined with "spacer gifs". E.g you wanted to indent a paragraph 17 pixels, you created a table with two cells and put a 17 pixel wide transparent gif in the first cell.

You're probably right.

However, these (below) suggest that HTML3 spec at least had layout attributes like align, wrap, clear on p; and had width for hr (it was a Netscape extension on HTML2 too, apparently).

Also since HTML2 textarea had cols and rows attributes. There was also default styling on blockquote and lists that have indents. \&nbsp; was used for horizontal "alignment" (tabs); code and pre too. I'm going to say there was some layout "tools" prior to CSS.

Quite interesting to read the specs now, at the time I was just groping around in the dark by myself, learning by reading source of live sites. Would have probably been much easier if I'd known a spec existed!

https://www.w3.org/People/Raggett/book4/ch02.html -- MSIE promise to include CSS Nov '95.

http://marc.merlins.org/htmlearn/html-ref.html#P -- HTML3 spec, I think?, dated 1995. Go up one level to find HTML2 spec.

Further aside: spacer GIFs I never came across until about MSIE4, avoided them myself, too much of a purist. In the Mosaic vs Netscape Navigator days I don't think anyone had started to attempt pixel-matched designs across different UA??

> It's such a mess that no one can attach a decent GUI to it.

A very good point. My guess is that we could let designers do a lot more and developers do a lot less, if it wasn't for that impedance mismatch.

> CSS is not a real constraint language. If it really were a constraint language, it would be better. There's no constraint solver. Just a bunch of rules applied sequentially.

> I'd like to have a real constraint system, like the one in Autodesk Inventor sketch mode

Here you go: https://gss.github.io/

> GSS reimagines CSS layout & replaces the browser’s layout engine with one that harnesses the Cassowary Constraint Solver

Here’s the [parent project][1] and the old [research page][2] at University of Washington. The most recent implementation is Rust in 2018. The JavaScript repos are inactive. I’m not sure if that’s because the algorithms are considered complete or because the project is dormant. One of the researchers is no longer at UW and the other is an emeritus professor, so semi-retired. The claim is Apple uses these layout algorithms in Interface Builder.

[1]: http://overconstrained.io/

[2]: https://constraints.cs.washington.edu/cassowary/

Too bad. That was the right idea.

With that, we could have Dreamweaver type layout working again.

That project seems to be more about the math than making layout easier. That's a problem with many academic projects. One thing I've liked about Autodesk products is that they often have complex math inside, completely hidden from the user. You see that in the CAD world, where the physical universe has to be modeled.

> Too bad. That [constraints] was the right idea.

In theory, yes.

And the theory certainly can work beautifully as intended in practice.

However, developers and designer tend to have huge problems with autolayout. Specifying what you want visually as a set of linear constraints is challenging. It is very easy to get very surprising outcomes, easy to overconstrain and underconstrain.

It's a very big sledgehammer aimed at some very delicate eggshells. Not just when it comes to understandability, but also when it comes to runtime performance.

You make a good observation that:

> The browser has lots of default, complex behaviors that drive layout, and […] CSS is more about […] guiding that automatic engine

I think for most people who struggle with layout, what they really need to learn is what process the browser uses to lay out content, so that they can then turn their mind to how to guide it. Instead, I've seen hardly any CSS tutorials / documentation that start with a description of the layout algorithm and what hooks it provides via CSS; they all start from the meaning of individual CSS declarations, which are never the full picture.

I think there's really room for teaching layout from the other end (the following is the browser's algorithm, and here's what can influence it), for people who think procedurally.

Understand the browser and learning how to 'think in CSS' is the biggest trick I've found to being able to work in CSS efficiently.

That, and experience. Very rarely do you actually encounter genuinely new layouts in CSS, so with experience you just end up building in your head your own little 'component library' and pattern match designs to that.

Good comment.

CSS is actually pretty simple, as long as you start with the smallest elements and work up. It becomes a nightmare if you try and address everything individually. It’s not really a programming language, but a series of guidelines.

I’ve seen this simplicity actually throw developers as they’re used to something much more complex and systematic.

Preprocessors like SASS are great, but I wonder if they’re designed to complicate CSS a bit so developers feel at home.

Pixel perfect design is totally possible, as long as the designer is aware of the constraints and opportunities of the medium they’re working in.

Pixel perfect is not possible in HTML/CSS. Stop spreading this.

But it is very possible to make websites look very good and inline with what was designed.

But good luck making an input, button and select the same height. It's just not going to be pixel perfect.

What is pixel perfect in your browser isn't in others.

But what designers should now is it doesn't matter as long as it looks good for everyone.

> Pixel perfect is not possible in HTML/CSS. Stop spreading this.

It absolutely is possible—we used to do it all the time back in the table layout days—but it is not desirable. They are inherently fragile (often users can break them just by changing the default text size), and they do not adapt to different screen sizes very well.

The key part of my point was "as long as the designer is aware of the constraints and opportunities of the medium they’re working in."

Designers coming from print often get caught out when designing for the web as they tend to think of a webpage as a fixed layout, rather than a flexible system of components.

It's also important to understand where the design and development budget should be effectively spent. For example, unless there's a real business or usability reason for doing so, there's little point in trying to custom-style form elements like selects as doing so is difficult and time consuming and system defaults look better and provide a more consistent experience.

We demand pixel-perfect accuracy at work between design and code – but the developers must approve the designs first to confirm that it's achievable.

I guess it comes down to what we define as 'pixel perfect'.

> I guess it comes down to what we define as 'pixel perfect'.

When the customer hears "pixel perfect" they don't think "different on different browsers and on different OSs and on different devices", they think "the same everywhere".

That should be one of the first conversations had with a client. It's all about managing expectations.

During the pitch meeting we'd point at the big TV in the meeting room, their laptop and smartphones and (maybe) watch, and explain that while we could make their site look great on everything, it wouldn't look the same.

Sometimes the target is a known browser version on a known OS (eg. intranet sites). Those are a lot simpler and (arguably) fun to make.

> But good luck making an input, button and select the same height. It's just not going to be pixel perfect. What is pixel perfect in your browser isn't in others.

It's... actually incredibly easy to do that. You just disable the browser's default styles for those elements and then set their height explicitly.

There is a certain interpretation of "pixel perfect" which, I agree, isn't really feasible or worth trying to achieve, and that's when it comes to layout. You can hardcode the dimensions of "atomic" elements like buttons and inputs all you want, but if you start giving hard pixel widths to containers that should be adjusting their size according to their content and surroundings, you're going to get yourself into trouble real fast. I think designers these days have mostly started to grasp this, though.

> But good luck making an input, button and select the same height. It's just not going to be pixel perfect.

Sure you can. Just see how Bootstrap does it.

It is true that for a long time, input controls were rendered using the native platform controls, so there were are a lot of differences and limited styling capabilities. But these days all browsers (as far as I am aware) use the browser rendering engine for input controls, and they are fully stylable.

Some preprocessors definitely overcomplicate things, but I consider SCSS to be essential because of three features:

1) Nested selectors

2) Imports

3) Variables

#3 is now solved/being solved natively, but I couldn't live without #1 and I'm not really sure why it hasn't been added natively yet

I don't think sass/less complicate this, they just bring in some familiar and useful elements.

How much further could css have gone on its own had it supported variables and functions from the get-go?

SASS is incredibly helpful so I think it is worth the pain. It is game changer, and still it can be learned in a few hours. Before SASS, managing z-index across a whole template or changing colors was a nightmare.

(If you are old enough, you may have come across one of those WordPress templates in which they crammed PHP $variables inside inlined CSS. #goodolddays)

Beyond the immediate issues of "what rules do I use to make this thing look this way", the cascade can also make large-scale management and code reuse challenging. It's sort of like object-oriented inheritance, except the definitions and instantiations live in totally different places, and the top-level object properties are defined by browser manufacturers, or possibly end-users. Without some sort of build system, static analysis is difficult so it's hard to say if a definition is being used or not to know whether changing it will break something somewhere else.

People have developed some techniques to mitigate these issues, but many are unintuitive and don't follow naturally from "make this thing look this way".

> It's sort of like object-oriented inheritance

With the key difference being that there's no rigid structure to it at all, much less a strict-subset hierarchy. It's really more like structural object types, which can be easily composed, than OOP classes. It's set theory, rather than taxonomy.

> Without some sort of build system, static analysis is difficult so it's hard to say if a definition is being used or not

This can be easily solved with good project organization. At my day job I maintain a codebase with a couple hundred SCSS files, which are on average a couple hundred lines each. We've organized things well enough that the cascade is a non-issue, and "leftover" styles from an element that's been removed are a rare occurrence. All you have to do is closely mirror your UI components, pages, fragments, whatever, with the relevant CSS files. Then if you add or remove something in the markup, you add or remove it in the corresponding styles.

> don't follow naturally from "make this thing look this way"

This is precisely the problem; programmers come from a background where they think in terms of "make it do this thing", and they try to translate that to "make this thing look this way". That's how you create supremely fragile CSS which is impossible to safely make changes to. Instead you should be thinking in terms of, "make it behave this way in the general case, relative to what's around it".

"This can be easily solved with good project organization"

"All you have to do is closely mirror your UI components, pages, fragments, whatever, with the relevant CSS files. Then if you add or remove something in the markup, you add or remove it in the corresponding styles."

Super simple. It is what it is and powerful etc, but simple? I have given up. I just use the minimum web tech to get by.

Yeah, "remember to keep these two files in sync by hand" is the opposite of simple. Like c++ header files, without the benefit of a compiler that will complain at you when you get it wrong.

> many programmers, who like things to be orderly, see CSS as arbitrary and chaotic.

It is arbitrary and chaotic. It breaks the principle of least astonishment.

CSS itself isn't a bad idea but less, scss etc. showed that it was lacking some features you desperately want and in the meantime just styling the web with "a little CSS" is not enough anymore.

You have a shitload of display sizes to support on the other hand and strange behaving browsers which aren't truly standardized on the other. That makes adjusting your CSS to all of these a pain in the ass even if you like fiddling around with styling (as I basically do).

I don't want to adjust my margins, paddings and fonts and then restart from scratch because f Apple decided they will do everything in Safari completely different from the rest of the browsers just to show how special they are.

I'm also sick of building selenium grids with a mac mini in them just to also test this piece of ... "ingenuity" ;-)

So nowadays I just go with a framework with sane defaults and no-hassle usability and when I need something special I ask people who don't do anything but CSS the whole day.

Without more standardization it's not a domain you'll be great at when you don't specialize in it - which means you got to invest a lot of time to master it.

Imo as long as you're not targeting internet explorer, things are pretty consistent these days. All modern browsers are now "evergreen", which means they update automatically and silently, which is the best thing in the world for web devs. The only inconsistencies you get are some having implemented new features before others, not really outright contradictions, and even that isn't a very big gap these days.

> I'm fascinated by the fact that so many of my fellow programmers - often the smartest ones - have so much trouble with CSS. I'm not sure exactly what the reason for that is

I will demonstrate why.

First, think of all the tools that you use that require a text interface. That may include a programming language (python, ruby, javascript, etc), a command line shell (bash, fish), a database client (mysql, psql), a configuration script language (systemd, nginx), etc. In all these the text based interface is the language used to speak with the underlying engine. Now, these languages must be designed and there are good designs and there are bad ones. If the language sucks, people can generally just choose to go with a competing alternative that has a somewhat more accommodating syntax. But CSS is a monopoly. We're stuck with it. For many of us it's a really shitty language that is guaranteed to live on, no matter what, just because, well browser technology.

Ok, enough ranting, on with my demonstration.

For this I'll take CSS positioning as a case. Let's say we decided to design a domain language to express how items on a web document must be placed. We could start from the perspective that when repositioning an element it should always be relative to some point of reference. That starting point could be the element's default position, or it could be the viewport, or it could be an ancestor element. From there we could devise some simple rules to express this.

To move an element you must first declare where you're starting from. For example moving with respect to its "default" position in the normal flow of the page would be declared as such (could be made optional too):

    position-reference: default
To move with respect to the viewport, you would start with:

    position-reference: viewport
To move with respect to an ancestor (and possibly even a distant cousin element):

    position-reference: parent  /* immediate parent     */
    position-reference: div     /* first div ancestor   */
    position-reference: root    /* the document         */
    position-reference: <some-syntax-to-navigate-ancestry>
From there you could add a number of extra properties to fine-tune some specific behavior. For instance if you need to maintain the space that the element was occupying previously:

    position-maintain-gap: true
Or to prevent scrolling when the item is relative to the viewport:

    position-scrolling: off
The above patterns might seem vaguely familiar to some. That's because I've just described "relative", "sticky", "absolute" and "fixed" positioning (albeit with some added possibilities). As someone used to interact often with text-based interfaces, if I didn't know CSS, the above would be an approximation of my expectation of its rules for these concepts. This is how I understand them and how I anticipate a good domain-specific language would allow me to express them. It's precise and descriptive, but more importantly it's not too idiosyncratic, meaning that I'm not making up terminology that is so foreign that occasional users will have to be given a refresher every time they need to use them.

Now, contrast that with how these concepts are actually expressed in CSS. Instead of the different patterns being simply given as combinations of the above simple options, as I've demonstrated, they're rather given as ready-to-eat dish with labels such as "relative", "absolute", "fixed", "sticky". The whole thing is then sprinkled with ifs and buts. This "simplification" doesn't always have the intended effect though, and many many people are just confused when first trying to understand positioning.

To add to your last bit: the fact that "absolute" is relative to the closest non-"static" parent is a sign that things aren't as decoupled as they seem. Same with how "overflow" mixes scrolling and clipping.

CSS is a badly specified mix of a unidirectional constraint system, a typographical system, a compositor and a declarative transition/animation system.

While there is by now a CSS: The Ok Parts, there are no good parts because they hang off the bad parts.

Some of the names are unintuitive, sure. Though I don't think the ones you provided are in particular; I think your distaste for those is subjective. But it's really not hard to learn the names for concepts which themselves make sense (at the beginning, perhaps, but not for someone willing to put in a modicum of effort).

Many of the worst parts of CSS, and even JavaScript for that matter, come from the need for backwards-compatibility. There are literally websites from the 90s that still render and function perfectly fine in a modern browser. That's an amazing property of the web, and I'd say it's worth the tradeoff of living with a few questionable decisions of the past. Plus, we continue to rapidly build new features on top of those backward-compatible ones, so it's not like we're truly held back by them. Modern CSS and JavaScript are barely recognizable from the 90s versions, but they still contain those as a subset.

> Some of the names are unintuitive, sure. Though I don't think the ones you provided are in particular; I think your distaste for those is subjective.

Relative and absolute... Is there a CSS book or tutorial that doesn't take a jab at these names when explaining positioning?

Relative means "relative to the default position", which makes perfect sense to me. Absolute means "I'm explicitly setting this position", which also makes fairly good sense. There are probably better names they could've used for "absolute", but there are also much worse ones. But the point is, these are just names. What really matters is the quality of the underlying system. You don't hear people complaining that Lisp uses made-up strings like "car" and "cdr" to refer to the start and tail of a list, or that bash uses "ls" and "cd" to list and change directories. Those are far less intuitive than "position: absolute".

I've always found people who struggle with CSS don't really know how CSS works and never studied as well as any other language or tool they use. They do a quick read of an article somewhere, ask a question on reddit, get an answer from some 15-year old kid, it doesn't work, and they give up. Yet they own whole book shelves on the latest trendy framework or language they are using.

I work as a frontend architect and UX lead (yes, it's tiring), and you're encountering a common problem.

Javascript is logical (sort of...), and a lot like learning math. It's fairly easy to validate your output. It works well with the logical side of your brain.

Learning CSS is a lot like learning English. There's the basic grammar, but also tons of edge cases, dialects, and straight up absurd rules (Buffalo buffalo..). It's a language primarily improved through experience and memory.

CSS has undergone LOT of development last few years, so things like div centering can now be solving by margin (oldest), flex (newer), and grid (newest), but only in certain browser. It's a language you must constantly keep up with.

Design is just colors and fonts right? (At least, that's what my CEO says). It's important to realize that good design is as hard as good code, and you really benefit from a similar education. That being said, cheat by using a color wheel or Coolors.co

Fonts all look the same until you learn how to look at them. Wine all tasted the same to me until someone taught me what to look for. Without knowledge about why fonts are a certain way you'll never be able to pick one, but it's totally possible to pick that knowledge up. Find a beginner book on fonts and you'll be on your way in no time.

A layout engine and design are two entirely different concepts.

CSS has nothing to do with design. It is the tool used to implement the design and there are loads of other layout tools out there that don't have CSS's infuriating quirks. On the flip side, they usually have steep learning curves because they are strict.

For a long time, until less than a decade ago, designers knew nothing about CSS. They'd do a design in pictures and their design would be implemented by a programmer.

Some (unlucky) programmers entire job was turning PSDs into HTML and CSS.

> Some (unlucky) programmers entire job was turning PSDs into HTML and CSS.

That was my entry into programming many years ago. But I wouldn't call it unlucky - early web devs like me (we didn't really call ourselves programmers back then) had front-row seats at the beginning of a revolution, and it certainly was entertaining to watch and be part of.

> CSS has nothing to do with design

CSS works the way it does because it was created to make the kind of designs that designers wanted possible. It has everything to do with graphic design. All the web designers I knew back in the early days knew some HTML and CSS and we'd often discuss possibilities and limitations of browsers and standards, and how to work around issues. They didn't just lob PSDs over the partition to the devs - there was an active dialogue and they knew their stuff.

>They didn't just lob PSDs over the partition to the devs

You were one of the lucky ones. I worked with designers who would've done fine designing a printed flyer, but couldn't comprehend the idea of a scrolling website with dynamically-populated content (of varying lengths) being viewed at different sizes on different devices/browsers.

Their solutions were along the line of "Force the browser to be XxY resolution and limit the number of words that can be entered in this area."

> CSS works the way it does because it was created to make the kind of designs that designers wanted possible

Well, not originally. Later that became a thing, yes - but all the design that was already there at that point (circa CSS 2) remained, as did the overall approach with cascading styles.

A styling language designed for HTML5 today from scratch, accommodating modern use cases, would likely look a lot different.


I think the best illustration of this "fight" between CSS as a tool for styling "traditional" hypertekst documents, vs CSS as a tool for styling "web pages" is the fate of Adobe's CSS regions proposal - and Håkon Lie's opinion piece arguing against it:


That was when "design" lost. But now with grid and transitions, there's a "new" CSS - one that is oriented around UX for "web apps". But apps evolved from documents, mind - not from windowing toolkits like smalltalk morphs or Java swing etc.

Fwiw I really liked the idea of regions for laying out rich documents - like what you might want for epub.

I must admit I'm not that concerned about "web apps" - everyone seems to end up doing their o we n abstraction anyway, and the CSS that "falls out" isn't really sane anyway.

I just wish we decoupled apps and sites, instead of forcing it all together in a large and incoherent design. This is especially painful now that it's spilling over into the desktop world because of all the Electron apps.

It would probably be written in JS, maybe something like JSSS [1]. I remember playing with it when it came out and thinking it was very cool. Pity it never went anywhere.

If we were going to start from scratch though, we wouldn't do HTML5, we'd use some other format. JSON maybe?

1. https://en.wikipedia.org/wiki/JavaScript_Style_Sheets

Extremely doubtful, given that many of the modern ones have been written in XML (e.g. xaml, android) and iOS went old skool with a drag/drop GUI.

No-one went pure code (because it's a massive PITA).

Display PostScript? Only kidding, maybe.

> All the web designers I knew back in the early days knew some HTML and CSS and we'd often discuss possibilities and limitations of browsers and standards, and how to work around issues. They didn't just lob PSDs over the partition to the devs - there was an active dialogue and they knew their stuff.

I find this false. PSD-to-code was very common back then. There even still some designers today that only work via images/PSD.

Not disputing the 'PSD-to-code'. Did it myself many, many times. I was disputing the idea that designers knew nothing about CSS. The good ones did.

> CSS has nothing to do with design.

What a bizarre statement. That's like saying words have nothing to do with stories, or paint has nothing to do with art.

I remember slicing designs in Photoshop into sections, to be dropped into pages...gross.

If anyone doesn’t get the “Buffalo buffalo...” reference here’s the Wikipedia about that bizarre English sentence [1].

[1]: https://en.m.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buff...

Oh wow. I'd always just assumed it was a US idiom along the lines of yada yada or something. Buffalo buffalo... doesn't work in British English as it is only a noun.

Nearest English silliness I can remember hearing is: police police police police.

Don't tell me you can't verb a noun in English English? "police police police police" - please...

FWIW I'm an ESL speaker from a non-English speaking country and despite having had endless exposure to (mostly American and British) English since a young age, I've never encountered the verb form of "buffalo" outside that one sentence. It's an informal North American idiom and by international standards apparently a fairly obscure one.

Policing OTOH seems to be a fairly widespread verb form with a clearly understood meaning (i.e. what the police conceptually is supposed to be doing). Unless you have close experience with buffalo, you probably can't infer buffaloing means "intimidating".

EDIT: Also as mentioned elsewhere, not everyone outside the US knows there are places actually called Buffalo or makes that leap when hearing the word "buffalo". So "Buffalo buffalo" is more likely to be read as "buffalo(n) buffalo(v)" (which already sounds weird if you don't already know what "to buffalo sb" means) which breaks down as soon as you add more buffalo to the sentence.

It’s extremely obscure as a verb in North America too, fwiw.

Buffalo the city was probably better known 150 years ago, when it was an economic powerhouse as one of the end points of what’s still the second most famous canal in the Western Hemisphere. Afterward it continued to be a significant industrial center until the decline of manufacturing turned the Great Lakes region into part of the “Rust Belt” in the past 50 years. Most Americans probably know of it these days because it still hosts an American football team.

Anyway, the point isn’t that that’s a common sentence. It’s that it’s a grammatical one.

Of course nouns have been made verbs in English. You'll find no British English dictionary listing where buffalo is, unless noting US usage, where it is both.

Police police police police is grammatically correct, but of little meaning : (the) police police(v) police (of) police (ie overseers of the police).

I read it as: police police (Internal Affairs) police(v) police.

>tons of edge cases, dialects, and straight up absurd rules (Buffalo buffalo..). It's a language primarily improved through experience and memory.

Yeah, I'd sum it up by saying CSS makes hard things barely possible and simple things hard.

The example OP gave of centering divs illustrates this point, and there are unnecessary weaknesses in laying out a page when, for example, sizes aren't known in advance. Overall, there's a divide between intuitive expression and output, wherein the browser ends up saying things like, "I won't do this (e.g. center) unless you also do that (e.g. tell me how big it is)." Really? Why?

In all, it's never been an efficient solution to the problem it seeks to solve. When the Great War on Table-based Layouts broke out, it was even less suitable, which made it even more painful that you were persona non grata for resisting. So, rather than demand a better standard and uniform browser support, we just hacked and kludged and shimmed around it. So, the need to support the legacy has made it even more impractical to fix, hence the attempted do-over with flexbox.

CSS has been the bane of front-end development for many a dev. Amazing that we largely just suffer through it, and its tyranny has reigned for so long.

Everything you say rings true ca 2000 to 2012. Today, CSS and the rendering engines have both improved and converged to such a degree, I’m not sure it’s fair to still criticize them quite so harshly.

Of course the cutting edge will temporarily see one rendering engine a few months behind another. But that’s unavoidable unless you prefer a monoculture, which is liable to move slower than slowest of today’s major rendering engines.

It’s perfectly normal today to create CSS (and JS) in one browser and find it working flawlessly in another. 10 years ago, you would have called everyone over to your screen to have them witness this miracle.

I think there's edge cases, dialects, and straight-up absurd rules in JS too.

I don't think CSS is any less logical... but some might not be use to _declarative_ languages like CSS is?

The difference is that with JavaScript, you can install a linter and happily restrict yourself to the sane subset of the language. It's very realistic to never have to deal with any of the uglier parts of JS, even as a full-time front-end developer.

With CSS, you can't avoid hacks. If you try to design anything non-trivial, you will have to employ tricky non-semantic tricks, run into edge cases, and have to settle on ugly, non-optimal solutions.

I don't think it's a declarative vs imperative thing. It's more that CSS was designed to be easy to use and relatively terse for a specific, outdated use case (20+ years ago when a website page was thought as a 1 dimensional flow of text and pictures).

Nowadays our requirements encompass pretty much the full spectrum of 2D space design, yet we still use a language that builds on high level primitives designed for a narrow usecase.

New features like Flexbox and CSS Grid help with the layout part, but it's not enough.

> 20+ years ago when a website page was thought as a 1 dimensional flow of text and pictures

Here's the thing though — most websites are still just a '1 dimensional flow of text and pictures'. They try to disguise it with multiple columns of guff, but it's still just text and images. Sometimes a video.

Sure there are web 'apps' now too, but most websites are not apps (thankfully).

>Sure there are web 'apps' now too, but most websites are not apps (thankfully).

The thing is, web apps are also just a more complex version of the same '1 dimensional flow of text and pictures,' just maybe with Canvas and a lot of javascript. There's no real difference between a web app and a document, as far as HTML/JS/CSS is concerned. The dirty secret of the whole "the web used to be documents but now it's applications" meme is that the applications are still documents.

What does installing a linter have to do with using a subset of a language?

Just... use the constructs you're familiar with? It's not like you can "accidentally" use an ES6 class or something.

You can accidentally use == instead of ===, or even accidentally use the assignment operator instead of one of the comparison operators.

You can know about for..in without knowing about hasOwnProp.

You can forget to enable strict mode.

The list goes on. Static analysis is universally a good thing.

installing a linter and limiting yourself to a subset of the language has to do with the fact that most development is done in teams, so when you limit yourself you limit the team to an agreed upon good subset of the language and nobody screws you over because they think the with statement needs a workout.

I experience the same than the author. But I have absolutely not the same problem with a declarative language such as QML, Cascade, Android xml, Jboss rules engines, etc...

I don't think it is caused by this aspect of CSS.

The problem could come from the fact that it mixes 2 purposes: style AND layout to apply it globally with rules that get harder to understand the bigger the project.

I’m in the same exact role, leading both UX and FE engs. It’s exhausting.

> Javascript is logical (sort of...), and a lot like learning math. It's fairly easy to validate your output. It works well with the logical side of your brain.

No, it really isn't.

Some languages are, JS definitely isn't. It's mostly illogical / broken / mental.

That isn't an argument, you're just expressing your disagreement.

Even if it were an argument I'm not even sure it would be an argument worth having because it's likely entirely orthogonal given the context of the original statement (i.e. contrasting JS with CSS and HTML -- where whatever esoteric programming language you're thinking of is not an option to begin with).

if you avoid the absurd parts, JS is perfectly acceptable. The standard ways people write modern ES6+ CSS is fine.

> Is it common for other developers to have issues with it, or is it just me? Is there any material out there that made CSS "click" for you?

If you're coming from an application development background, you will hate CSS layouting. It's the most ass-backwards way of structuring a UI that you will ever encounter. A lot of web people who never used stuff like Qt, Swing, Winforms (etc) just don't realize this. They think there's some sense in CSS. There isn't, it's a bunch of historical accidents.

HTML wasn't designed to be dynamic, it was designed for documents. CSS wasn't originally meant to do layouting. The end result is an incredible amount of technical debt. CSS performance is a complete disaster. It's unfixable. If you need to do a non-trivial amount of dynamic content, you need to use Canvas or even WebGL and re-implement a lot of stuff yourself, but then people will complain that it's not "semantic", that it's poor design and that it goes against what HTML is meant for. It's a complete joke.

The thing is, you don't have much of a choice. The web platform is what it is. If you want to work in the web frontend, you'll have to deal with it. Alternatively, don't work there. There's other opportunities.

I'm glad to read I'm not the only one struggling with it. It's not as bad as with the OP; I can get stuff done in CSS. But any non-trivial layout always requires a lot of trial and error: does this need to float? Does inline-block work better? Now there's flex layout on top of that. Do I need relative or absolute positioning for this thing? Do I need padding or margin here? And why does my margin not do anything?

Every time I think I finally understand it, I run into a situation where it doesn't do what I expect. And then there's hacks with negative margins and that sort of stuff, where it feels like CSS needs to be wrangled into doing something it doesn't want.

The worst part for me is that it's one of the few places I end up having to hack my hacks because I find out that Firefox does something wildly different from Chrome so the fix I just made to Firefox made it better but broke something else. It feels just as annoying and opaque now as when I was doing CSS hacks for Netscape navigator vs IE. The other thing that frustrated me about CSS and continues to this day is the lack of permanence of a working layout. That is one of the things that really separates the backend from the front end mindset for me, the back end can be done forever but the front end will have to change to fix something unknown in the future

Right on. Also worth mentioning in the context of deprecated web-plugins: Flash and Unity which provid(ed) sane wysiwyg layout tools (Unity's 2D stuff, being backed by scriptable components, is/was especially powerful and ergonomic)

I spent most of my frontend career in that world (and dabbling in Qt, SDL etc. for kicks), and now shifting to the web a couple years ago, it boggles my mind how horrible CSS feels compared to what I used to do with minimal scripting and a bunch of button clicking.

The thing is, Winforms et al. solves a much simpler problem. It only runs on one platform, it does not handle scaling gracefully, it does not even attempt the solve the complex problems of text re-flow to accommodate different size viewports etc. Swing is fine for cross-platform GUIs but can it render books in high-quality typography on various devices? (Or would it use a HTML rendering control with CSS support for this?)

The design of CSS makes a whole lot more sense when you understand what problem it is designed to solve.

> CSS wasn't originally meant to do layouting

This is not correct. The first version (1.0) did not support advanced layouts but it was definitely in the cards. DSSSL was an inspiration and supported layout.

The complex problem of text re-flow is probably not that complex. It has been solved rather satisfactory in all word processors and desktop publishing systems.

Sure, but it is not solved by GUI toolkits like winforms, which is why they are not directly comparable. And A DTP system will not gracefully adapt the layout if you change the page dimensions or scale up the font.

My point is just that CSS is designed like it is because it tries to solve some particular problems. If you expect it to work like a GUI toolkit (or DTP program) you will be confused because they do not try to solve the same problem.

Could you give some examples of how specifically layouting is solved more elegantly in these systems? I don't have too much experience outside of the web and I'm certainly not enthusiastic about layouting in CSS (though with flex & grid it certainly isn't as bad anymore).

I'd recommend spending some dedicated time learning about layout, not leaning on a framework.

CSS layout is largely about the relationship between elements. Instead of looking at it as "I want this element on the right," try to see the relationships between elements. What's the group of elements, and what causes them to be where they are? (Generally, complex layouts are nothing more than nested groups of elements.)

Once you recognize the patterns, CSS layout becomes straightforward. Not easy, but straightforward. It becomes a matter of defining and expressing the relationship between elements, and the constraints that define their layout. Flexbox is really the thing to focus on here. Don't worry about the words if you mix them up -- justify vs align, etc. Just the idea of a spacial relationship between things with rules that define the constraints.

Often times, the relationship winds up being expressed as "I want this group to consist of items with space between them on the current row they wind up on opposite sides of viewport, and when they wrap, I want everything aligned to the left."

Also, really understanding CSS is not about tricks, but if there's one thing that can help you gain an appreciation, it's learning how to write layouts that can handle arbitrary number of elements without any templating logic to add special case classes, e.g. for the first and last column in a grid. To this end, using equal but opposite positive and negative margins (negative on a container, positive on its children) can provide space between elements and allow for arbitrary numbers of elements within a layout where you don't care which is first or last in a given row. Let the elements flow into the layout.

I think there's a pretty definitive set of exercises any developer could work through to learn about the different types of constraints we need to express, and from there, it's generally a matter of recognizing the pattern in a higher-fidelity format.

That's really interesting. I'm also firmly in the space of finding CSS layout inscrutable (CSS styling is fine). I'd concluded that the issue is precisely the lack of peer-to-peer relationship constructs. Everything seemed based on 2 constructs:

1. Flowing 1D content (text) into a 2D space

2. Hierarchical relationships, i.e. positioning children with respect to parents.

I haven't looked deeply into flexbox or grid. My initial skim suggests they're both still fundamentally hierarchical. I'll take another look now given your comments.

I'll freely admit I haven't invested a lot of time trying to get to grips with the more recent constructs (flex/grid). I would say my initial forays were difficult and frustrating. CSS layout seems (seemed?) the antithesis of the maxim "make the simple things easy and the hard things possible".

As a counterpoint: back in the midst of time, there was a cross-platform UI toolkit called Galaxy. It only had 2 layout constructs: springs and struts. Springs defined a proportional layout between components (so would stretch/compress), struts defined a static relationship. It was remarkably simple to define layouts using just those two concepts.

The web is clearly a more complicated space than conventional, thick client apps that only ran on the desktop. Responsiveness is a much bigger challenge now. Nevetheless, it seems to me that the key construct lacking in CSS is the ability to specify peer to peer relationships among elements - without needing to create a whole cruft of container components.

You've incentivised me to give flex/grid another look. I remain healthily sceptical, but thanks for the prompt.

I'd say grid is much more of a "new" concept for CSS than flexbox.

And while I'd always understand learning the basics - to get stuff done most everyone landed on hard coded (sort of) grids before "CSS grids" came out.

Beyond that, I still recommend looking in the (reborn) CSS zen garden:


> I'd recommend spending some dedicated time learning about layout, not leaning on a framework.

This 1000x. I was at a university that used Bootstrap in their Web Design class(!). And, predictably, it didn't work all that well. I spent some time tutoring one of the students and was amazed at the content they didn't cover. Not even modern things like Flexbox, but basic stuff like sibling/child selectors and the cascade.

This is 7+ years old, but once I learned about flow and the box model, things generally made a lot of sense.

I remember when I first told my colleagues that I followed every single CSS course on Lynda, they laughed. They thought why would you spend all this time on a non programming language?

No one takes CSS seriously. For most, CSS comes as an after thought. Build every part of the application then suddenly "Oh Right! CSS!" Slap bootstrap or other popular framework then don't think about it.

Yes, CSS is not a programming language like others but it is just as complex. It requires studying, practice and long exposure to become versed in it.

Note: you can google your way into using a couple jquery functions, but you can't become a competent JavaScript developer like that. The same goes for CSS.

> Build every part of the application then suddenly "Oh Right! CSS!" Slap bootstrap or other popular framework then don't think about it.

It depends on the problem your trying to solve, if you just want something that looks decent (because you're a programmer and you don't notice things like colors, alignment and spacing) then something like bootstrap is a good go-to.

I still think learning CSS properly is worth it, using bootstrap without knowing CSS is like using an ORM without knowing SQL, but less dangerous.

CSS is almost a failure as technology. None of it's promises has been realized.

The idea with CSS was that we would be able to separate content from presentation. Remember CSS Zen garden? Yet that has never been the case and div tags were always needed to be able to display something simple.

Another promise was that content would be displayed easily on different mediums, desktop, mobile even print.. yet it's impossible to get decent rendering in every medium.

For the first years of CSS it was always easier to get a decent layout with tables than with it.

Finally all the CSS preprocessor, like saas and compass show how incomplete the technology really is.

It's only a failure when viewed through the lens of application development.

The web platform wasn't initially designed for applications, it was designed for documents.

If you're crafting a document, you can separate style from content pretty neatly with CSS.

What if my style requires a triple outline around a header?

My heretical view is that it's time to abandon CSS. You already generate your HTML with some program (whether server-side or javascript) that takes a canonical, normalized representation of your content and spits out repetitive HTML elements (one pattern of elements for a button, another for a calendar, etc). Have that same program apply inline styles on elements that need styling.

> The idea with CSS was that we would be able to separate content from presentation

I've been a frontend dev close to 5 years now, and recently I read the entire CSS spec front-to-back in scrutinizing detail for a project.

If the goal was really to decouple presentation and content then CSS has failed spectacularly. Having element selectors, attribute selectors, child and sibling selectors, very tightly couples the content with the layout. It also has the ability to affect content by inserting text nodes for example using the 'content' rule.

I'd say one big gotcha that trips up most people is not understanding when a style is valid or not. Certain styles are only valid for certain display types (see the CSS spec). Also look at the non-normative references on W3C for the default style sheet to see what default rules get applied to elements

To really fully keep content and presentation decoupled you have to stay away from those things and use something like css modules or similarly have a one-class-per-component rule.


Worth noting that the real separation of content from presentation is JSON-data + a CSS/HTML hybrid front-end, often implemented as an off-the-shelf display framework (Bootstrap etc).

The straightforward way to separate content from presentation is to have a step that transforms that content into a specific form: 2D screen based, 2D page-based, aural, etc., including different purpose like a small read-only mobile gadget vs a full-screen desktop app. Web technologies actually have a beginning of this: XML source + XSLT processor, which is a general-purpose declarative tree transducer. But web community took a wrong turn here.

CSS Media queries allow you to trivially handle different mediums (screen size, pixel density, screen-vs-print etc). It really is very very easy.

I dont agree that CSS preprocessors are evidence that the technology is incomplete. Does a c/java/golang/etc compiler mean that x86 is incomplete or somehow flawed? I would wager that most programmers wouldn't agree with that. CSS preprocessors are basically just a way of saving time and improving maintainability by "compiling" some syntactic sugar down to "raw" CSS. Same could be said with doing assembly programming vs e.g. rust/golang etc.

I agree though that in the very early days layout was hard with CSS, but then in the very early days we didn't even have devtools and XMLHttpRequests were still something mysterious and exotic. Times have changed and CSS has changed along with it. I'd recommend you try revisiting modern CSS if you have not already done so - you may be pleasantly surprised at how easy it is these days.

> CSS Media queries allow you to trivially handle different mediums (screen size, pixel density, screen-vs-print etc). It really is very very easy.

Disagree. CSS media queries allow you to identify different media, just like uname(2) allows you to identify the platform you‘re running on. Handling all the aspect ratios, resolutions, capabilities, bugs, idiosyncracies of the current device or modus operandi is not at all trivial, especially if you don’t want to design for each situation from scratch.

The fundamental problem, I think, is that alignment is a key concept in design which isn't reflected well in CSS. The concepts of normal flow and the box model are almost at odds with wanting to align lots of different parts of a page. CSS Grid and Flexbox do help with this certainly but don't completely solve the problem.

Even disregarding mobile and tablets, I think it's also sometimes surprisingly quite hard sometimes to specify how fundamentally you want a page to look in differently-sized browsers - how things like spacing and guttering and so on should work particularly when your content is dynamic.

Plus, there is the fact that it is hard to shield parts of your page from being inadvertently affected by CSS that you don't want to affect it. Again, there are ways to minimise this, but if you're not the only person working on your codebase, good luck!

And if you want to learn a bit about design, The Non-Designer's Design Book by Robin Williams is a good starting point. It is a quick and engaging read and will certainly make you start to appreciate things like the differences between fonts.

I actually prefer coding CSS from scratch. Color schemes and making things look nice IS hard, for my previous and current projects I had to get feedback from friends, family, end users, graphic designers, etc. UX is hard, it's a different field than programming, but there is a method, research, and science behind it.

Here's a good resource for UX: https://goodui.org

And here is one for color theory: https://uxplanet.org/color-theory-brief-guide-for-designers-...

I also really enjoy building CSS UIs from scratch, but editing existing stylesheets is a pain point. Band-aid after band-aid.

I think keeping UI components tiny and coupling the stylesheets with the component is the best way I've seen (not necessarily styled components, just styles in the same folder as the component.)

As the component is removed, its easy to nuke the stylesheet with surgically removing related styles and not breaking something else.

>I also really enjoy building CSS UIs from scratch, but editing existing stylesheets is a pain point. Band-aid after band-aid.

I feel the same. I fiddled with css on personal projects just fine, but in my job, diving into years of accumulated, imbricated classes is a nightmare and even though I try, 80% of the time I end up passing the problem to the design team.

Why not styled components? It’s what immediately jumped to my mind while reading your comment, until you said otherwise :)

Styled components, CSS-in-JS and CSS modules largely solve the same problem. I think it's just a matter of preference.

Same here. I recommend to avoid bloated kitchen sink frameworks like Bootstrap and Foundation unless you don't plan to do any customizations at all and only include the parts you actually use. Otherwise you'll realize that you're actually fighting the framework by trying to override it.

I hate css, but one of my colleague (who's really good at it) told me once that people have problems with css because they don't study and take it seriously. I.e. I spend so much time reading on new languages and design architectures, but besides some articles here and there I don't study css or take it seriously at all. So yeah, there you have it.

I also think it's getting better. One major problem with css was getting it to work across all browsers, but now if you're lucky enough to only have to support modern versions it's so much easier than it used to be!

CSS is not as difficult as many people think.

I believe part of the reason why developers have trouble with CSS is that they don’t ever try to write it from scratch. A lot of web development tutorials/courses/bootcamps often go in depth on JS and maybe HTML but always just slap in CSS frameworks to make things look nice as an afterthought.

I remember the first project I worked on as a web developer was to update the styles of an existing web app with very complex UI. It was hard as hell. But I was lucky to have worked with a senior developer who was a CSS wizard. He taught me that CSS is not magic although it is magical. If you don't give up, you can bring any designs to life.

Not knowing any better, I spent months playing, tweaking, learning how to style different components from scratch. I mastered selectors and the cascade, block model and floats, display and position types, a few tricks like using negative margin, constructing triangles from borders. I never stopped honing my skills. Before long I started learning about responsive design, transitions, animations, performance, and design systems.

CSS became a playground for me to experiment. It opened up a whole new world to express my imaginations. My advice for anyone aspiring to master CSS is to find some design inspiration that you like and just build it. You'll learn so much along the way if you don't give up. At some point, things will fall into place and you will realize just how wonderful CSS really is.

No, as someone who's struggled, and seen other programmers struggle, with CSS way before bootstrap was released I can assure you this isn't true.

The whole set of web technologies is a mess. We‘re still in the stone age of web UI design, similar to the 80‘s era of home computing when everybody built their own UI with basic drawing primitives. It’s going to take a while till decent, cross-platform/device UI libraries make progress and designers discover the value of reusable components that just work and are familiar to users.

Until then, we‘re stuck with terrible websites with, at most, one messy version full of ads for desktop computers, with much too small links/navigation elements for tablets (hi, HN!) and one clunky mobile version that looks horrible on most devices, particularly tablets.

The sad thing is that by the 1990s we'd figured out how to do good UI design for desktops, but then we promptly forgot every single bit of that knowledge when the web came along.

But the web wasn't supposed to be a UI platform - it was supposed to be a medium for delivering text with some images and media occasionally interspersed. Hypertext markup language.

Java applets could use Swing to get a normal-ish desktop UI and still be close to the web. But we keep trying to cram a UI framework into HTML/CSS.

The standards are slowly mutating and eventually they may provide a good UI framework.

JavaFX and Qt are both modern UI frameworks. Both provide a drag-n-drop interface to design applications using standard widgets such as lists and tabbed panes etc. You can modify the styling with CSS (at least in JavaFX, I don't have much experience with Qt). But the final layout spec is done in FXML or the Qt XML format - the XML has <TabbedPane>s and <HBox/VBox/GridBox> and <Button>, with CSS used to style these elements and dictate their visual properties. Instead of divs and spans hacked with css/JS into becoming scrolling lists and tabbed panes or horizontal container boxes.

I know the basics of HTML/CSS and it took me half an hour to figure out how to put 3 images side by side. Because divs can't represent that naturally - I had to use weird css and put 3 divs inside the outer div. In JavaFX you would put an HBox and drag three Images into it and it just works, because a HBox represents a UI concept instead of a document markup concept.

I have been doing UIs since the mid-90's, with Turbo Vision being my first framework.

Naturally also Web based ones since early 2000's.

Share the feeling, everything is so much easier in native toolkits.

There is some hope though thanks to Web Components and Houdini.

I must be missing something, because isn't 3 images side by side just:

<div><img ...><img ...><img ...></div>

? But you're right, the web isn't a UI platform. It's designed for to produce things that are like Microsoft Word documents. Web-apps are like using MSWord's scripting and text layout to produce a MSWord-app. Yeah, one can do it, but it's like cutting a steak with a spoon.

You are somewhat correct. I just tested with the tiny HN logo (upper left of this page), and a div with 3 imgs makes them appear side-by-side. The issue I had previously was that the three images were quite wide, and while I wanted them to still go next to each other (with a horizontal scrollbar in the browser), the browser moved images into a new row if they would overflow past the right edge.

I haven't used JavaFX in a while but I'd bet there's a checkbox you can toggle in the builder GUI to control how an HBox overflows.

The solution for HTML/CSS was to give the outer div "white-space: nowrap" and the three inner divs (with images inside them) "display: inline-block".

Aren’t imgs inline-block by default?

That gets onto a major tangent, namely the fact that the web took over as a UI due to the incredible pain and security nightmare (bad isolation) of shipping and updating native apps. The web was a way to avoid the hell of installing a native app, so the web won.

This is (still) a problem with OSes. Mobile improved the situation a bit but not really that much. I am now reluctant to install mobile apps since virtually every mobile app is a potential vector for who knows who to spy on me. Mobile apps are isolated enough that they're unlikely to trash the device but they still have huge security isolation problems.

TL;DR: endpoint OSes suck so the web won in spite of being a crappy UI platform.

Thinking about the apps I used in the 1990s, we definitely had not figured out good UI design. There were some good ones, but there were some terrible ones too. Remember Napster's interface? Yikes.

In the mid-90‘s the web wasn’t that bad, people used normal buttons, unstyled links and basic tables. The downward spiral started when corporations came and wanted their “CI” styling, then designers came and wanted to be “creative” and turned web pages into minigames where you have to guess what color or text style denotes a link, what the icons mean and how to trick the infinitely-scrolling website into displaying the footer. ;-)

And now we've come full circle with reader modes that disable all that crap the designers add.

I have a lot of time messing with css that could have been solved in minutes using tables instead...

> It’s going to take a while till decent, cross-platform/device UI libraries make progress and designers discover the value of reusable components that just work and are familiar to users.

I find it very unlikely that browser vendors will agree to have the same implementation across their own products, vested interests and all.

The tipping point for me was memorizing "A complete guide to flexbox" from the site "CSS Tricks" by using flash cards (Anki).

The problems with CSS are:

- A lot of features have been abused before there were good layout features in CSS. *

- Errors are silent and you can repeat rules.

- Selector specificty is a major fail in the language IMHO. *

- Everything is global. *

* An example: floating an image is an excellent way of wrapping text around an image. Inline blocks are excellent for inserting layout in the middle of text. Neither are ideal for creating a layout. Flex and grid has now fixed that however.

What helps is to internalize the core concepts and to never "slap on another rule" when things just don't work. Start from scratch and update your mental model.

* CSS-in-JS bypasses the issue of global selectors. And when CSS is localized, specificity becommes a none-issue. Check out styled-components for either React or Vue. When IE11 dies and Edge turns Chromium, shadow DOM will probably become the standard way to solve this.

> The tipping point for me was memorizing "A complete guide to flexbox" from the site "CSS Tricks" by using flash cards (Anki).

That page was a godsend. It's one of my most accessed bookmarks :)

> Everything is global

Shadow DOM and WebComponents to the rescue!

Multiple asterix are stripped it seems.

Asterisks are used for emphasis here:

  *like this*
like this

Footnotes we do usually do with a different mark here; some use square brackets [0], others use superscript chars¹, and I've also seen daggers† around.

It clicked a bit more for me understanding the box model better. More recently flexbox makes things a lot more clear/easier and handles a lot of those problems by default. I have no idea how design works, that seems a bit more art.

EDIT resources

I personally love https://cvan.io/flexboxin5/ for testing and https://flexboxfroggy.com/ for learning flexbox

CSS is great, but its poorly taught. I've known so many developers of all skill levels who get stuck somewhere between "I can make it red but I have no idea how to apply all these random properties into the layout I want." They'd ask me for resources, and I couldn't find one I thought was very good at that.

So I tried to write one.


What's nice about this is I wrote it for real people, tested it on them, applied their feedback... etc. It's a little old now (this was before widespread Flexbox support) but it's specifically aimed at the sorts of problems you described.

I liked the no bootstrap section. People lack the foresight of shooting themselves in the leg. Currently working on a project where the front-end guys ended up using !important for literally everything due to lack of knowledge on how Bootstrap works.

It sounds like you just haven't put in the effort/time. I very much doubt that CSS is "too hard" for you.

I've had similar experiences with regex, shell, & vim. If you're not doing it all the time, it's easy to just brush it off to the side or google whatever you need to do.

No reason to be an expert in something you're only going to use once in a while.

I would put regex shell and vim all in the same bucket as being esoteric and hard to learn since they don’t replicate any of the normal syntax and patterns you are used to. Actually, they are arguably even weirder than CSS.

My frustrations w/ CSS stemmed from not having respect for the complexity of the problem that CSS solved. I went into it w/ the same attitude of "hey, just center this thing", and didn't really get anywhere. These days I have accepted that CSS is a tool for pros, which I am not.

> hey, just center this thing

Step 1: On your container div...

display:flex; justify-content:center; align-items:center;

Step 2: There is no step 2.

Yeah, with flexbox we can finally do the layouts we could do with tables since 1996, and it's only a little harder.

With display:table from CSS 2 you could do the layouts you could do with HTML tables. Flexbox solves a different problem - for example you can't have rows and column in a flex. There is some overlap in functionality, but generally flex is more convenient to use.

this won't work on bootstrap elements

Another reason to avoid bootstrap if possible. I wouldn't touch that thing with a 10 foot div.

Each to their own, but it's better to make your own templates, unless your primary role is something other than frontend dev and you want the equivalent of store-bought pasta sauce instead of making your own pasta sauce.

Are you using the bootstrap’s utility classes?

.d-flex.align-items-center etc

Speaking as someone who has no problem with either CSS, SQL, C++/java/perl/python/assembly or Jan Tschichold, the problem with CSS doesn't seem art-like, but rather SQL-like. People expect CSS/SQL to be like those other languages that also have indentation and (){}[], but they are based on other concepts.

C++ and Python may be different from each other, but they're both imperative block-structured languages with a strong emphasis on time and happens-before.

SQL is set logic expressed as ABNF. If you want to write good SQL you have to let go of assignments that happen-before other assignments. Instead there are sets, unions and other concepts from logic.

Debugging javascript is a little different from debugging C++. Debugging SQL is fundamentally different.

CSS is like that. It's Jan Tschichold's design rules expressed using ABNF and has nothing to do with von Neumann machines. You might achieve Zen by reading one of Tschichold's books, and ignoring all of the syntax and tricks and howtos for a while.

I held the same belief for a long time, but now I think that CSS isn't particularly in general, but can be very hard if a few core concepts are missing.

The main thing that personally made it really hard for me is that I totally forgot about the first thing you learn in CSS: _Cascading_ - Coming from saner languages, the concept that what is written at the bottom of the file has more meaning than what's at the top of the file, or even worse that the file that is included later in the HTML has more meaning (without much scoping, and sometimes unintuitive specificity of selectors), seemed bonkers to me (and still does to some degree). Once I internalized that, that solved 50% of my CSS problems.

Apart from my anecdotal stupidity, one of the best resources I found was "Learn CSS Layout the pedantic way"[0].

[0] http://book.mixu.net/css/

>Incidentally, but very likely related, I always failed to have any glimpse into how design works. I have no idea which colors "go" with which ones, and pretty much all fonts look like the same for me.

Yeah, you're not a designer.

Note I'm not insulting you. :)

CSS is very much like magazine or print layout IMO. If you're not used to that, it won't gel well. If you think of layout from a design perspective and _not_ a programming perspective, it's really not that bad. The warts more come down to differing implementations across browsers, which has become far less of an issue in recent years.

I expect you'll get a very different response from the crowd here, though, so consider it my two cents. I've done much backend work (like yourself) but started in frontend, so I feel adept enough to work with CSS well when I need to. shrug

Can I be really predictable and give a "very different response"? Worked in magazines for years, still do a lot of print cartography, and I find CSS a completely different mindset to Illustrator or InDesign or Quark or whatever.

It just feels like a weird outlier to me - not freeform enough to fulfil the "design" role, not programmatic enough to fulfil the "developer" role.

Same for me. As someone who's done a lot of layouts in InDesign, it seems to me that CSS is only starting to offer decent tools to reproduce that mental model (e.g. CSS grid). But somehow doing incredibly basic things such as positioning or aligning elements can still take inordinate amounts of time.

I too worked in catalog design / printing. I had a lot of catalogs from many manufacturers (some 5 to 10 years old). This was how I learned UX design, I benchmarked design decisions made by other companies. Since I knew how those companies operated, this gave me insights on what good/bad designs are.

Designing a catalog is similar to designing a SaaS tool.

Designing a magazine is similar to designing a marketing website.

Working with AdobeIndesign taught me the following things, that translated into web development:

(1) Importance of style guides (things like BEM, SMACSS, etc): If you don't lay these out upfront, your catalog becomes incredibly inconsistent and hard to manage (too many components everywhere).

(2) How to organize your SCSS files - it's actually almost the same way you do it in Adobe Indesign. There's a `base` folder for global layout styling (fonts), `components` folder for things like buttons, tables, etc.

(3) How to layout a webpage. In Indesign, you start with the header/footer usually in your masterpage layout. Then you design each page from top to bottom generally (for a catalog at least). The viewport is more or less the size of a single page. You can only fit so much content there.

(4) Font-types - Open indesign, dig through all 100+ font types and see what the differences are. Some can handle fractional fonts, others have support for narrow styling (Arial).

(5) Design combinations - Take a look at a Grainger or McMastercarr catalog. There's many tricks for cramming a lot of information on one page. Minimal font sizes, horizontal lines in tables, use of white-space eye relief, consistent styling, etc.

(6) Constraints - If you saddle-stitch or 3 punch bind your catalog, your margins differ. If you make brochures, it's like designing for mobile devices

(7) UX Interaction - There's many ways of looking at a page, and where you want to draw a user's attention first.

UX tools are still playing catchup to what Indesign has offered for years.

I would say CSS is different mindset in that there are more rules. And you have to usually handcode it yourself. It's "design" in the sense of knowing what colors to use, size of content, etc. "Development" in the sense of knowing how to use master-page layouts / component designs upfront.

Yeah, I hear this a bunch, and I can see why it'd feel that way. My standard response is that HTML/CSS simply didn't advance enough for a period of n years to make it easier, so it (for awhile) was arguably stuck in the late 90s/early-mid 2000s for layout concepts. The other response to you noted it's gotten easier lately too.

Yes, this. So much this.

I was in your boat about five or six years ago. Programming was fine, CSS was kinda-not-really ok, and design was just non-existent. Over time though, it really is something you can learn.

I started by cloning designs in CSS that I liked. Same way I write programs just to learn. Pick a design and try to reproduce it. (Here's a good simple one that could probably be finished in a single sitting. [1]) Eventually I was able to clone an entire website while only referencing the internet for CSS details, not core concepts. It'll take time just like learning any language, but the theory behind CSS does make sense if you can peel back the layers of features built on top of it. (Like Git, the core model is beautiful - the CLI not so much.) Reading about the "cascade" part of "cascading style sheets" would be a good place to start if you get the basic syntax already. Then study the selector operators. All of them, there aren't that many.

Then read books on design. Info about CSS the language is readily available online. Info about design, not as much. Design for Hackers [2] is targeted at programmers and explains not just the what but also the why certain designs work. The way our brains interpret color and how that causes certain colors to work well together. How people process information and how to leverage that to make designs that "make sense." Visual Grammar [3] is a design reference book I refer to. It's like a SQL reference book - won't teach you the language (of design) but explains the options you have and when they could be useful. Things like "these types of alignments will produce this type of result."

Just remember that it takes time to learn a skill. And design is definitely that - a skill that can be learned.

[1] https://assets.awwwards.com/awards/images/2016/04/uxpin-teas... [2] https://www.amazon.com/Design-Hackers-Reverse-Engineering-Be... [3] https://www.barnesandnoble.com/p/visual-grammar-christian-le...

I'll toss another design resource into the mix that I don't think gets mentioned enough: John McWade's "Before & After" magazine and videos. His focus isn't exclusively web but the principles he applies also apply to the Web. He does a fantastic job of training one to develop the eye of a designer. E.g. noticing certain patterns that aren't immediately apparent and then working with those to bring out a certain aesthetic.

I can't recommend him highly enough.


I've written a small but non-trivial amount of CSS for my website recently, and my general perspective has been that CSS has quite a few non-obvious corner cases (margin collapsing, the exact semantics of how things will wrap or overflow) and I really haven't quite understood why certain solutions work and when some don't (when they seem to do the same thing?), and I'm not sure if it's because the model is just too complex or these are idioms that I should memorize.

CSS is not an art thing. It's just a configuration language with a accidental hierarchical features attached. CSS has as much to do with design as a tube of paint has with painting.

As a technology, like all things related to how browsers work really, CSS is not really a well designed part of a wholesome and complete architecture, but an accidental feature on top of a pile of an accidental agglomeration of features.

CSS is not art. It's just accidental complexity. It's totally understandable to me if it seems weird.

But if you need to learn it - maybe train yourself by small examples? Maybe you are trying to understand the layout of a complete and complex page? What if you implemented simple HTML pages by hand of increasing complexity and figure how CSS affects those? People are different learners but this sort of thing helps me along often.

And the font thing - typography has a long history. Since the chances are fairly good that your designer counterparts are font afficionados it never hurts politically to familiarize oneself at least with the history of the craft and to identify serif fonts from sans serif ones.




You're experience is so common that there are sites like "https://css-tricks.com/". I feel the problem here is that when they were making the standards, they for whatever reason separated the content from the layout and styling. I think XAML is actually an incredible example of well implemented layout and styling. I can do the layout graphically, and I can adjust the layout intuitively using XAML for those things that can't be done graphically. I can dive further into it and apply styling also through XAML. From a developer experience perspective, XAML is what a developer is looking for. HTML+CSS has it's roots in authoring pages of content, not applications and it clearly shows. They've attempted to evolve both to become application development languages and they're just not meant for that. The WWW really needs something akin to XAML+C#, maybe in this case a hybrid layout/styling language combined with TypeScript (IMO). All languages have their merits and their shortcomings, but for a web application developer, thank your lucky stars that CSS Frameworks exist.

FWIW my father struggled with CSS for countless years before retiring. The reasons were he never got his head around the DOM or the CSS box model and the fact that it all assumed you were using CSS to style a document (or more specifically, a DOM tree). He would instead want to place this/that here/there, oblivious to the fact that he was building a web page that scrolls, rather than a more familiar VB app screen that does not.

Understanding the DOM, the CSS box model (and more recently, flexbox), and the above-mentioned nuance if you're coming from the app world, is more relevant than ever in our mobile-first time and age. Until you wrap your head around the notion that no, you're not styling an app screen that is fixed-sized, but are rather styling a document, you'll find CSS hard. (And yes, the real WTF is why are we using this type of tech to build UIs instead of native controls, but that's another debate.)

Once you do grok that, you also need to learn to accept some quirkiness and imperfection (it is a lousy language, after all, and browser engines don't render everything the same way), and you'll find that CSS is not that hard.

The reasons were he never got his head around the DOM or the CSS box model and the fact that it all assumed you were using CSS to style a document (or more specifically, a DOM tree).

This seems to be true of many devs who find CSS hard - there seems to be an assumption that you can take any HTML structure and use CSS to magically make it look like any design. The author of the question even lists a huge number of languages they've used over 10 years but misses out HTML as one of them. The simple fact is you can't just use CSS. To implement specific layouts you also need the right DOM structure.

>He would instead want to place this/that here/there, and never really got his head around the notion that he was building a web page that scrolls,

Not only that but you are building a page that displays on all kinds of screen sizes so you just have no idea how much space there is between here and there. Thats 90% of what makes CSS hard because depending on what screen you are on, you can't just put something here because here doesn't exist for everyone.

I think CSS is designed fairly well its just that its solving a very complex problem of how do you make one page display on all kinds of devices without having to define layouts for them all.

holy shit i'm old.

CSS is simple.

It uses two basic constructs: rule and its selector.

Selector is SQL's SELECT/WHERE statement essentially that says:

When the element conforms this condition it has these set of properties. Any element may have multiple rules applied with matching selectors in particular order (so called CSS specificity).

And there are 20-30 basic CSS properties defining different aspects of layout and rendering.

Yes, there are 200+ other properties (and counting) in the full set. But that's for Jedii and merely 10-20 of us who are in business of creating layout engines.

It used to be more of us but the ones from MS are lost for the Republic - all their events were bubbled up onto the Dark Side.

CSS is not hard. Design is hard. Putting a technical barrier between yourself and a decent design makes designing a little harder. But CSS is just obscuring a really tough problem. One thing that makes CSS seem tough is its incompatibility with the design process. A "simple" design change can mean many many lines of CSS or CSS that is simply incompatible with existing CSS/HTML structure. The best CSS writers I've known all have backgrounds in design/art. It's a long term play, but I'd say invest in learning to design. Forget about CSS for a while.

How many hours have you spent writing CSS versus the programming languages you mention?

I don't think there's any art to writing CSS or having an easier time with it. It's just putting in the hours to know what works and the energy to understand the foundations (box model, cascading, etc. which are concepts you only need to commit to memory once).

Maybe CSS clicks better with some people, but the others can offset it with time. When I started writing CSS 15+ years ago I never thought I'd be able to do anything useful with JavaScript. But then you put in the hours…

What you discover about CSS is that it's an accretive thing. You start out perhaps with a (comparatively) simple basis, whatever came with whatever app or framework your site is based on, or if you're lucky and starting from scratch, what you yourself wrote and understand.

Then over the years, you and other developers and designers on the team add to the CSS. You can't go back and change anything, because changing something to look right on this page may make it look wrong on another page. You can easily see the structure of selectors on the page you're looking at, but not the set of all possible selector structures on every possible potential page on the site to know how it will cascade everywhere. So you just add on, gradually getting more and more specific with the selectors up to the point where you have to start using !importants.

Meanwhile, over the years, the 'best practices' change, and the CSS that you and your coworkers write changes to adapt. So you end up with things originally sized in pixels, later multiplied by a floating point scaling, overridden with em measurements, overridden by whatever the current fad in measurements is. Change any of that and it breaks random things throughout the site due to cascading, inheritance, and document structure/selector specificity.

Due to the way it accretes over time, you end up with massive amounts of CSS, most of which is overridden but can't be removed without breaking random things. You can't reconcile it or do it the right way without a full rewrite.

And in the end, it still always takes a few hours to figure out how to center something without breaking the alignment of other things, or whatever you're trying to do. Because it will be different than it was last time. It's not like just calling element.align(vertical=center, horizontal=center); as it would be in a programming language. It's a series of hacks built upon hacks to do the most basic things.

I’m currently writing my second ebook on CSS, and you are exactly the type of person I want to help.

The first thing you need to understand is how a page behaves when it’s _unstyled_. I mean when you haven’t implemented your own CSS. It turns out that there is no such thing as an unstyled page because the browser comes with its own default CSS.

At that point you have to get a feel of how each type of element (block, inline, table, list…) is rendered. Turns out that you’ll that if you understand block and inline elements, you’re halfway there (that’s actually what my second chapter will cover).

When I started writing CSS, I wrote it by hand in Notepad++, line by line, with no autocomplete. I think you need to go through that process to understand each property first, and learn what it does.

Send me an email and I’ll send you a draft of my book. If I can solve your problems, it’ll mean I’m on the right path.

> I can't say "hey, CSS, this is the parent div, and all child divs must obey its size". I can't do anything basic on CSS without turning for help.

Use Flexbox. It makes layout so much more straightforward.

This is an awesome resource for learning Flexbox that you can use as a reference until you don't need to anymore: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

> I have no idea which colors "go" with which ones, and pretty much all fonts look like the same for me.

This isn't about learning CSS, this is about learning design, which is a completely different game.

As a designer who often hands over designs to developers, I find it all too frequent scenarios where developers struggle interpreting design into code. I have NEVER seen a developer who can implement a design exactly per spec in CSS.

This is not to say that developers are incompetent with CSS, in fact, it probably says more about CSS than it does about the developer. The fact that CSS has gotten so convoluted is counter to its original goal.

Perhaps I have just work with companies who don't have an A-class developer team? I don't know. But it's not unusual for developers to straight up tell me "I'm not a CSS guy". Like... really? Who is then?

As both a designer and primarily a developer I can tell you there hasn't been a design I couldn't implement exactly as per spec over several years.

The issue has been more a case of it would be better not to and the design being incomplete (being most frequently static mocks) it hasn't fully captured the interaction, all scenarios or device widths. Designers need to really understand the medium they are working with and meet devs halfway.

Good design is function over form and working within constraints. All too often in the industry the designs are created as though they are for print. This is in large part also due to the fact designers tooling itself was designed for print and we are just now beginning to have better tools for designing interfaces but there is a long long way to go.

as someone who is intimately familiar with CSS and doesn't have a problem using it - it's still poorly designed. I think the problem you have with it (and the one I have with it) is that it is in no way systemic. It's like PHP - it's evolved over time not by iterating on the foundations, but by tacking new features on. Flexbox/grid have solved a lot of the layout issues that required messing around with display:inline-block/margin:auto/float/clear for so long (by basically pretending none of it ever existed), but other issues are still around. The fact that box-sizing:border-box is not the default is basically down to netscape winning the browser wars. Shadows overlap even when they logically shouldn't. It's not nightmare-level but it is hard to mentally model at first.

I don't think it helps that most of the CSS I've seen in the wild is vastly over-complicated.

I’ve been working with CSS for about 20 years now and it still baffles me at times. I understand selectors just fine and I’ve memorized most rules, but placement and spacing are still unintuitive in my opinion, not to mention all tbe browser-specific rules and overrides. Oh yeah and there are plenty of young devs who don’t understand that SCSS generates CSS and don’t understand actual CSS. It also doesn’t help that so many libraries and frameworks encapsulate all the CSS heavy-lifting for you, never forcing you to actually have to learn CSS, which is in fact hard.

You really want to develop a mental model of a CSS engine, so you can “run” code in your head.

This will allow you to read code and have a high chance of predicting what it will look like before running it.

Your probably not developing this mental model for some reason.

You should try to explain why you are seeing a visual result, and keep a notebook of how CSS primitives work together. For example, why are there 10 ways to vertically align, and why do they all work?

Once you collect enough primitives, you can use them together to design a layout.

You could try developing your own css layout engine which would force you to understand the rules.

I am a designer turned developer. But long before entering development, I made websites with HTML and CSS from scratch.

I have no idea why people find CSS difficult. There is the odd case which even I find cumbersome, but for most of UI development, I find creating layouts with it very natural.

If you have specific questions, I can probably help.

Same exact experience. I have a few theories as to why some struggle. One, I think of myself as having really great spatial awareness and reasoning abilities. I can think of a div in 2D space and imagine all of the forces acting on it to push it around. I’m a very visual person and tend to do well with stuff like this. Contrast this to complicated recursive algorithms and I can’t do it without actually drawing it with shapes and physical things. So I think of this as the proverbial right brained or left brained... some are able to visualize things better in their mind and I think those people tend to grok css better.

Two, I think all of the modern tooling and libraries have stunted folks abilities to learn the fundamentals. There’s also been a paradigm shift in that, at one point, there was a much more distinctive line in the sand between frontend and backend where it was more typical to build a website that was either static or used a CMS and you spent 90% of your time living in HTML/CSS... so you could master it better. Nowadays if you find the latest tutorial or join a boot camp or whathaveyou you’re gonna a be messing with components and css-in-js, express servers, graphql etc... so it’s a lot harder for a newb to hone that skill.

If you wanna know and be good at CSS you need to go back to basics and actually learn it. Text editor, style.css, index.html and a browser window.

I guess I'm alone in liking CSS.

Yes, it definitely takes years of experience implementing annoying designs to appreciate... But the macro-positioning stuff comes pretty easy once you understand the box model and can visualise the positioning.

I don't think it's an art. It just takes real experience.

It's not just you. I'd recommend using a CSS framework. Have you checked out Bootstrap [0]? I was very much the same way (focused on backend). CSS is just a means to an end for me, in that I just wanted something that doesn't look like total garbage, so I used Bootstrap for the frontend bits. Allows you to quickly get up and running using the examples without learning too much CSS [1]. Just find something that looks like what you want and then copy/paste. Much much easier.

They have a pretty nice grid system that allows you all types of formatting options (desktop/mobile). All types of text formatting options too. Honestly, I think you're way better off learning something like Bootstrap unless you want to do this professionally.

[0] https://getbootstrap.com/

[1] https://getbootstrap.com/docs/4.2/examples/

EDIT: downvotes? Why not mention why you don't like bootstrap and share with the larger thread? At least, then it is useful to everyone else.

Don't use bootstrap for anything beyond personal project prototypes. It ends up being a complete nightmare for maintenance. Coupling of DOM with presentation and state is the number one thing we should be avoiding in modern JS apps.

Interesting, I'll have to read about that. This has totally not been my experience.

It works great... for a while. Then you end up wanting to tweak something here and there, start adding classes to things, and you realize you want to do something that requires changes to the DOM within a component and you're screwed. Or you ignore the fact that the right way would be modifying the DOM, use some hacky CSS to kludge it, and you start getting browser inconsistencies. Either way you end up stuck with 100k of dependencies to style a popover and a dropdown that could have just been defined in a design system from the get-go and done with minimal CSS in a React/Vue type architecture scoped to the individual component.

Ah, that does make sense. Thanks for adding the examples -- I can totally see this happening. Guess I just haven't been bitten by that yet. Although, I do remember running some mass regex through the codebase to update class names when bootstrap changes something. Or, changing templates to use some new formatting. This can be nerve wracking.

There are some use cases for Bootstrap for sure, but I feel you need grasp the basics of CSS first. It is like using jQuery for everything instead learn proper Javascript.

Until you get to the point where you are reinventing jQuery vs just using it. The same thing can happen with CSS, you are formatting all this stuff, getting a layout, spending tons of time fixing layout issues in CSS, etc. Where your time might be better spent just using Bootstrap and working on your app vs CSS.

I think there is a spectrum Of skills with programming at one extreme and visual design at the other. Even within “front end” you tend to have JS experts and CSS/design/UX experts. Some people can do both.

When you consider UX, accessibility, progressive enhancement, cross browser and cross device support - there’s plenty to know. And unlike programming, it doesn’t all flow logically. Some stuff is subjective, other stuff requires specific knowledge of browser quirks etc.

The only site that helped me gain some _understanding_ of CSS (as opposed to knowledge, tricks and hacks) was this one http://learnlayout.com

It’s a bit dated now - Flexbox is mentioned at the end and CSS Grid is entirely absent - but still important if you’re supporting older browsers.

But CSS has never “clicked” for me. For a start the whole idea of cascade is based on inheritance and I generally prefer composition. I like designing UIs and it’s quite a satisfying challenge to match a wireframe to the pixel. But overall, I’d rather be writing application code.

If users could just read JSON everything would be a lot easier...

I don't see get why anyone thinks that CSS skills and design/UX skills somehow go together. It seems to me that the skills needed to write CSS have more in common with those needed for programming than for UI design.

I can only assume that you're trying to run before you can walk. Remember that you're just defining a set of layout rules. You're not giving the browser specific instructions to follow. It seems that there's the temptation to assume that CSS is easy and simple, because it's for the web and isn't a proper programming language.

That is clearly not true. CSS describes a complex set of interactions which evolved over many years. You'll have to refer to MDN, experiment in your browser dev tools, etc.

Start in small and isolated chunks. Open a codepen with just a couple of divs and work out how their layout interacts.

I firmly believe that you can write beautiful CSS. Your list of languages shows that you are clearly interested in learning, and in expressing your needs in varied ways.

As an aside, I would recommend having a design on paper/on screen to implement before starting to write your CSS. Until you become relatively fluent with it, I think CSS relatively counter-productive as a design tool. Thinking about the target result as a separate step from implementing that result is going to be a much better approach.

CSS is utter crap. In the history of computers, one programmed in a single language at a time. You had punch cards, then a text file in a terminal, then a text file in a PC written in a language like FORTRAN, COBOL, PL/1, Java, etc. And it was fine. Then they invent a bizarre 3 language sandwich where you switch back and forth between 3 completely incompatible languages (CSS, HTML, JS), which don't even agree on how comments are entered. It is one of the worst designed languages ever, surpassing the previous abomination RPG. I can't wait to deep six the whole HTML stack, as it is a huge time waster. We need a single, well-designed language that can all the general purpose coding we need (and generate websites). Maybe the output will be JS because that is what browsers support today, but seriously let's not put lipstick on a pig and call it pretty. That CSS can draw but not compute, and JS can compute but not draw, and HTML can't do IF, what kind of nutty design is this? Chaotic rapid growth was the cause, but the cure is to dump it entirely.

These made CSS click for me:

- https://flexboxfroggy.com/

- http://cssgridgarden.com/

That was fantastic. Attempts to teach programming through gamification tend to have issues, but the instant visual feedback and clear goals helped me understand CSS much better.

I really dislike CSS. I find of the 3 main web 'languages' it is the most difficult to do well. I really hate the 'C' in CSS. I've found that using scoped CSS cuts down on a LOT of the things in CSS that bug me the most. Like changing the style of a particular div and now all the p tags inside of it auto-magically changed as well!? So if you are using React, Vue, etc. I recommend finding some approach to scoping your CSS to your components so as to avoid as much of the cascade as possible.

As for layout, spend half a day learning about flexbox (https://css-tricks.com/snippets/css/a-guide-to-flexbox/). It's much simpler than CSS grid and it'll do 90% of what you need as far as layouts go. If you have a particular section of your page that needs to be laid out in a grid, then you could try out CSS grid in that limited section. I think it is a nightmare for overall page layout.

I have done a lot of backend and front-end coding over the years I've found CSS is complex just due to the sheer depth of detail, but not hard once you get the hang of the basics.

The key areas that will probably help you the most are flexbox and grids. These are modern things that will make your life in CSS 10x easier and more productive. With flexbox and grid it becomes trivial to do "hard" things like centering div's, full-height divs, footers etc etc. Use flexbox for laying things out in one dimension (e.g. "I want these related <things> to appear in a row/column") and use grid for doing two dimensional layouts (e.g. "I want a bar across the top and bottom and then two columns in the middle"). Mix and match flexbox and grid (e.g. use flexbox inside of a grid area) and you've got 90% of the CSS done in my experience.

This guide for flexbox is awesome and spells it all out: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ (although their site's visual design is the worst type of hideous garbage IMO, but I can forgive them that for the content)

The last 10% is fiddling around with colours and margins and font sizes etc. I'm no designer and rely on the UX and Visual Designer to tell me what colours/fonts/margins/etc to use, but regardless there is actually something very very satisfying about nailing the CSS and seeing something ugly transform into something really nice right before your eyes.

Also a final top tip is to get familiar with your dev tools in your browser of choice. Doing "real time" edits in the browser (in CSS but also DOM & JS too) then updating the code in your IDE is something I do frequently.

Whenever this subject crops up, I'm inclined to just answer "Yeah, it's just you", at the risk of that coming off as too harsh.

I really like CSS and it's where I got my start, and used it for a long time, often to make up for not knowing JavaScript.

I don't think CSS is an art thing. I think CSS is pretty simple, but requires an understanding of how CSS works and how browser layouts wotk.

Without that, you're going to have a hard time, but I can't really think of a language where that isn't true, either.

Sometimes I feel like this is the result of people undervaluing CSS, because they "just want to make a colored box" or whatever, but fail to view it as its own language, with its own ecosystem and considerations, placing undue expectations on its simplicity.

If I were to "just make a program" in C, without any knowledge or consideration for how Windows works, how stacks, heaps, memory, and pointers work, and how C works, then I'm gonna have a bad time, and the same goes for CSS, imo.

Being able to produce nice, competent design requires a very different skill set from the one developer has. It's not our job to know what are complementary colors, what is hierarchy etc. But when handed sketch/photoshop design it's part of my job to implement it.

It's not a coincidence that you brought up positioning.

> I can't center my divs properly.

I remember having a similar feeling. What made it click for me was searching for some articles like "how to master css".

Btw, just did that search and this is the article I remember I went over https://designshack.net/articles/css/5-steps-to-drastically-..., which is the first result.

Understanding how to position things I think was the biggest aha moment: floats, box model, the difference between positions such as fixed, static, absolute etc...

I think if you go over resources mentioned in that article you'll be good enough.

It feels like there is this idea that CSS is very simple, not a real thing, so we don't dedicate the time to learn it. You wouldn't expect to be good with React after one day, would you? It takes time to learn js, having that base it's easy to pick up React in a few days. And then you read articles on best practices, staying up to date with new versions etc.

CSS requires much less, but still some time and effort. Treat it as technology, give few days, don't skip steps, just sit down and learn it.

You can't solve `x + 5 = 10` when you don't know what `2 + 2 = ?`

So don't try "hey, CSS, this is the parent div, and all child divs must obey its size" until you know what is the difference between absolute and relative position.

I don't think CSS has anything to do with art, you usually have the design done already, you just need to put it together in a way that browsers can read, so it's just good ol' programming. Thing is that it's very easy to do a little things and tweaks in css, copy & paste snippets, so people jump to conclusions about css being easy - but then you discover that to really master css it requires a lot of lateral thinking and being able to look at the design and "see the matrix" behind it. It's like trying to figure out haskell and you come from C, you need some time for your brain to rewire how you think of problems. IMHO emphasis should be especially at a lot of learning by doing it, because experience is everything with css. So just give yourself some time, work on it and you'll figure it out...

My feeling about CSS is similar to asm/Assembler. It gives you ultimate handles, but it's very much low-level down to pixels. Same about peculiarities of the underlying platforms and browsers.

While I see great uses for asm directly within parts of an application constructed with higher-level languages, yet building a whole system using asm is unnecessary. Compiler does this job.

With CSS from scratch or not, you need to move, store, add, clear, and jump on your own. And let's not think of how many losely coupled variables a real-life web-design presents to deal with. There's no compiler for this, only a debugger (Firebug, etc.) CSS frameworks simplify some aspects of this, but fundamentally it's still low-level.

That's what makes this CSS chase a somewhat futile exercise in a long run. Assembler is at least is more concise to memorize.

This is a great way of putting it.

It's easy-peasy once you get the general algorithm down:

1. Is there a Stack Overflow CSS snippet you can use as-is that solves your problem? Score!

2. No? Fiddle with random bits until it looks OK in your browser of choice (Chrome). Display: block and position: absolute are great time savers, slap that on most things.

3. Ship it! Onto the next feature!

Pro-tip: Pixels totally work and you should just stick to that everywhere. The browsers and device manufacturers have kindly taken the necessary steps to make it Just Work no matter what the medium.

In case you think I'm being sarcastic, only half. Nobody cares about your beautifully cascading, resolution independent em's and semantically beautifully structure. The whole thing will be run through an uglifier anyway and probably you should just have used JS for your runtime generated layout anyway if you have any kind of dynamic behavior.

Yes, it is horrible. It's got a little bit better (think flexbox and CSS grid) but it still feels clumsy, unintuitive, unpredictable, inelegant, frustrating. You learn to live with all it's painful shortcomings, but you'll never learn to like or love it.

Interesting aside: what would the creators of CSS do differently today?

Bert Bos:

- Feels there was too little detail in the first CSS spec (but Håkon Wium Lie thinks there wasn't enough)

- Wishes there were more ways to display link behaviour e.g. expanding/collapsing text

- He wanted to create CSS syntax that was readable for people who were not programmers

- He preferred a full stop (period) to mark the end of a group of statements. Curly brackets (braces) to group statements was Tim Berner-Lee's idea.

- Grids should have been a fundamental part of the CSS spec from the beginning

- Prefers the idea of CSS for documents and a separate language for UI elements

- Thinks the cascade could have been made easier

Håkon Wium Lie:

- Feels there was too much detail in the first spec: the more you added to the spec, the harder it became to implement

- Thinks that margin collapsing was too complicated for v1 and could have been dropped

- Also thinks first-letter and first-sentence pseudo-elements should have been left out of v1

- Hypercard was based on the idea of cards rather than documents - he wished a CSS card element had been defined

- He didn't want border radius originally, but designers insisted and he now likes it

- The v1 spec was written without any test documents - he considers that a major mistake

- They both approached CSS in a document frame of mind and wonders if they should have considered the idea of web apps more

Source: https://www.youtube.com/watch?v=PQTpsxf7rQQ

Interesting comments from those guys.

I taught myself CSS by reading the CSS 1 spec back in the late 90s (mainly aimed at IE 4 - Netscape 4.6 sucked bad) before there were any books on it. I think the CSS 2 spec was also out by then too, but the browsers didn't support it yet (that took a surprising long time).

I found learning CSS 1 from the spec pretty easy as it wasn't a large spec and was fairly easy to read. The CSS 2 spec was a lot larger (5-10 times?), and a lot more complex with all the new stuff. Learning that took some help from the old Eric Meyer book from O'Reilly with the pair of trout (?) on the front.

The Eric Meyer book helped a lot with understanding fundamentals like how flow worked etc and properly grokking inline vs block etc. There wasn't really any of the tooling (eg Firebug and successors) to help back then.

Of course, I wasn't reading the specs to implement a rendering engine - just to use it.

I stopped doing any CSS about 8 yrs ago just as CSS 3 was starting to happen and never really learnt that. It seems way more powerful/complex/useful these days.

One tip that really helped back then was to try and do what you wanted with the very minimum of selectors/declarations to avoid conflicts, ambiguities and debugging difficulty. So creating lots of scratch empty test pages to explore one specific technique before including it with all your other CSS/HTML.

I understand this feeling of CSS being some kind of black magic or something that just doesn't play by the rules. At almost every single place I work it feels like I am the only one who has a real grasp on CSS and makes stuff happen.

My personal advice is to take a website you are familar with and try and duplicate it with pure css and html. When you get good at simply writing it from scratch then you'll be able to understand it easily. You'll start to notice the red flag stuff, the useless UI libraries (useful is relative) and stuff that you could get done on your own easily.

My most important tool is the element inspector for any browser that isn't displaying as I expect it to.

CSS isn't hard. It's design is broken on a few things which makes it look more complicated than it should.

I've done web for 20 years and I still Google around when it comes to aligning things vertically centered and I sometimes fall back to using tables for layout because it's still the most stable way to keep stuff at where it should be.

And of course the way you need to declare in a very redundant way for selectors on multiple elements is annoying but we have at least sass and my preference is using stylus (combined with pug) which removes a lot of those unnecessary declarations go away with the ability to define variables in 1 file and use it all over.

> Incidentally, but very likely related, I always failed to have any glimpse into how design works. I have no idea which colors "go" with which ones, and pretty much all fonts look like the same for me.

This is not related. There is no magic or natural connection between grokking CSS and having a sense for color theory or typography. They are connected by circumstance only, in that they're all useful for web design, and in that CSS can control colors and typography in the web browser. CSS is not any more an "art" thing than Javascript or C, although it is a thing with which one can make art (as are Javascript and C).

In reference to a sibling comment (https://news.ycombinator.com/item?id=19021837):

> CSS is very much like magazine or print layout IMO. If you're not used to that, it won't gel well. If you think of layout from a design perspective and _not_ a programming perspective, it's really not that bad.

Yes! I went looking for this comment before adding it myself. Although I chose not to reply, since that's only part of what I want to discuss.

Once I realized that CSS is exactly what would make sense for laying out a textbook, it clicked for me. Until a few years ago, web design implementation was hacking this model to realize application and widget layouts.

Nowadays, flexbox and grid are basically universal, and we can use them as we please to do proper 2-D layout, and then use classic CSS for textual flow. It's a wonderful time.

But to go beyond that mismatch of expectations, the other historical problem with CSS is how to organize it in a reasonable way. Typically, you need a number of rules to apply to related elements in order to achieve some specific effect, but these get all jumbled with other effects that need to reference overlapping sets of elements. Combine this with the fact that CSS offers a crap-ton of features that you rarely need, especially in the selector spec. Preprocessors and methodologies like SMACSS and especially BEM helped give us ways to tame the madness. The BEM website (https://en.bem.info/) is a great resource for this.

This is all front-end dev skills that most of us learned by thousands of articles and hard knocks. I wish I could point you to a bible for this, but I don't know of one.

When it comes to design, that's its own skillset, which really may have little to do with CSS. Many of the designers I've worked with don't know how to implement their designs in CSS (although that's not always the case). The principles of good design ultimately come from the goals of the product, mixed with usability concerns and, of course, fashion.

I'm also a seasoned back end developer. It took me 3 years to become a beginner at CSS, and two more to feel like I could finally style an arbitrary front end at an intermediate skill level. This is in comparison to 1 year to master javascript and another year to "get" React top to bottom. CSS was even harder to learn than ansible or clustered mongodb at scale.

I suspect it's a neurological difference. I've seen masters of CSS struggle with basic operational computing concepts that feel obvious to back end developers.

> I can't center my divs properly.

This is actually pretty simple, once you understand how "block" elements work. Block elements will always try to fill up the "available width" i.e., they stretch side ways. The sum of margin + its width must match the total width.

Inline elements will fill up its parent block like text.

So, a simple example - suppose you set a div's width to 100px, and margin to auto, then you will a 100px wide box centered.

I see people get confused when they try to have a block that has an unspecified width and hope CSS just figures out.

> This is actually pretty simple, once you understand how "block" elements work.

I disagree -- in this and every case where someone has told me that something is simple once you understand the fundamentals. Understanding how a tool works is completely different from understanding how to use it to accomplish a particular goal. One's a deconstructive process, and the other is a constructive process.

CSS positioning woes are brutal- until you have the knowledge from previous struggles.

Full disclosure, I am artistic, but imo css is a different skillset.

You'll have knowledge on when to use flex, floats, or the new css grid, be able to center <pictures> behind text, and all the other traditionally tricky things.

Honestly, just practice, don't give up!For layout specifically, Flexbox can solve almost any problem. Once I "got" flexbox I was having an easier time. And CSS-Grid can solve almost everything else!

I have a lot of aesthetic sense, and a strong eye for good layout and design. I still struggle every time I need to use CSS. I know enough to eventually make it do what I want with a lot of experimentation and googling, but not without a great deal of difficulty. I’ve known CSS whizzes who can make it do what they want easily, but they’re extremely rare.

I think it is just a really poorly designed framework. Other layout toolkits for native programming are typically far easier to learn and use.

The main things you should learn to become decent at CSS are:

- the box model

- how cascading, specificity, and inheritance work

- googling CSS problems with the site:stackoverflow.com filter

Bit tongue-in-cheek with that last one, but the rest will give you a solid understanding of why certain things work the way they do when your code doesn't look the way you expect.

> I can't do anything basic on CSS without turning for help

The thing is, if you are working with a whole website (even simple looking websites can have a lot of HTML and CSS), then there are often no "simple" problems, at least with layout, because every element can and often does affect every other element.

Sometimes you just need a good old analogy or picture to demonstrate some things: https://stackoverflow.com/questions/33132586/why-isnt-my-mar... (disclaimer - I wrote that answer). In a lot of ways, your elements and their CSS are like rocks in a river... the water/document flows around them in certain ways, which affects stuff around them or downstream. Removing one or adjusting it can change how the water/document flows, and thus can affect other rocks/elements, etc.

When I was struggling with CSS at my first job (2011), the thing that made it click for me was learning the significance of the `display` property and its possible values. After I learned that each `display` value causes the element to be rendered in a certain way, and that some CSS properties were only useful for certain `display` values, it became much easier to predict how the layout would look and to organize the CSS properties in my head.

For example, it cleared up a lot of questions when I learned that `display: block` elements naturally expand to the greatest width they can while matching the height of their contents.

Also, the Mac app CSSEdit (now folded into Espresso; https://espressoapp.com/) helped me learn the various CSS properties thanks to its GUI interface that listed properties by category, such as Text, Decoration, and Layout. It had icons for each possible value of each property that made it easy to remember what values each property supported. A useful feature of the app was letting me load an arbitrary web page and edit its styles with its GUI editor – I could see which properties were more often useful and how switching the between the possible values would change the look.

I arrived at CSS and HTML from a background in print layout with Adobe PageMaker and InDesign in the 1990s. Professional layout programs like InDesign attempt to separate content from layout and styling. The first step in creating a print document is to set up a grid of empty containers. The second step is to fill those containers with placeholder text (often Loren ipsum). Step three is to develop a style sheet to style the text so that styles can be updated in one place and applied consistently throughout a document. The last step is to flow content, written as plain text in an external copy editing tool, into those containers.

Coming from that background, HTML (the document structure) and CSS (the style sheet) are relatively intuitive. I can see how they were influenced by tools like InDesign. However, browser quirks are very frustrating. I try to avoid situations where I need to deal with them, or if I do I try to find CSS written by others that guides the way.

I think it’s probably unfortunate that screen layout techniques, where screens are variable size and interactive, were so heavily influenced by print layout, where pages are of fixed size. On the other hand, maybe HTML + CSS was too influenced by Microsoft Word style desktop publishing where layout and content are in a single document and not influenced enough by InDesign style publishing were layout, content, and structure are each distinct. But relatively few people are ever exposed to professional print layout tools like InDesign.

Having recently gotten into parametric CAD and constraint based design, I’m hoping to see more of that approach make its way into both print and screen design.

Yes CSS is too damn hard.

Too hard to learn? No. Too hard to use? No. Too hard to do elegantly? No.

It's too hard because it doesn't need to be nearly as hard as it is. Advanced layout can be done using techniques like pivot, relative anchoring and alignment, and lots of other approaches that CSS lacks.

It's too hard because what is there is broken. Even the new stuff (try to select a row in an auto-adjusting grid. You can't yet, and the powers that be will eventually fix that... which is ridiculous for a modern release)

It's too hard because it's neither how designers think, nor how programmers think, nor how users think. So you need to write it in some weird hodgepodge that accounts for none of those and all of those.

It's also too hard because due to the difficulty it takes a lot of time to get good at, and so we as non-CSS gurus don't invest the time we need to digest it... because why would we when it shouldn't require that sort of investment?

At the end of the day it's almost like going to your neighbor's house but some committee forces you to walk in zigzags and on your hands. It'll get you there, and you will become so good in the process you could work in a circus, but it's an unnecessary pain when you just want to drop off a cup of milk.

I was like this 5 years ago. It's trite and no one wants to hear it, but the basics go a long, long way.

All of that stuff you hear about in front-end interviews ( like the box-model and relative vs absolute positioning ) comes in handy.

I do admit that pre-flexbox CSS did require some wizardry and hacks here and there. I think "modern CSS" is quite enjoyable and we're able to enjoy a time where we no longer need CSS frameworks to do all the "hard work"

I remember times of supporting x-platform css for IE5/5.5/6 and FF1. IMO everything that people complaining right now is nothing with the Wild West that was back then.

Indeed, I think times and CSS has gotten much better. MDN's documentation is great, and browsers are finally starting to standardize.

People have mentioned flex and grid a few times. I would add using box-sizing: border-box; solves a lot of problems stemming css' default of measuring from the inside of elements that need to fit together from their outsides. See https://css-tricks.com/almanac/properties/b/box-sizing/

You can use JavaScript to extend CSS, to make it a higher-level language and _more_ declarative. CSS has live-updating variables in it which can be set and re-set from CSS, from HTML, and also in realtime from JavaScript. This means we can also include concepts from Reactive Programming and expose the streams of data directly to CSS in ways it can harness for styling purposes.

You can also extend selectors and at-rules in ways that allow you to define new, custom features, supported by JavaScript, and utilized from valid CSS stylesheets.

Given all this power and flexibility, you can go a long way toward turning CSS into the "styling language of your dreams". When you're extending CSS you also get to pick all the naming you work with as well.

Rather than trying to replace CSS, or abstract CSS away, it turns out the friendliest solution is to start with valid CSS and continue building on top it from there.

Check this out for more information about how to extend valid CSS with JavaScript: https://github.com/tomhodgins/caffeinated-style-sheets

CSS is best served along with HTML. I believe that one should understand the intricacies of HTML — the hierarchies in which one writes and the ability to think far ahead on how they will be treated on a page, container(s) or re-purposed by a templating engine.

HTML and CSS for that matter are very easy to start off. After a while, many begin to believe they are done; when actually, they are just starting off. It is one of those whom many would choose to ignore or use other tools to just “get it done”. A good designer, who can code, can do magic if s/he can go deep into HTML and CSS.

For instance, when developing interface designs for a complex or a big enough system, I advise my team to think of each and every block as something that is liquid enough to be thrown inside a container of varying possibilities. Test with few default container sizes but leave enough room that this can be just thrown in anywhere and will adapt to that containing block. This has become easier in React and other frameworks that encourage design thinking in modular blocks of designs.

Pre-processors, post-processors do help but one needs to be clear of the underlying philosophies and methodologies of CSS to appreciate these helper tools. Mastering these tool can then help work faster, smarter.

CSS is learned through practice, knowing the quarks and being able to make it work for 80%+ of the use cases. Break-up into smaller chunks of simpler blocks, have a styleguide-ish setup for yourself (if you don’t have one for your team), use development tools as guard rails. Finally, have a good post development workflow to get the final juice — task automation that removes un-used CSS, et al.

Imagine being able to get a column’s background color to extend equally all the way down the page in a 3-Column Faux Layout in 2003 (sometime around 2002-2004). ;-)

I picked up CSS last year because I always felt bad I never really put my time into it while I had to use it so often, I'm not a designer by any means but I like to experiment things out, but what I got from what I learned is that CSS works in its own way, it's not that much about "I want this div in this position" but more like "Everything in your page must flow a certain way" and from the experience I've had with certain inhouse "frameworks" it seems like other people dont get it either.

I think that in that sense CSS still irks me a bit, I still do a lot of things that just feeeel like a hack, but from what I search and google around it seems like that's the only way to do it? but I also think it's kinda fun, I like reading the MDN web docs from time to time and they do seem to explain things very thoroughly, I've had a lot of moments where things started to click after reading it.

> Incidentally, but very likely related, I always failed to have any glimpse into how design works. I have no idea which colors "go" with which ones, and pretty much all fonts look like the same for me.

I'd just want to point out this is completely unrelated: the best people I know when it comes to designing interfaces (both UI and UX) don't know much CSS. That's very much a creative field.

I can do CSS without many problems (nothing too fancy but slicing any interface or basic flexbox grids for layout and such). CSS isn't complex, just very foreign. Understanding the "rules" (cascading, priority) isn't hard, but knowing how to use it (how to target the element you want, what css to use to get the positioning/styling you actually want) takes a lot of practice. Though when it comes to creating a beautiful page I'm of no use.

Sure, CSS is hard, just look at the specs which define the height and width of elements: https://www.w3.org/TR/css-position-3/#size-and-position-deta...

There's a lot of complexity there.

Your frontend experience sounds like you've only dealt with web apps. Try making more web sites. That is, collections of pages that have enough content on them to scroll. Don't use any framework, don't even use JS if you can help it -- maybe something like PHP is ok to avoid some repetition (i.e. just use it for require_once of shared html). Then you'll understand the environment CSS was forged in. Ctrl+F the comments here for "box model" for the main "make it click" piece. (Edit: you might even want to try designing without CSS, to see what that's like. It's actually not that bad, and may well remind you of how things are typically done in frameworks these days -- a regression IMO, but a reminder that separation of design from markup isn't truly necessary.)

CSS isn’t bad after writing it a lot and googling the same tricks to do what typically works. My best advice is to stick to some framework for most UI (material or bootstrap) with using custom css seldom. Colors are definitely an art form and matter a lot.

Those are two different problems, imo, one is you don't know the language, and the other is design. I'm an artist and I've always understood design (not to say I was great at it, it still took experience, but I can see a site and I can understand why it does/doesn't work visually), so I can't speak much about how to learn it, except to first try to copy/observe from designs you think are good and go from their.

As for css. I actually like designing UIs from scratch so it's not like I hate it when I'm doing it, but it's bad. It's like 80% works as intended, but then there's 20% that is just weird quirks and there's no way around them but to memorize them. For example, I just ran into a particularly annoying one again recently (you can't do overflow-x: hidden with overflow-y:visible). This stuff is not going to change. At best they might add some new property to fix it. And the workarounds are often dirty.

I would suggest, A) keep a list of problems you run into and their solutions if they're particularly weird, even better, make fiddles of the solutions, and B) comment your css with why you did what when it's out of the ordinary. Sometimes you'll need to create extra wrapper divs, etc, and when you come back to a project after some time you'll have no idea why they're there or why you placed some weird css property, C) master flexboxes and grids and know their limits, that will get you 90% there usually.

Also using something like scss or less, or currently I'm trying styled components (css-in-js <- though it doesn't feel like it), really helps.

As for how related learning css and learning design are, I'd say, you do not need to know design to know how to use css, but you need to know css to be able to implement a design. You can get by without knowing design (there's plenty of css frameworks), but frameworks won't save you when you need to tweak them with css. Also you can practice design without knowing css (e.g. using photoshop or figma or something), although note many times nice designs are nightmares to implement in css, which is why I think learning css is more important.

> Is CSS an "art" thing?

No, but it helps to enjoy and respect visual layout challenges. Without appreciation of design, particularly web UI, you won't have much to aim for except MVP.

With programming, you are not usually switching back and forth between code and some visual layout element. CSS on the other hand, is an endless game of tweak, refresh, repeat. It's not for everyone.

BTW, Flexbox is now widely supported, and is much nicer to work with than trying to float DIVs, which nobody ever liked or found easy. Flexbox provides a nice way to center your elements horizontally and/or vertically, not to mention very nice control of spacing and item-level responsive sizing with flex-shrink.

It sounds like layout is your primary problem (as it is most people's). You should view (the layout-specific parts of CSS) as a layout description language, which is a class of languages you've never worked with before, and so something that requires significantly more time investment than just learning a new syntax (e.g. JavaScript). My guess is you haven't put in that amount of focused study, so naturally it doesn't click for you.

This is not to say CSS doesn't deserve any blame--it's a bad layout description language, as evidenced in part by the fact that the recent grid+flexbox additions are much better (where supported) than old-school CSS.

For me (maybe) its the size thing. I've never read anything about "content driven size" so maybe I just don't understand it, but I'm often confused about why some box (div) is the size it is. When I use dev tools to try to understand, nothing seems to help. I can see how the rules cascade, I see how the flexbox and grid things work, I can grasp the DOM and selectors - but then why is everything so small or so large...

The suggestion of building a page from scratch is good and helpful <BeginHumor>And the next time a CSS friend wants to learn JavaScript I will suggest they start by learning i386 assembly language :-) </EndHumor>

My wife is a technical designer for jeans and recently started learning web development because we moved and there wasn't much denim industry. She turned out to be good at CSS and I think it's similar to making jeans. From looking at the overall shape and style you can't easily construct a pair of jeans. People with artistic style can sketch a pair of jeans but to actually go from that to the specs that go to the factory (what a technical designer for denim does) is a different set of skills. Art is definitely a part of it but it's also a lot of tricks of the trade and processes, and this seems analogous to CSS.

Half the problem is that we got spoiled from WYSIWYG tools of yesteryear. Drag-drop-boom!-Done! But it turned into rocket science when dealing with web browser "auto-flow" and "responsive" design. Something that took 20 minutes in WYSIWYG now takes 4 weeks UNTIL you get proficient[1], and then the new different "in" layout framework comes along and you have to start at square 0 yet again. (Okay, maybe square 0.5 since some experience may transfer.)

It often seems like it would be easier to make 3 WYSIWYG designs for small, medium, and large screens. The device and/or server would pick the best fit of the 3. In other words, WYSIWYG x 3 < autoflow design time.

Reinventing 3 wheels is easier than reinventing one rocket.

Footnote 1: Often people fudge them to work most of the time, but glitches often show up over time as new browser or OS brands/versions come out and expose one's accidental fudging-based version lockin.

You are not alone! Beyond the bugs and inconsistency that web browsers implemented, I've always felt that css was unnecessarily over-complicated. During development on projects, it seems to be the thing that used to create the most hair-pulling frustration. But nowadays, i have learned to let go of some things, including any OCD feelings about css. Either i construct the most basic views, and hand it over to someone else who is willing to put up with css (and who is better at picking colors)...or simply construct the basic views - and stick to the bare/default view without any colors or complex css applied at all.

As anything, CSS requires practice. Imagine writing Haskell after having experience only with Python or C — you will probably expect it to be different — and difficult. You will probably want to read a book or two about Haskell, going from the first principles to real-world programs. Starting directly with real-world problems in Haskell will probably leave you frustrated and confused.

Perhaps you were never interested in CSS, and never gave it much thought; but it too has its own basic principles, after learning which it will be easy to say, like you want: "hey, CSS, this is the parent div, and all child divs must obey its size".

CSS is pretty simple and like a programming language you can overwork it to high complexity. And most people who aren't used to how to optimize it, just make a usable kludge of CSS.

When I first was going through CSS to learn it I thought it was the worst thing in the world - manly because many people had copied CSS without knowing what how to really achieve - or inheriting disparate css blocks which add to the confusion.

Once understood and starting from scratch, you can make it a lot more logical and flexible without much of a mess. My big tip - learn to break down style parts into separate classes and then combine the classes as needed!

First of all, CSS is t like any programming language. It’s a cascade of properties that is tightly coupled to the tree-like nature of HTML. You don’t ‘understand’ CSS on it’s own; it must be in tandem with suitable HTML.

Secondly, the visual aspects of design (colours, fonts, layout) have got nothing to do with your grasp of CSS. I am not a designer and really struggle to make pages look good without a professional’s help. But give me a beautiful design and I’ll code it up in lovely CSS for you no problem.

P.S. check out Tailwind CSS https://tailwindcss.com/

Seconding the recommendation for Tailwind. I know functional css is controversial, but Tailwind isn't dogmatic about it. Sensible defaults for colors, fonts, padding, etc. And unlike Bootstrap, when you use Tailwind, you're actually learning css instead of a framework. I feel like my css is a little better since I started using Tailwind.

CSS is hard. I like Colors but I find it really hard coding hand picking Colors and designing this game exactly the way I want. Sometimes the design will look like not the way I imagined and since I had put too much time, I have no choice other than accept it. Bootstrap 4 & mdbootstrap are great help but eventually prior pains of learning css helped to change or modify bootstraps. Now just looking for tools that would reduce the size of css files which I am using and remove the css content which I am not using. That kind of app will improve load time.

First learn design, then learn the tools(CSS). Preferably using a book that has nothing to do with web design. Problem with most developers is that we only learn the tool and forget to learn design. To understand how to properly mix colours, you need to study colour theory. To understand how to use the right fonts, spacing etc, you need to study typography. Also learn about image types. I don't understand why most web design books want to dive straight into CSS before design.

After that, you need hours and hours of practice in order to be good at it. We learn by doing.

> I have no idea which colors "go" with which ones, and pretty much all fonts look like the same for me.

Can't help on the fonts thing here, but for colors, there are a couple of things to consider. You can use color wheels of different kinds to find matching colors and harmonious color palettes to create/use in a color scheme. There are many online sites that provide this for free. While deciding on colors, you should also consider accessibility from the color blindness point of view and the contrast point of view.

I can relate to OP's lack of appreciation for fonts and color palettes - not 100%, but I get it. Color wheel tools are useful, and their results do look notably better to me, but using those may not improve your understanding of the color relationships much. But then, maybe you don't need to understand.

Colorhexa.com shows you how the color you chose is perceived by people with color blindness.

Applications are open for YC Summer 2023

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