惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
P
Privacy & Cybersecurity Law Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
C
Cybersecurity and Infrastructure Security Agency CISA
S
Security Affairs
Latest news
Latest news
Security Latest
Security Latest
N
News and Events Feed by Topic
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
T
The Blog of Author Tim Ferriss
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
The Exploit Database - CXSecurity.com
The Last Watchdog
The Last Watchdog
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
V
Vulnerabilities – Threatpost
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Azure Blog
Microsoft Azure Blog
V
Visual Studio Blog
The Cloudflare Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
博客园_首页
S
Secure Thoughts
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
AWS News Blog
AWS News Blog
腾讯CDC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Register - Security
The Register - Security
N
News and Events Feed by Topic
A
Arctic Wolf
MongoDB | Blog
MongoDB | Blog
爱范儿
爱范儿
Project Zero
Project Zero
A
About on SuperTechFans
罗磊的独立博客
云风的 BLOG
云风的 BLOG
Know Your Adversary
Know Your Adversary
S
Security @ Cisco Blogs
Google Online Security Blog
Google Online Security Blog
K
Kaspersky official blog
L
LINUX DO - 最新话题
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Fortinet All Blogs

CSS Wizardry

Front-End’s Missing Metric: The TBT Window Meet Your Users Where They Are with Obs.js Better Browser Caching with No-Vary-Search font-family Doesn’t Fall Back the Way You Think What Is CSS Containment and How Can I Use It? When All You Can Do Is All or Nothing, Do Nothing Obs.js: Context-Aware Web Performance for Everyone Low- and Mid-Tier Mobile for the Real World (2025) The Fastest Site in the Tour de France Making Sense of the Performance Extensibility API Why Do We Have a Cache-Control Request Header? HTML Is Not a Programming Language… Build for the Web, Build on the Web, Build with the Web Licensing Code on CSS Wizardry A Layered Approach to Speculation Rules Designing (and Evolving) a New Web Performance Score Core Web Vitals Colours The Ultimate Contract Templates for Tech Consultants: Protect Your Business and Get Paid Optimising for High Latency Environments Cache Grab: How Much Are You Leaving on the Table? blocking=render: Why would you do that?! Correctly Configure (Pre) Connections The Three Cs: 🤝 Concatenate, 🗜️ Compress, 🗳️ Cache What Is the Maximum max-age? How to Clear Cache and Cookies on a Customer’s Device The Ultimate Low-Quality Image Placeholder Technique Core Web Vitals for Search Engine Optimisation: What Do We Need to Know? The HTTP/1-liness of HTTP/2 In Defence of DOM­Content­Loaded Site-Speed Topography Remapped Why Not document.write()? Speeding Up Async Snippets Critical CSS? Not So Fast! Measure What You Impact, Not What You Influence Optimising Largest Contentful Paint Measuring Web Performance in Mobile Safari Site-Speed Topography Speed Up Google Fonts Real-World Effectiveness of Brotli Performance Budgets, Pragmatically Lazy Pre-Browsing with Prefetch Making Cloud.typography Fast(er) Time to First Byte: What It Is and How to Improve It Self-Host Your Static Assets Tips for Technical Interviews Cache-Control for Civilians Bandwidth or Latency: When to Optimise for Which ITCSS × Skillshare What If? CSS and Network Performance The Three Types of Performance Testing Getting to Know a Legacy Codebase Image Inconsistencies: How and When Browsers Download Images Identifying, Auditing, and Discussing Third Parties My Digital Music Setup Measuring the Hard-to-Measure Finding Dead CSS The Fallacies of Distributed Computing (Applied to Front-End Performance) Ten Years Old Relative Requirements Airplanes and Ashtrays Performance and Resilience: Stress-Testing Third Parties Refactoring Tunnels Little Things I Like to Do with Git Writing Tidy Code Configuring Git and Vim Base64 Encoding & Performance, Part 2: Gathering Data Base64 Encoding & Performance, Part 1: What’s Up with Base64? Code Smells in CSS Revisited Typography for Developers Moving CSS Wizardry onto HTTPS and HTTP/2 Ack for CSS Developers A New Year, a New Focus Preparing Vim for Apple’s Touch Bar Choosing the Correct Average CSS Shorthand Syntax Considered an Anti-Pattern CSS Wizardry Newsletter Nesting Your BEM? Improving Perceived Performance with Multiple Background Images Continue Normalising Your CSS Pure CSS Content Filter Pragmatic, Practical, and Progressive Theming with Custom Properties Refactoring CSS: The Three I’s Speaker’s Checklist: Before and After Your Talk Improving Your CSS with Parker The Importance of !important: Forcing Immutability in CSS Mixins Better for Performance Managing Typography on Large Apps White October Events Workshop Partnership BEMIT: Taking the BEM Naming Convention a Step Further Travelling Like You Want to, When You Have To Contextual Styling: UI Components, Nesting, and Implementation Detail Subtleties with Self-Chained Classes Cyclomatic Complexity: Logic in CSS Immutable CSS Can CSS Be Too Modular? More Transparent UI Code with Namespaces When to use @extend; when to use a mixin The Specificity Graph CSS Wizardry Ltd.: Year 1 in review
Build-along #1, reflection and reasoning
Harry Roberts · 2011-11-06 · via CSS Wizardry

Written by on CSS Wizardry.

Table of Contents

Independent writing is brought to you via my wonderful Supporters.

  1. HTML first
  2. No IDs
  3. ‘Ugly’ classes to do lots of heavy lifting
  4. Portable sprite icons
  5. Mobile first, lay the foundations
  6. Grid systems just make life easier
  7. ‘Extraneous’ divs actually make builds far more robust and extensible
  8. Don’t measure stuff
  9. Be resourceful
  10. Take away?
  11. Finally
  12. Update
    1. Sped-up video

Here are, in no particular order, just a few thoughts about the build-along I did last night. These thoughts cover the thinking and reasoning behind the decisions I made. The build-along was a single, small PSD, but the following should apply to builds of any size. Get into the habit of doing the following on tiny sites and you’ll be well equipped to build that next Facebook meets YouTube with a dash of LinkedIn that that prospective client just emailed you about…

Here is the final build and its code is on GitHub.

HTML first

I built this HTML-first. No CSS other than the UA’s whatsoever. No images, no styles, no JS, no classes, no containers, nothing. I started with pure text-level and content semantics. No divs, no spans, nothing that would in any way aid styling. Nail your pure, raw HTML first before even thinking about CSS. This ensures you’re thinking fully about the most important aspect of any site; its content.

No IDs

The build uses no IDs for styling. This was quite an odd shift for me to make, and I made it a number of weeks back. The main drawback of using IDs is that they introduce a specificity wild card not unlike using !important (though obviously not as horrible). By not using them it means that I can’t really get tripped up by overly specific selectors as easily as I could if I was using IDs. I’ve not removed the chance completely, but really easily and quickly lessened it.

‘Ugly’ classes to do lots of heavy lifting

There are quite a few classes that some might deem ugly; the media and grid classes instantly spring to mind. The thing here is that classes aren’t semantic or insemantic, they’re merely sensible or insensible. If a div is 6 columns wide then a class of .grid-6 is totally sensible, if it needs to change then change it. If you ever redesign you’ll be touching the markup anyway; I’m convinced the pure CSS redesign (in a commercial world) is a myth.

These classes also bring performance benefits, once a class gets called once it becomes free to use again; a performance freebie. If you use grid-6 once on a page, every subsequent usage is totally free, from a performance point of view.

Portable sprite icons

The .s class is a theoretically horrible class, but as we outlined above, nothing (except micro-formats and similar) reads or even cares what you name your classes. You can name a class anything you wish and a browser has to honour it, just pick wisely!

So, the .s class is one good example. Whenever you want to use an icon background image you ideally want to sprite it, but in fluid elements this isn’t possible. Enter a spriting element.

This is just an empty element that gets the sprite applied to it in its own fixed width/height box.

Chris Coyier uses pseudo elements for this which is great as it’s really clean, but the major drawback for me here is that they’re not very portable. A pseudo element is tied explicitly to an element in the CSS, so you can’t just drop the icon wherever you wish. Using an empty element means you can drop an icon wherever you wish. It’s six-of-one and half-a-dozen of the other; cleanliness versus portability; pick which one you’d rather have.

I can imagine that 75% reading this still think it’s a horrible, but we need to remember that an empty element affects nothing. It’s empty so it has no content, if it has no content then screen readers don’t encounter anything in it.

You’re probably also thinking that it’s heavily presentational, but there’s really no difference between:

And:

<img src=star.png alt="">

The first is just out-and-out better in that it allows you to sprite that image up!

I was asked why an i and not a span. I’m almost ashamed of the answer but it’s purely because i is shorter, it’s as simple as that. I know that a span is probably better suited as it’s devoid of semantics but as there’s no content in the i nothing is affected by semantics anyway. Feel free to use whatever element you prefer though, like I said, my reasoning is kind of shameful!

Mobile first, lay the foundations

I did this build mobile first, sort out the content, the type, the general feel of the site first, then used min-width media queries to build up the desktop version.

Incidentally I don’t use respond.js or similar to get media queries working in IE et al, they get the mobile version. The layout of the site is not that important because a PSD is a clue, not a contract. A PSD tells you how a site should generally appear; the type, the colours, any brand treatments, that kind of stuff.

If you spend enough time on the mobile version that should be good enough to serve as the baseline, anything on top is a bonus for browsers that support media queries.

Grid systems just make life easier

In a similar vein to the above, grid systems are typically frowned upon as being insemantic, but the joy is that, as we covered, classes are neither semantic or in semantic. Plus–even better than that–a div is devoid of any semantics, it’s a generic container element. Adding these to your markup comes free-of-charge. Using a grid system allows developers to quickly construct consistent, robust and efficient layouts in seconds.

‘Extraneous’ divs actually make builds far more robust and extensible

You should never add markup where avoidable, but that doesn’t mean you should avoid it at all costs. Sometimes adding an extra div will make components a lot less brittle, rather than relying on unpredictable style rules and overly slim markup, sometimes it’s just far better to add another div to ensure a more robust build.

Take for example the media object. You could probably build that construct using far less HTML, but then would it be as extensible? You could just assume there will only ever be an img floated left with a p to the right of it, but if you do that and a client asks for a list with that p and a caption under the img you’re in a bit of a pickle; if you just start out with a div on each side to start with then you have the ability to build whatever the client throws at you, and it will always be predictable.

So, add extra markup where it saves you headaches. I’m more impressed by powerful and extensible code than I am with lean and brittle solutions, and I can guarantee which the client will prefer…

Don’t measure stuff

Throughout this build I only measured one thing; the grid system. I honestly think that, in web design, the pixel’s days are numbered. Build everything without a care as to its dimensions. Everything in the build can be moved around and dropped anywhere else without you needing to worry if it’ll fit. All your components should always be fully fluid and only constrained by their parent, in this case the grid system.

Here’s a challenge, next time your designer sends you a PSD designed on, say, the 960GS, resize your browser to 800px wide and build it like that. That’ll really put your fluid, responsive skills to the test!

Be resourceful

During this build I copied and pasted loads of code. I used my vanilla boilerplate, I copied and pasted the media object, the nav abstraction, the carousel. If it already exists somewhere then reuse it! There are no prizes for writing more lines of code; be resourceful.

Take away?

Even on tiny sites, powerful markup is far more quick, robust, extensible and sensible than convoluted, brittle stuff. No one reads your classes except other developers. Users appreciate fast UIs, clients appreciate stable and robust sites and you, the developer, like to save time, be efficient and only solve problems once.

What may at first seem like an ugly class or bloated markup is actually a really quick, predictable and reusable construct.

Websites make us money, so let’s make them as quickly as possible and in the most predictable, future proof way we can.

Finally

There is a video of the build to go with this, but I need your opinions, do you want the full, several hour epic or do you want it sped up to, say, double speed? I’m going to get that processed as soon as possible.

Update

As promised, I recorded the whole thing warts and all. You might be interested to know a few things non-code related about the build-along.

  • The whole lot was done on an 11″ MacBook Air with no external mouse or keyboard.
  • My good friend Jake, who is wanting to learn a little about web development, was next to me the whole time.
  • I cooked and ate my (now famous (in tiny, tiny circles)) chili during the build-along.
  • Refreshment was courtesy of Matusalem and Fentimans.
  • The songs you saw on my Spotify are not necessarily wholly representative of my taste in music ;)

The normal, non-sped-up recording is now on YouTube. Part 1, Part 2. The sped-up version is proving a little more troublesome; crunching over 4 hours of video on an 11″ Air is taking a while…

Sped-up video

To view the faster video right away, simply opt in to YouTube’s HTML5 Trial, open the YouTube URLs above in Chrome and then select the playback speed options that now appear on the player.