Hacker News new | past | comments | ask | show | jobs | submit login
Learn CSS (web.dev)
842 points by markodenic on May 21, 2021 | hide | past | favorite | 189 comments



I'm the content lead for web.dev. Just wanted to give a quick shout out to the people who made this happen because it's not clear on the site. I think this is also useful information because you'll see that a lot of CSS experts we're involved in this project.

Adam Argyle [1] and Una Kravets [2] created the podcast series. Una mainly drove the overall project to convert the podcasts into this written series. Adam provided technical reviews on the written content and I also believe he created most or all of the self-assessments (i.e. the 'check your understanding' quizzes). Andy Bell [3] wrote all of the content (and demos, I think). Rachel Andrew [4] edited all the content. Rob Dodson drove the engineering work behind creating this new "courses" infrastructure on web.dev. I was hands-off on this project so I may not have gotten everyone's roles exactly correct, but I do know these were the main people involved.

[1] https://twitter.com/argyleink

[2] https://twitter.com/Una

[3] https://twitter.com/piccalilli_

[4] https://twitter.com/rachelandrew

[5] https://twitter.com/rob_dodson


It is interesting that this uses a podcast + text rather than what would have been a more conventional video based tutorial. The use of a podcast for describing something so fundamentally visual as CSS looks really unusual. I just started going through and came back here to note that it somehow seems to work well!


I wonder if videos are a little overused as tutorials. Videos aren't very searchable (yet), and they are unreliable to scan through (in most scrubbing implementations I've seen), so while they are nice to get started, they are hard to return to later to brush up on something.

I love this podcast + text approach in theory. A podcast to talk through the material, and a really well written page to reference. The CSS Grid page is a great example of this.

Aside: As someone who has been in web dev for a while, sometimes I feel like what I need is an "unlearn CSS" tutorial, to erase some old habits.


Yes, I found that odd as well, no plan to listen to 15 min podcast on a web-page when Im just trying to quickly learn something I need to know to fix my code. Though overall the aesthetics of the site are nice, very clean look and nicely organized.


Content designed to answer individual questions (eg StackOverflow) is often different in form than content designed to provide comprehensive education like college classes.


That's poor strategy when creating developer docs, no one wants to listen to a 15 min podcast when they come to a page to learn something or find an answer to their question. Most people on website are scanning for relevant information and they don't want to spend more time than needed, that is how good content should be presented.


Are you not aware that just because a certain piece of content doesn't suit you at this moment, doesn't mean that the content is bad?

In addition to yourself, there are other people in other situations who are looking for different kinds of content.


These are not developer docs first. There are plenty of wonderful other resources that serve as CSS dev docs as a primary resource.


I've listened to some of the podcast and it is really good, even in the car where you're highly unlikely to have devtools open.


At first blush, I like it a lot, and am eager to give it a try. I'm busy, and, no matter how much more efficient videos would be in an ideal world, I just don't have a lot of time to sit down and watch them. I also like to get away from the screen and go see what the outside world looks like every so often, y'know?

With a podcast, though, I can listen while I do dishes or whatever, and hopefully that will at least give me enough background information that I can understand the written parts more quickly.


Just as an FYI, I'm seeing a certificate error when loading web.dev. I'm on latest Chrome Version 90.0.4430.212 (Official Build) (x86_64) on Mac OS Big Sur

Screenshot: https://d.pr/i/gvj3fA

I've been trying to visit web.dev for days for various reasons, but I just get this and neither Chrome nor Safari will let me visit. But apparently a bunch of you can see the page, so I'm confused as to why I seem to be the only one seeing this... but maybe you or someone there can help? Thanks.


Very odd, I'm on the same release (Catalina) and no difficulties. The certificate is from Google Trust Services, which presumably Chrome should honor.

Perhaps you have a proxy causing interference?

As the sibling comment notes, looking at the certificate using Advanced may help clarify things.

Update: here's the full chain that I see:

web.dev, signed by GTS CA 1D2, with a root certificate of GlobalSign Root CA - R2.


This is what I see: https://d.pr/i/8VY9As

As far as I know, I have no proxies to interfere...


Apparently there's still more to see if you dig deeper, but I'm unfamiliar with Chrome's UI for invalid certificates.

If you can open your terminal, this may be easier:

% openssl s_client -connect web.dev:443

It will hang (I guess awaiting more commands) but you can use Control-C to kill the connection.

The gist below has the first several lines showing what you should see.

https://gist.github.com/macintux/68ab1317d4b7677951069baf95c...


OK, I think I see what's happening. There's some other software that overrode the *.dev cert. I'll remove that and see if it works. Thanks for your help!


Huh, that's...unexpected. My best guess was that somehow the root certificate was missing from your computer's trusted certificate store.

Glad you got it sorted, happy to help.


It was a fairly common issue when .dev first launched. https://andycroll.com/ruby/clean-up-broken-dev-domains-after...


Aha, interesting. Thanks.


Yup, that's exactly what happened. Thanks to both of you for your help! I really appreciate it. This was driving me nuts!


Open that Advanced button to proceed, inspect the certificate (click the lock icon in URL bar)


could be DNS of your ISP?


You have a bug on the focus slides where the first few buttons are actaully links to //web.dev and when you click them in order to give them focus the whole codepen iframe navigates back to your site.


Una and her content are great.

Checked out the first two chapters on this resource and immediately recommended it to my colleagues as well.


Hey Kayce! How come you no longer do the chrome dev tools update videos on YouTube?


I stopped doing DevTools docs/advocacy when I became documentation lead (content strategy + people management) for Chrome DevRel (the team behind web.dev, developer.chrome.com, Chrome Dev Summit, Workbox, and lots of other stuff) about 1.5 years ago.


This is amazing. Did y'all use any kind of static site generator or documentation tool (e.g. Antora) or was it hand rolled?


All of web.dev is open source. Here's the directory [1] for the Learn CSS content. The site is all based on Eleventy [2]. I don't know if Rob (engineering lead [3]) and team did any funny stuff for the Learn CSS infrastructure in particular but you can ping him on Twitter for questions.

[1] https://github.com/GoogleChrome/web.dev/tree/main/src/site/c...

[2] https://www.11ty.dev/

[3] https://twitter.com/rob_dodson


Thank you very much!


Thanks for sharing this!


Looks great! Small pet peeve regarding tutorials: When learning a new technology I don't care about the headaches people had 20 years ago. My first concern is how I use the technology and what it can do for me.

The section about layout starts with: "In the early days of the web, designs more complex than a simple document were laid out with <table> elements. Separating HTML from visual styles was made easier when CSS was widely adopted by browsers in the late '90s." etc. etc.

This history lesson is not really relevant for newbies. It is basically a "you kids have it easy, when I was your age...", something which every generating find really tedious to listen to, since it is irrelevant for their current situation.

Knowing history is fine when it is relevant (e.g encountering legacy code), but it shouldn't be the first thing in a tutorial. Put it at the end or in a footnote or appendix.

I think it happens because writers tend to explain stuff in the same order they learned it themselves. But this is not always the most natural order to learn things for newcomers.


Nah, I think the history is important, especially for web development where modern tech stacks are technologies built on technologies built on technologies, and pretty much everything has to be backwards compatible.

I've run into so many situations while learning web development where a design decision seems like nonsense until later when I learn about the history of how it evolved. First example that comes to mind is the `===` situation in JavaScript.


History can be important, but I don't see what knowing that developers used to (ab)use <table> for layout explains about modern CSS. By all means, include historical context if it helps explain why something works the way it does, but otherwise drop it.

And while backwards compatibility remains a concern for browser vendors, it's much less of a concern for web developers nowadays given the vast majority of users are using auto-updating browsers. Indeed, the purpose of this guide appears to be an explicitly "evergreen" guide to CSS, targeting only the feature set of modern browsers. If you're using grid, custom properties, conic gradients, etc. you're not writing backwards compatible code.


tables are still relevant for layout if you work with email at all. In fact, if you want to be able to do email well, you have to be able to do layout like it was 10-20 years ago. There's also lots of legacy code out there to be working with, and sometimes the "old way" of doing it is still better than the new way. A pet peeve of mine is seeing flexbox everywhere, when a simple 'display: inline-block' might work. In my opinion, it's all still relevant so long as it still exists as part of the language.


Email is a different can of worms, but it does not just correspond to web design 20 years ago. You can use a lot of CSS in email, but in a different way and under weird constraints with never exited on the web.


I resent the "(ab)" in "(ab)use tables for layout"... it was all we had AND was still better at vertically centring things until Flexbox arrived!


Abuse only in the sense they were not designed for this purpose. Like people using <blockquote> to create margins.

It is like using a screwdriver to knock in a nail because you don't have a hammer - better than nothing, but not what a screwdriver is designed for.


A table is an extension of a grid and therefore actually in the same ballpark as the proper tool for layout whereas using <blockquote> to create margins is totally random (though perhaps someone could stretch an explanation).

It's of course pedantic to discuss all this now as those days are thankfully long gone :D


I think it adds a lot of colour to a relatively boring part of the tutorial


I'm confused why the web standards don't include something like a version header for JS and CSS. That's an easy way to eliminate cruft and silo the logic in the browser engines.


How would that eliminate cruft? Browsers would still have to support old version for backwards compatibility. Much better IMHO to extends the languages in a backwards-compatible manner.


It's also useful to be able to know what you're looking at when reading code that others have written.


Exactly this. When you're starting something _new_ it's possible that you don't care at all about the history. It's when you inherit something _old_ that the history becomes very important.


My peeve is really about how to structure teaching. Teachers often seem to forget how they learned things themselves. You learn a programming language by diving into it it and making things work - not by first studying its historical roots decades back.


I think it depends. Anecdotally, I personally feel very unanchored and semi-anxious when someone just dives in to the explanation of "how we do it" without the context of why we do it this way and how we got here.

I find it similar to the use of acronyms. When an explanation introduces domain-specific acronyms I always ask what the acronym stands for. It's important to me because just memorizing key "ABC" and associating it with some kind of outcome forms a very weak bond in my brain. If I know what the acronym stands for, the bond is far stronger and larger pieces of the picture are revealed. Interestingly, I find that when I ask an explainer what an acronym stands for there's a couple classes of responses. In my experience, most are simply that the explainer doesn't know. And among those explainers, most don't care. But some will be curious and look it up. A few will know and you can tell that they find it important too. Fewer yet, will explain the definition when introducing the acronym and maybe even comment about its origins.

I'm guessing that these classes of people would also correlate closely to those who prefer turn-by-turn directions vs a route on a map with the full context of other routes in the area.


> The section about layout starts with...This history lesson is not really relevant for newbies.

so folks know what we're talking about:

https://web.dev/learn/css/layout/#layout:-a-brief-history

It's four (pretty short) sentences that give a small amount of context pretty quickly and then links to another resource if you want to know more. I'd agree with you if it were a page or two's worth of history, but there's not much to find distracting here.

More importantly I think you're focusing on the newbies who are coming in with nothing but ignoring the newbies who are looking at existing code and a whole bunch of tutorials and stackoverflow answers out there written over the last two decades. Acknowledging that things have changed in CSS quite a lot in that time and pointing to where they can learn more means you don't distract the really new newbies much but you also don't confuse the other ones, leaving them with lots of questions ("but I read [this] about CSS...") and no idea where to look to reconcile some old advice ("use jquery for all styling!") with what they're learning now.

But it's also four sentences in the eighth chapter of a tutorial. It's not going to solve all confusion but it's also not a derailment.


But there are many generations of cruft. Table-based layouts is just one thing, how about font-tags, quirks-mode-triggering doctypes, frames, float-based layouts, <!--[if IE]> and so on. Each of these might by necessary to understand in some very specific cases of legacy code.

I'm just saying: Don't put this up front in a tutorial.

Don't explain GOTO before explaining if-else blocks.


The contrast helps me.

As someone who made/hosted Web 1.0 websites, isn’t a software engineer, and has over the past few years tried creating/hosting websites again, things got a lot more complicated in the interim.

So I hear your perspective that it sounds like some old person is yelling get off my lawn. No one wants to hear that.

However, for someone like me who didn’t have CSS, the slight history lesson is helpful.


Don’t agree. Historic context is important to understand legacy codebases, code examples in other resources and colleague’s behaviors.


Yup I think this is the most important piece of why new students should know about this, if they ever touch a legacy codebase.


Very few legacy codebases from the tabled 90s still using tables. Yes, a few exist but not that hard to grok.


Sure, but that is an advanced subject. Don't put it before explaining what the technology actually does!


The historical context can be important, but I agree that it can get in the way of the learning for CSS newcomers. I think there's a happy medium here. A link to a separate article or reference of the history would get it out of the way but offer context for those that seek it.


This history lesson is not really relevant for newbies.

If you're working on a new project that's true. If you're working on an old project, and bringing it up to date, then understanding the code that's there is very useful. That starts with understanding how things were in the past, and why people did things that might seem a bit crazy (eg spacer.gif).


You still need spacers in 2021 to add bottom padding to CSS grid:

https://github.com/w3c/csswg-drafts/issues/129#issuecomment-...


Specifically with CSS, if you omit this, the first logical question of anybody who attempts to learn it is "wtf, why does it work in such a stupid way".

Basically, historical context helps to cool down natural negative reaction.


CSS and Javascript both. Forget legacy codebases, people seem to forget how much legacy documentation, tutorials, and Q&A is out there confusing newbies who don't have the context to know what's no longer relevant or accurate.

In answering questions from actual newbies completely new to this, I was a bit surprised at just how much I took for granted because I was around for the historical context.


I think it is more helpful to explain why thinks work the way they do.


It is relevant in html emails, which are basically a time machine to inline styles and table layouts if you want consistent rendering. This would make no sense to a developer unless they understood the progression to where we are today.


Email development is pretty niche and its own category of expertise. CSS straight up doesn’t apply there the way it’s used regularly (via selectors)


Totally disagree. In a technology with a long history, especially one that never breaks backwards-compatibility, a whole lot of things seem nonsensical without context. And this isn't just relevant for apologetic purposes: seeing and internalizing the patterns and the internal logic often requires that background knowledge.

Think about when you're learning to work on a legacy system. You (hopefully) don't just learn the current state of the system in a vacuum. You go through and learn the history of decisions and constraints that got it there, the layer upon layer of changes that resulted in the end result in front of you.


In my view, if you have made it through to module 8, you're not going to be put off at that point by a single paragraph explaining the historical context. If it was the introduction to the whole course, you might have a point.


I disagree. I like to learn about the history and motivations behind a technology. It gives me context and helps me to remember facts that would otherwise be hard to remember, besides being enjoyable.


> This history lesson is not really relevant for newbies.

I disagree. Knowing the context and motivation behind why a certain technology was created is always helpful for learning.


Funny, this very page you're commenting on uses tables for layout.


I see the reason for people’s disagreement, but with a very important exception:

Sometimes new ways of doing things completely free us from the friction of the previous ways, and people who do not already have those scars have the advantage of being unrestricted by them


Consider that part of the audience are developers who've dabbled in HTML/CSS over the years, but never frequently enough to stay current. We have old habits to unlearn. The context helps.


> I don't care about the headaches people had 20 years ago

Hard disagree. Especially with technology, what we have today doesn't usually make much sense unless you compare it with what we used to have: everything started out the simple, but naive way, and evolved out of combat-tested lessons learned to what it is right now. If you don't know what those lessons were, a lot of the design decisions that went into what you see will seem mysterious and, possibly, pointless.


I've worked on a lot of legacy codebases that implemented some of these older design patterns. Understanding the history is essential to knowing what to replace it with.


> When learning a new technology I don't care about the headaches people had 20 years ago

I do. This really puts things into context for me. If I don't get that when learning something, I will look for the answers later. So I'm very happy when it's right there to begin with.


Sidenote: This may be a case where the kids don't have it easier today, as many people I know say that tables were much easier than today's CSS3+ grids and flexbox layout systems.


I don't want to pile on here, but give another reason why you might care how people did things 5, 10, 20 years ago: you're likely to encounter that code at some point.


I think attitudes like this are why so many people don't respond well to math


In terms of Flexbox, this guide in the React Native documentation is BY FAR the best guide I've seen anywhere.

It tells you just the right amount of things you need to know to be productive. https://reactnative.dev/docs/flexbox

It's not React Native specific. It works for web-based CSS as well.


That's a nice site to learn. This is my goto reference (they even sell it as a poster).

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


Essential supplemental material: https://css-tricks.com/flex-grow-is-weird/


This is my favourite resource for learning about flexbox: <https://flexboxfroggy.com/>

And this for grid: <https://cssgridgarden.com/>


I've learned flex using similiar game, some kind of tower defence I think, it's astounding how quickly I memorized these things compared to standard learning by reading


Agree. I think you're referring to this: http://www.flexboxdefense.com/


Theres also a flexbox tower defense site that was pretty neat iirc. Similar concept/way of learning by gamification.


I often find this flexbox cheatsheet handy https://flexbox.malven.co/


I've always found CSS infuriating to use when working with it (albeit not often). This looks like a clean and easy to follow course so will be one for me to look at over the weekend.


I think most web users wished web devs understood CSS better (even if they don't know what it is.) I'd be willing to bet half the stuff things like React are used to do could be accomplished much better with a small amount of CSS and probably no javascript at all.


I’ve seen this more times than I can count…

A lot of people think of CSS as if it’s not code itself. Modularize it and create patterns like you would for any other piece of code(ie. react components), and it becomes fairly straight-forward to do things that would normally take 100+ lines of code in JS, in just a fraction of the time and code.


Could you give an example? (not trolling - genuinely would like to see where the Venn Diagram between framework and CSS lie)


Animations, even 3d ones, drop-down, sliders, static scroll elements, are often implemented on horrible js with bad performance and accessibility, while trival with a small amount of css.


Sadly, the trivial CSS solutions are often not supported by some browsers that a lot of people use (apart from the obvious IE, Safari on both Mac and iOS is possibly the worst offender for this), making the godawful JavaScript solutions a tragic necessity.


lmao Safari is just fine


Safari is the bain of my existence and owes me money for the sheer amount of time I’ve had to invest in working around their god awful css and svg engines. PWA my a*.


That's fine, I didn't think you were trolling. But I'm not sure what are you an asking an example for? Do you want me to write up a comparison or just tell you some cases where HTML/CSS is lighter than JS? I'd honestly just recommend building a flashy animation primarily with Javascript and then try and build it using only HTML/CSS. Most of the time it will be easier and more readable to go with the latter, as well as more performant and likely to stand up to the test of time.

There are definitely a lot of times where Javascript makes sense, but what I really just wanted to point out is that people usually default to 'Well I'm already writing tons of Javascript, I may as well write more!' as an excuse to create simple animations or transitions with dozens, or hundreds of lines of code, or bringing in a dozen external dependencies to handle it that also break in weird ways. I'm definitely not a NoJS zealot either -- I've been working primarily with React code full-time in production systems since 2014. But over time I've found CSS to be far more pleasant and faster to work with than testing, maintaining, and/or relying on someone else to do the same thing in JS.


I wish you were right, but this is unfortunately wrong – and it's not because developers don't know CSS well enough, but rather that CSS is just plain not good enough. And ridiculous new features keep being added to it when we still don't even have some of the necessary primitives that should be there.

As an example, one of the most basic components I can think of is an accordion. You simply can't make one that works in a visually pleasing way (the way most people would expect!) in CSS because you can't animate to or from `height: auto`. The best you can do is some cop-out technique of fading out or squishing the content with `transform` and then having the content that follows it do an immediate jump up/down.

Instead, animating an accordion that actually animates the layout around it smoothly absolutely does require JavaScript, to tell CSS what non-auto values it needs to animate to and from.

And that's just the most basic component I can think of!

Another example: anchoring one element to another, when those elements don't have a parent-child relationship. Think tooltips. This requires JavaScript to measure the anchor element's position on every goddamn frame and keep the other one in sync, when the layout engine already has all the necessary information and could easily be built into CSS.


The implication here seems to be "when using HTML semantically", because I think everything you're talking about can be done with CSS if you're willing to abuse HTML.

Take this CSS accordion which uses hidden form elements: https://codepen.io/raubaca/pen/PZzpVe

I agree that if you want to use HTML semantically *and* have intuitive UX/UI, you're very limited in what you can do without Javascript, but this isn't *just* a failing of CSS; rather, I think it's due to the design of HTML and CSS historically being to the exclusion of the other, rather than with a symbiotic relationship in mind. Go far enough back into the history of web standards and it kind of makes sense though; HTML and precursors had been in development for years before CSS was standardized


I appreciate the semantics angle but I don't think it's actually related; semantics are a separate issue.

The reason the animation appears to work in the example you link to doesn't actually have anything to do with the form elements or semantics – rather, it's cheating by animating the `max-height` of the tab content from `0` to `100vh`.

This can be done just as easily without all the form stuff, but it's a bad solution to the accordion animation problem, because (1) it assumes that accordion content will never exceed the height of the viewport (what about on phones in landscape mode? you're only talking a few hundred pixels there), and (2) CSS will ease between the actual minimum and maximum values without regard for where the element's true height actually stops changing, i.e. it will animate from 0 to 100vh in the duration requested even if the height only ended up being like 20px and thus visually stops changing 5% of the way into the transition – so whatever duration and easing you specified isn't actually being rendered in the way that you wanted. If you specified an `ease-out` for example (starts fast, slows down at the end), you'd just get a super fast linear-looking transition that ends much quicker than you planned and never has the slow easing at the end (because CSS is actually still transitioning the `max-height` property which is no longer having any effect on your element that's much shorter than the max-height).


>accordion. You simply can't make one that works in a visually pleasing way

Well yeah, you can't do it in pure CSS because you can't do most things in pure CSS. The HTML element you're looking for is "details." (this seems to be one a lot of react people miss.)


I'm well aware of details (I use it in GitHub READMEs frequently), but you still can't animate it like I described – without that, no designer is ever going to want you to actually use it. Builtin elements are worth fuck all if they don't meet your requirements!

You a moment ago:

> half the stuff things like React are used to do could be accomplished much better with a small amount of CSS

you now:

> yeah, you can't do it in pure CSS because you can't do most things in pure CSS


I've gone down that rabbit hole of pure-CSS components, frankly its a worse maintainable nightmare than using JS where appropriate.


Admittedly I’ve never been very good with CSS particularly the “newer” layout stuff I’ve never really used or learned.

That being said I’d rather use CSS than the abomination used for styling in WPF.


This guide doesn't have any exercises. There are a handful of "check your understanding" multiple-choice quizzes, but what's really needed are "make it look like this" interactive assignments.

For that, I strongly recommend "Flexbox Zombies" and "Grid Critters" by Mastery Games. They're good games, and excellent educational resources for learning CSS layout.

https://flexboxzombies.com/p/flexbox-zombies https://gridcritters.com/


I've essentially made my career with CSS. I've been hired solely because of my CSS skills. I am continually surprised when I interview engineers proficient in Angular / React / JS but they cannot even do a basic full page layout (think header, footer, and two adjacent content areas in the middle ). Anyone starting from scratch to try to get a career in web dev become great at CSS - its a niche no one seems to want to learn


Ditto; my first career break into the web app development world came from a friend who is a really talented developer although he had never heard of flexbox. I quickly helped him fix a frustrating layout issue and he got me a job developing a React app for the government. I didn't know React at the time although I've learned a ton since. All because I spent years messing around with CSS.


Hey! Glad to meet another member of our club :)

I unironically love CSS and I once got a contract gig doing nothing but CSS for a PWA, because their front-end dev didn't want to or couldn't (can't remember) do it


This guy does some seriously awesome stuff with CSS, but a lot of it is in the "Don't try this at home, kids." category.

http://www.cssplay.co.uk/

Look at "Demos" to see what I mean (http://www.cssplay.co.uk/menu/).


Does anyone have recommendations for tutorials/books/courses that go beyond explaining the basics of CSS to how to actually design stuff with CSS. I've gone through numerous this is how Flex and Grid work, this is list of all the options for Flex and Grid, this is why we used tables in the old days and Float had it's problems. I'd like to learn how to use the building blocks of CSS as they are now and ... you know be able to learn how to make nice looking designs.

I realize to actually get good at design requires elbow grease and practice, but it still would be nice to have a good teacher/guide to show you how things are done now.


In practice, most FE jobs consist of a designer that produces mocks in Figma or InDesign or similar, then you as the engineer take those mocks and make JS+CSS out of it.

As for what the designers do, it's mostly copying ideas from popular apps and tweaking it to appease the product people, who are requesting changes to appease leadership.


You are to the point where you know what CSS can do, and can work your way through building out UIs. From here it's about adopting a system, and a system that will work well with your needs.

Are you building in a react environment? Are you building WordPress websites? Are you just building simple landing pages? Are you building in a team environment? These could all have different solutions, they could also use similar solutions.

But you need to decide how you want to think about CSS. Which to me, is atomic vs component driven.

Atomic is building small reusable classes, then use those classes everywhere in your HTML. It keeps things consistent. [Tailwind CSS](https://tailwindcss.com/) is the winner of this race at the moment. Lots of people are moving to it. There are solutions for standard CSS, SCSS, or even working with it in React type environments.

Component driven is how I think of BEM, "Block Element Modifier". Break things into reusable components, keep your naming structure consistent according to BEM specs.

I personally prefer BEM type of process (break your pieces into components), but with usage of utility classes also, these can be thought of as atomic (one use, like text-align: center;).

I'm going to try Tailwind on a project soon (I've been following it for years), but I will still think of it in a BEM type structure. Things get messy in atomic when you have complex UIs that have different needs across device sizes. I personally have a hard time looking at HTML when one element could have 10+ classes on it if you go pure atomic.

I've kept things consistent without Tailwind with my own set of config (for things like colors, units, font stacks, z-index stack, etc), then various helper functions for things like keeping breakpoints consistent.

There are lots of great resources (look up atomic css and BEM css), you should browse through many of them to get a well rounded picture of how people work with CSS.

But figuring out how you want to think about CSS and putting a system around it seems like where you are. I recommend trying various methods out, and see what works best for you. Just be flexible if you are in a team environment. A team sticking to a defined standard (even if it isn't your favorite) is better than lots of competing standards.


I thought this book was helpful https://www.refactoringui.com/book


Perhaps what you really need is a Designer. I know I just like my work better when other people get involved. When I code up really awesome CSS, there's usually someone else involved. Until then stick to something like bootstrap that hands you some basics, but still allows you total control at the end of the day.

Perhaps Tailwind is another option? Use a system to make an MVP or wireframes, then get someone to pretty it up and give you a PSD, Zepplin or Figma link.

Or for a DIY angle look into 2D Design, Print design and Desktop Publishing. Design a business card, that kind of stuff is the old school of user interface. Typography is another hot one, studying communication is the key to getting good.


I struggle with CSS. I am not sure it's CSS that's proving difficult or the ability to design anything even remotely presentable. I suspect my struggles are more to do with the latter. Looking at good designs and trying to derive a variant that works for me turn into incredibly frustrating exercises. Let me see if this content helps.


I'd second doing this tutorial. I think what they have is terrible for somebody brand new to CSS, but for a developer who has worked with CSS and still not quite put it all together, this tutorial is great.

For me one of the keys to "getting" CSS, and I think is the hardest, worst part of CSS, is understanding all of the implicit contexts that are generated. For example, elements have positioning roots. Nowhere does this word even show up in the CSS language, you have to know that it's created whenever an element has a position that is not static.

Similarly elements have a stacking context which is hugely important to understanding z-index and transform. Again never explicitly mentioned, inststead stacking contexts are implicitly created by a variety of actions like setting an element's background color to anything with a non-zero opacity.


Thanks for the details. Will definitely go through this tutorial


Unless I'm mistaken, a subject is missing from this course: media queries. It is briefly mentioned int the "Grid layout" chapter, because one can build a responsive row/column by using functions like `minmax()`, but there are many cases where media queries are still needed. Outside of this course, web.dev has several articles about this.


In my experience media queries are more often used incorrectly than correctly. Any responsiveness that can be modeled as a continuum should be; only truly discrete changes should go in a media-query. Something like, "The entire menu bar goes away and gets replaced with a touch-friendly version". They're good to know about, but they can be a footgun for beginners.


I've always wanted to write my own CSS guide, because (in my experience) people are rarely focused on the right thing when they're writing CSS.

Developers (especially junior) think that if it looks right, that it is right, and they're done. But CSS is not just specifying how something looks, you are also very much specifying visual behavior, not just appearance. Content is dynamic, layouts change at different breakpoints, new elements come and go, another dev comes in and adds something later... you need to account for all of these things.

For example, a developer rotated an element using CSS transform because the library we were using only supported a horizontal layout and not a vertical one. Sure, everything looked right in isolation, but now this element doesn't play nicely with others, because transform only affects the visual position, not the offset position of the element, so all its siblings still think it's horizontal, and they're getting all jumbled together.

Or, using absolute position to, say, anchor a close button to the top right of an element. Sure, the way you did it happened to put it visually in the right spot, but it's not actually in the right spot according to the layout engine because its offset parent is not the element you're trying to anchor it to, so if other content gets put in there eventually, it will be in the wrong spot.

Or, they'll use `line-height` to add space around some copy, without thinking about how that text will now look when wrapped.

So in my opinion, any CSS tutorial worth a damn needs to hammer home that (1) just because it looks right doesn't mean it is right, (2) you can't really ever style an element in isolation, you need to think about how it interacts with its parent and sibling elements, and (3) elements actually have two different positions, one that you see, and a potentially different one for layout.

Knowing those things is key to understanding whether you've designed things "correctly" vs. something that just happens to look right in the moment.

(I've only skimmed this course so far, so I'm not sure whether it satisfies what I want. But I'm hopeful!)


> Or, using absolute position to, say, anchor a close button to the top right of an element. Sure, the way you did it happened to put it visually in the right spot, but it's not actually in the right spot according to the layout engine because its offset parent is not the element you're trying to anchor it to, so if other content gets put in there eventually, it will be in the wrong spot.

I'm absolutely guilty of this one and would love to know the correct way to do it if you have a resource handy. I generally feel like working with CSS (or ideally Tailwind now) is an uphill battle. In my defense I would also give the container a padding which should (in theory) prevent any of its statically positioned children from overlapping. But as a full-stack developer I often feel like this is the domain of people who spend their entire career focusing on design, and generally when I'm working in this realm its because we don't have one of those people.


Sorry, my description of that one was a bit vague. The error I had in mind wasn't using `position: absolute` to anchor the button, but rather in not thinking about the offset parent.

As an example, if your goal is for the button to appear over the right-side inner box ("hero content") here:

    +-------------------------------------------+
    |+----------+  +---------------------------+|
    || nav      |  | hero                      ||
    ||          |  |                      (x)  ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    |+----------+  +---------------------------+|
    +-------------------------------------------+
...then you should make that button either a direct child of that hero content (and give that container `position: relative` to make it the offset parent), or if that's not semantically acceptable, then add a new container around the hero content which will match its size/position and serve as the button's offset parent.

Otherwise, if you just let the outer container be the offset parent because it happens to place the button in the same spot in the moment, then later when more content gets added to that container, you'll end up with this:

    +-------------------------------------------+
    |+----------+  +---------------------------+|
    || nav      |  | header                    ||
    ||          |  +----------------------(x)--+|
    ||          |  +---------------------------+|
    ||          |  | hero                      ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    ||          |  |                           ||
    |+----------+  +---------------------------+|
    +-------------------------------------------+

...where the button is no longer over the correct box, because it was never anchored to it correctly in the first place (instead, it was anchored to that outermost container).


Ahh OK, interesting. That seems like more of an HTML issue than a CSS one (putting the close button element outside of the container element which it's associated with). I'll carry on doing things the way I already do then.

Thanks for the detailed response


Note that if you set `position: relative` on the container element, the button will stay in the right position no matter where the dialog (or whatever) moves later


It has everything, a clear thread, podcasts, code areas and a simple quiz. Really nicely done, thank you, Google!


This looks good. I've been using mdn mostly; but I usually go deep into CSS for a bit then leave it for long periods of time.

That said, what has replaced SASS? I'm struggling to find a preprocessor that allows nesting/grouping etc. Or is that built into CSS by now? Being able to nest CSS was a game changer for me in terms of css organization.


Nesting is not possible in vanilla CSS. However, there is an Editor's Draft about it which has gained some momentum recently.

https://linkedlist.ch/ref/25/


Nesting is still not possible in regular CSS. In fact, it's the only reason I still use Sass—I don't use any of Sass's other advanced features.


The function stuff is pretty sweet. EDIT: By that I mean "mixins"


I'd say that "nesting is bad" has replaced SASS. Nesting encourages long selector chains which are generally a bad practice. That CSS makes this painful is a nice reminder to only use long selector chains where necessary.


Sass still has a lot of popularity in the BEM world where you can use nesting to generate flat classnames that would be tedious to write out by hand, e.g.:

  .element {
    &__title {
      color: red;
    }
  
    &__subtitle {
      color: blue;
    }
  }
which compiles down to:

  .element__title {
    color: red;
  }
  
  .element__subtitle {
    color: blue;
  }
There's a lot of (valid) criticism that this makes code harder to grep, although if you structure things well it's still easy to find via the base element class. BEM and approaches like this in general tend to require a lot of discipline and organization to pull off effectively.


This is where I'd step in and argue BEM is a terrible idea. Any time you're encoding hierarchy like this into strings you have failed. BEM is the worst of both worlds since you have higherarchical class names and you have still created CSS that's heavily dependent on the hierarchy.

CSS wants you to write:

.element.title { color: red; } .element.subtitle { color: blue; }

Any technique that depends on discipline and organization has already failed.


I don't think CSS has any particular preference, which is why there's so many different ways to approach these problems. But I do agree, I don't think I've ever worked on a BEM codebase that didn't end up messy, and the disciplined approach almost always means making tons of small naming/organization decisions as you code, which is tiring and difficult to maintain.

People scoff at CSS-in-JS and atomic approaches like Tailwind (although Tailwind seems to get a lot of support around these parts now!), but I've really come to see the value in side-stepping these issues entirely.


CSS does have a preference.

CSS has absolutely 0 knowledge of your BEM hierarchy, they're just different names as far as its concerned. The developer has just chosen to pretend that a hierarchy exists where there is none.

CSS cannot do trees, but it can do logical AND and OR, so you can somewhat express a hierarchy as a union of the different levels of your tree, so

.button.login.green has a logical meaning in CSS where .button__login--green is no different than using .pinapple as a class name.


Fair enough, I think it's safe to say that CSS has a skew towards the cascade and I guess I misunderstood your original meaning there.


I see. That just goes against the way I naturally think, unfortunately— which is why I thought SASS was such a great breakthrough. I do understand it, though, because when I want to modify something in some over-written hunk of garbage CSS it is a real pain to try to get the selector that actually works (thank god for dev tools).


One of the challenges with CSS is that it has so many ways to do the same thing, and it needs that because there are so many different workflows.

If you are in an environment where you have 0 control over how the HTML is structured I can see where long selectors are helpful, but when you do have full control over the HTML they are a huge anti-pattern.


Agreed, if by "helpful" you mean "painful but necessary because the asshole that wrote it didn't put a unique class on the main target of the div." But nesting doesn't necessarily imply long selectors, if done properly IMHO. If I have full control, I can put a class on the likely-to-be-selected element (ultimate target- the content) that allows me to get to it immediately so that I can, say, change the font.

In other words, I like nested CSS when I have a nested structure on the page. Then each class relates to one thing, and I can maintain continuity of the outer containers (say) as I change the inner ones.

In the old days, we didn't have column inside of content inside of page inside of ..... We just had whatever we had and css nesting wasn't as logically congruent with the structure.

Now, though, we have hugely nested pages (which stinks, but whatever), including a lot of inline-written CSS and the only way to get to it is long selectors. I agree it's an anti-pattern.

But you can have nesting and not require long selectors. And if you do need them for some god-forsaken reason, they are easy to find from a SASS structure.


Thank you. I have this ongoing goal of learning to front-end. JavaScript has always made sense. Frameworks change, but it generally follows CS principles in a way that I can understand. But CSS just breaks my head. This looks like CSS broken down in a way that I can digest it. Thanks again!


I've used CSS for close to 15 years. I've just never got around to really learning how it works. Every time I have to do it I manage to just about get by without actually learning it for real. But it's frustrating. I think it's about time I learnt it for real.


> I've used CSS for close to 15 years. I've just never got around to really learning how it works.

Same here. This also happens in other fields; my brother is a journalist, and most newspapers (here in Norway at least) fired most of their photographers when the industry suffered due to online papers not generating as much money. They thought it's easier to learn a journalist how to take pictures, than the other way around. I feel that most people who create webpages think similarly, i.e. it's easier to make the programmer learn how to create a good design + CSS etc. than learning a designer how to program... Both newspapers and webpages have suffered from these ideas I think; but money talks...


This has also been my experience. I have found that I don't mind writing Javascript, but my lack of strong CSS knowledge prevents me from building more front-end stuff.


it's just like not learning how your IDE works. You can coast along OK, but it's like you have sand bags on your feet. It's amazing how few devs actually know CSS; In my opinion you can really stand out if you're willing to spend a couple afternoons learning concepts like the Box model. CSS/HTML is much easier to work with when done correctly, too.


I'm glad someone is working on better CSS tutorials.

The place I have the most trouble is getting content inside a flexbox to fill the box, especially when making a single screen app where I want various "panes" and I want the content inside to fill those panes.

For whatever reason I still haven't completely figured it out and it's always trial and error. Sometimes I need a "min-height: 0" and other times it seems like I need a "height: 100%;" and a maybe a "position: relative;"

I wish (I should probably write this myself), I wish there was a way of specifying the areas and their constraints and then have that translated into the appropriate CSS.


I never really "got" the float model for layout, so Grid is a welcome improvement these past few years. That said, this is still missing the one thing I've yet to find in any discussion of CSS.

How to appropriately size text. No -- for the 1,000,000th time -- I will not use Modularscale, which feels obtuse to me. Using some formula on a website that someone says works also feels arbitrary. Not to mention that the SASS implementation hasn't been touched in years.

With Grid, I felt like it was the first time I saw someone create a layout where it was obvious what was going on. I have yet to see something like this system - but for text sizing.


What exactly about sizing text causes issues? Do you mean fluid/responsive sizing?

AFAIK, the best modern way to do it is `font-size: clamp(0.75rem, 1rem + 2vw, 3rem)` (the use of rem as well as vw is to not break zooming for accessibility)


Pretty much.

The thing that really made Grid sink in for me was seeing the pseudocode at Grid By Example [1], showing how each of the different constructs work.

[1]: https://gridbyexample.com

Jason Santa Maria's On Web Typography [2] originally included a "worked" example that you could put into a page and pull apart to start building similar things in your own projects. However, before it shipped, this section was dropped.

[2]: https://abookapart.com/products/on-web-typography

With calc and clamp now in the mix, it seems as if we no longer agree that 1rem=16px even if px is probably the most precise screen unit we have.

"Uh, pixels aren't responsive, so let's not even mention them."

It's not the end goal, but it feels like we're throwing away the map which could explain how to reach said goal.


Never use viewport-relative units (like vw) for text sizing, it is not a best practice for accessibility (part of the reason it's not in the examples here).

Modern browsers handle zoom just fine, regardless of units. We use rem in case a user has set their own preferred base text size (the same reason we don't use viewport-relative units).


That's why it's rem + vw, to prevent accessibility problems


The vw introduces the accessibility bug. Your can add whatever other units to it you like, the issues remain.


What accessibility bug is that? Adding the other unit is specifically so the issues do not remain.


Am I the only person who sees a security error on this page? I'm on latest Chrome Version 90.0.4430.212 (Official Build) (x86_64) on Mac OS Big Sur

Screenshot: https://d.pr/i/gvj3fA

I've been trying to visit web.dev for days for various reasons, but I just get this and neither Chrome nor Safari will let me visit. But apparently a bunch of you can see the page, so I'm confused.


Looks really nice from what I’ve seen! One thing that I think could be especially helpful as an extension is booking into CSS from JS especially for animation. I feel like it helps because then you can do stuff like destroy an element after a fade out animation without having to know how long the animation takes or do chains of animations.


Is there a site where I can practice relatively simple css challenges. For example for this html, center the text and align text in all three boxes, etc. Css battle is great but there are only finished answers not explanations.

W3schools have some but they are too simplistic.



This is the first CSS tutorial that explains _why_ CSS works a certain way. I think so many new devs struggle with CSS because they don't understand why it is the way it is, which helps explain how it is supposed to be used.


This is your brain. this is your brain on css. any questions.. CSS is great, only problems are browser interpretation. Seems like now we healthily don't try and support all.


Google feels fresh for the first time in a while.


I will now be using my Friday morning to have a deep refresher into CSS. Thank you


Adam Argyle is awesome.


Adam Argyle is rad.


Where was this 6 years ago when I needed it! Nicely done.


This looks like an outstanding course!

Thanks for publishing it!


Strange choice of podcast for learning


this is a good resource.


It is absolutely amazing how many things we can do with CSS. It's as powerful as some programming language, while in fact being completely declarative and super fast at the same time!


One really interesting feature of CSS is that it's a regular language (you can write a regex that matches all valid CSS files.) This is unusual even for many config formats.


I'm glad we sacrificed any concept of hierarchy, scope and structure so that CSS files can be parsed by regex.


It can still refer to hierarchies via selectors. Honestly I think that's a fantastic way to handle it.


I think it has good and bad sides, but looking at the specs/draft-proposal for the new functionality being drawn and the hoops the syntax has to make in order to preserve the "it's regular language" while incorporating long time needed functionality it seems like it's a bad choice - one of those things that in some years people will go, "why tf is this like this"

I understand a proper parser would (perhaps) be more complex, but could also be open sourced in a lower level lang such as C, and then used by everyone, there's also already the full test suites for testing the output - maybe even Google+MS+Moz could open a contest - "fastest, most readable and efficient parser in C (or rust, wtv) takes 10k home"


A viable alternative to all this is using tailwind, can't recommend it highly enough. When you pass the initial period where you feel like you're repeating yourself (1h max) it takes the nervousness out of your CSSing, it feels more like coding and less like schmoozing..

Just a happy user


I like tailwind too but it's not an alternative to learning CSS. You still need to know CSS to be able to use tailwind


I agree with your first sentence, but not with your second.

For my own homepage i did not write a single line of css.

I am very, very bad with CSS and can't wrap my head around it, but tailwind allowed me to create a very pretty, responsive homepage with very high lighthouse scores (bought tailwind UI too).


> I am very, very bad with CSS and can't wrap my head around it, but tailwind allowed me to create a very pretty, responsive homepage

Congrats, you now know CSS! It sounds like I'm joking but honestly, Tailwind is essentially composable shorthand for CSS with a design system applied. If you grok Tailwind, you understand the concepts of CSS, you just might not know the full names for all the properties and values.


Yes, but when i try to apply this knowledge i fail every time.

I do unterstand the basic ideas behind CSS, but is just cant apply it. Tailwind allowed me to apply it.

If i could, i would prefer to write CSS! After 10 years i have given up though.


That's the thing about Tailwind. It's (almost) the right abstraction.

Personal anecdote, I understood how flexbox works only after using Tailwind for a personal project.


Yes, very true.. But you just don't need to maintain the exploding specificity hell, instead use a declarative workflow, which is significantly easier to reason about.


This is like saying an alternative to learning how to cook is to sustain yourself on takeaway.

Tailwind might be nice, but most projects will require in-depth knowledge about CSS.


People absolutely do use tailwind as an alternative to understanding CSS. Having seen and worked on projects in tailwind, I feel like that's it's primary purpose.

Go on Twitter and look at the Tailwind community - they see CSS as a doomed, awful language and Tailwind as the thing that makes it pleasant. They're not CSS developers. They're people actively trying to avoid being CSS developers.


Learning any CSS library is not alternative to learning CSS itself.


It's weird reading ycombinator and the persons above you says something else.


I know it's been said before, but no Tailwind does not replace CSS.

Tailwind replaces having to come up with a new semantic class name every time you need to style an element only to realize the actual semantics you picked were completely wrong.

Tailwind is basically a cleaner way to do everything as inline styles.


> Tailwind is basically a cleaner way to do everything as inline styles.

I'd say that's underselling it. For one thing it keeps you within a design system. By default you're given spacing that works in increments of 0.25rem, a handful of colors, etc to work with (which can be replaced/extended) so you have to go out of your way to break the design system that's in place.

Also inline styles don't allow for hover, focus, @media, etc. Which were always a pain in the ass with normal CSS anyway. Using Tailwind was the first time I didn't find writing a responsive UI to be a giant hassle. You just design for mobile and then for anything that needs to change on bigger screens you put a sm: or lg: or whatever breakpoint style and you're done.


Tailwind isn't quite inline styles (technical details) but yes, it replaces having to name 'login-box' with a copypasted set of styles that you can't change easily without massive regex work.


Until somebody has another similar box so they reuse login-box a bunch in your application, then you realize that they actually need to be customized and have to tear it all apart.

Tailwind doesn't make you copy and paste, it moves the reuse of styles out of CSS which sucks at managing reuse into whatever HTML building system which likely has some concept of reusable views.


> Until somebody has another similar box so they reuse login-box a bunch in your application

Then they make `.box` and include it as a mixin. Like CSS developers have done for a decade (and which tailwind itself does using PostCSS)

> Tailwind doesn't make you copy and paste

Yes it does. Moving all styles into individual elements without reuse is copy and paste.


> Yes it does. Moving all styles into individual elements without reuse is copy and paste

Tailwind all but assumes you will be using something that allows you to extract HTML into components, be that something like React or Vue, or classic partials in a server-side templating language like Twig. You reuse the entire component, rather than just the CSS, which IMO is far better aligned with how apps are actually built.

So no, using Tailwind classes is no more copy pasting than typing CSS in full into a separate stylesheet is copy pasting.


You’re misunderstanding the relationship between components and styles.

Login box and messages are separate components, but they share padding metrics, border styles, a palette, etc.

Have you used tailwind before?


I use Tailwind almost exclusively these days.

My argument is that using the “mr-1 pl-2” utilities on both a login box and a message would be no more copy pasting than creating a stylesheet with “.login-box { margin-right: 0.25rem; padding-left: 0.5rem; }” and “.message { margin-right: 0.25rem; padding-left: 0.5rem; }”.

And if you’re suggesting that you would create a single CSS class with those properties to apply to both the login box and the message, then it’s my opinion that that is a broken abstraction that falls apart as soon as your designer asks if you can make the spacing in the login box a little looser.


This is like saying that learning JQuery is an alternative to learning JavaScript.


Except that learning JQuery is an alternative to learning the native javascript DOM API.


DOM API? perhaps

JavaScript? no


I really love it, as it provides 1 layer of semantic abstraction over raw css, meaning, it's easier on the mind, very useful for frameworks like React / Angular / Blazor / Vue.

There is a learning curve, but if you assimilate the language, by doing a project or two, you won't have to even look at the documentation for doing your designs.


I like Tailwind so much. I wonder if there is a checklist of CSS things for common components such as buttons so that I can just follow that and get everything done with Tailwind without thinking much.


Tailwind UI is the paid version, Tailwind components the free version (has some gems, but irregular quality and not a consistent design system)


No.


Don't use Tailwind, it's garbage.




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

Search: