3 Things (Almost) No One Knows About CSS

Share this article

Think you know CSS? If the results of a free CSS test I’ve offered online for the past six months are anything to go on, plenty of practicing developers don’t know CSS as well as they think. Out of over 3,000 people who have taken the test so far, the average score was just 55%.

But hey, an average isn’t that interesting by itself. I was more curious about which questions people were getting wrong. For this article, I’ve run the numbers, and zeroed in on three questions where people scored especially badly. I’ll talk you through each question, show you the answer that most people chose, and explain the correct answer.

It’s safe to say that if you take the test yourself after reading this, you’ll have an unfair advantage!

Question 1: How Best to Set line-height

This first question should have been easy for anyone who deals with text styles on a regular basis:

You want text on your website to be double-spaced by default. Which of the following line-height values is the best way to achieve this?

  • 200%
  • 2em
  • 2
  • double

With four answers to choose from, you’d expect 25% of people to get the right answer by luck alone, and only 31% got this one right! Take a minute and pick out an answer for yourself, then read on.

First off, double is a red herring. The only keyword value that line-height accepts is normal. I’m happy to say that only 9% of people fell for this one. The remaining three answers were all pretty popular, though.

The answer that most people selected is 2em (39% chose this). Indeed, 2em will certainly give you double-spaced text for the element it’s applied to; but so will 200%, and only 21% liked that answer! Either ems are much more in fashion than percentages, or people don’t really understand them.

The correct answer, though, is 2.

This is a lesson that was drilled into me a long time ago, when I was first learning CSS. Always specify line-height as a unitless number; that way, descendent elements that specify a different font-size will inherit that number rather than a fixed line height.

Let’s say the page has a default font-size of 12pt, but it also contains a heading with a font-size of 24pt. If you set the line-height of the body to 2em (or 200%), then you’ll get a line height of exactly 24pt (twice the body’s font-size) everwhere in the document—even in that heading. The heading will therefore be single-spaced, not double-spaced!

Setting line-height to 2 instead tells the browser to preserve the font-size/line-height ratio even when the font size changes. The line height for the body will be 24pt, but for the heading’s 24pt font, the line height will automaticlly increase to 48pt.

Question 2: How to Make Elements Overlap

This question was a bit trickier. It called for some experience of the “dirty tricks” that CSS layout often requires:

Which of the following CSS properties, used by itself, can cause HTML elements to overlap?

  • z-index
  • margin
  • overflow
  • background

Got an answer picked out? Okay, let’s dive in.

Once again, there was an easily-eliminated option: background. All but 2% of test takers steered clear of it, knowing that it controls background colors and images.

Unfortunately, most steered straight into z-index. A full 46% of people jumped on that one. I’m guessing it’s because no one really understands how z-index works. In fact, setting the z-index property by itself has no effect whatsoever; you also need to set the position property of an element for z-index to do anything. In short, z-index lets you control the stacking order of elements that do overlap, but they need to be overlapping in the first place. MDN has a really nice article called “Understanding CSS z-index” that’s worth a read for more detail.

overflow should have been easy to eliminate too, if you’ve ever used it. It controls how content that doesn’t fit inside a sized box behaves: whether it’s chopped off, whether it flows out past the edges of the box, etc. Again, this depends on the box’s size being constrained with other properties; by itself, it won’t cause overlaps. Still, 22% of people thought it might.

That leaves us with margin, which is the right answer. Only 30% of people got it. You might wonder how on earth a property that creates distance between elements can cause them to overlap. If you’ve done any real-world CSS layout, the answer should be obvious: negative margins make things overlap.

To demonstrate this, create a page with two div elements. Set the margin-top on the second div to a negative measurement, for example -100px. Bam! The second div now covers the bottom one hundred pixels of the first div.

In practice, you’d almost never overlap blocks like this on purpose, but negative margins are extremely useful for squeezing HTML elements into places they don’t normally go. I often use them to push left- or right-floated elements into the padding region of their parent box.

Schematic of a right-floated box resting against the right border of its parent

For web design history buffs, in 2005 overlapping elements with negative margins is what made possible three-column page layouts such as the so-called One True Layout (and later the Holy Grail layout).

Question 3: Pseudo-elements vs Pseudo-classes

This last question is a bit of a cheap shot, I’ll admit. But with only 23% of test takers able to answer it correctly (that’s worse than chance!), it clearly hits on a point of confusion:

Which of the following effects is best achieved using a pseudo-element?

  • Add a drop-shadow to a hyperlink when a user hovers their mouse over it.
  • Display the label of a checkbox in a different color when the checkbox is checked.
  • Give the even and odd rows of a table different background colors.
  • In a flexible page layout, display the first line of a paragraph in bold text.

Three of these choices are effects you achieve with a pseudo-class; only one involves a pseudo-element. Can you tell the difference?

A pseudo-class is a particular state in which an actual HTML element can find itself. Think of it as a virtual class that is applied to the element automatically by the browser under certain conditions.

A pseudo-element is a part of the document that CSS lets you style even though it isn’t an actual HTML element. It’s like a virtual HTML element—something you get to style even though it doesn’t have actual HTML tags around it.

With this distinction in mind, let’s run through the options:

Add a drop-shadow to a hyperlink when a user hovers their mouse over it.

A hyperlink is an actual HTML element. Applying styles to it only in a particular situation (when the mouse is over it) means we’re using a pseudo-class. The pseudo-class you’d use in this case is :hover.

22% of test takers thought this was a pseudo-element.

Display the label of a checkbox in a different color when the checkbox is checked.

Again, a label is an actual HTML element, not a virtual one. When a checkbox is checked, the browser applies the :checked pseudo-class to it. You can then use it in your selectors to style the checkbox, or even a label next to it (e.g. using an adjacent sibling selector with +).

20% of test takers thought this was a pseudo-element.

Give the even and odd rows of a table different background colors.

This is the one that really fooled people, but once again we’re talking about applying styles to actual HTML elements (tr elements, in this case). A tr being even- or odd-numbered within its parent element’s collection of children is just another circumstance that you can match with a pseudo-class.

In this case, the pseudo-class is :nth-child(even) (or :nth-child(2n)) for even elements, and :nth-child(odd) (or :nth-child(2n+1)) for odd ones.

I’m guessing it’s just because :nth-child and pseudo-elements in general both sound like really obscure CSS features, but a full 36% of test takers picked this as a pseudo-element.

In a flexible page layout, display the first line of a paragraph in bold text.

This, of course, is the right answer. And by now, hopefully, the distinction is clear. In a flexible page layout, you can’t look at the HTML code of a page and say “that element there contains just the first line of the paragraph’s text”. The browser does the word-wrapping depending on the width of the paragraph, which is something you don’t get to control in a flexible page layout.

:first-line is the pseudo-element that lets you apply styles to the first line of text in a block, no matter where that first line wraps to the second.

If you’re thinking “OK, sure, that all makes sense, but c’mon—no one knows the difference between pseudo-elements and pseudo-classes”, well the W3C agrees with you. In the CSS3 Selectors spec, in an attempt to distinguish the two, it changed the syntax so that pseudo-element selectors use two colons (::first-line), while pseudo-classes still use one (:hover). Of course, for backwards compatibility, browsers must support both versions.

So yeah, like I said: cheap shot. But hey, if you’re a CSS geek like me, I imagine you’d know your pseudo-elements from your pseudo-classes.

How’d You Do?

So that’s it: three tough questions from the test. If you answered just one of them with confidence, you’re doing okay. Got two of them? Not bad at all. If you got all three, I’d love to hear from you! Especially now that I’ve given away the answers to these, I could really use some ideas for more tricky CSS questions. Post ’em in the comments!

If you enjoyed these questions, maybe you’d like to give the rest of the test a try. Rest assured, the other questions are much easier than these … mostly!

Kevin YankKevin Yank
View Author

Kevin Yank is an accomplished web developer, speaker, trainer and author of Build Your Own Database Driven Website Using PHP & MySQL and Co-Author of Simply JavaScript and Everything You Know About CSS is Wrong! Kevin loves to share his wealth of knowledge and it didn't stop at books, he's also the course instructor to 3 online courses in web development. Currently Kevin is the Director of Front End Engineering at Culture Amp.

LouisL
Share this article
Read Next
Creating Fluid Typography with the CSS clamp() Function
Creating Fluid Typography with the CSS clamp() Function
Daine Mawer
Comparing Full Stack and Headless CMS Platforms
Comparing Full Stack and Headless CMS Platforms
Vultr
7 Easy Ways to Make a Magento 2 Website Faster
7 Easy Ways to Make a Magento 2 Website Faster
Konstantin Gerasimov
Powerful React Form Builders to Consider in 2024
Powerful React Form Builders to Consider in 2024
Femi Akinyemi
Quick Tip: How to Animate Text Gradients and Patterns in CSS
Quick Tip: How to Animate Text Gradients and Patterns in CSS
Ralph Mason
Sending Email Using Node.js
Sending Email Using Node.js
Craig Buckler
Creating a Navbar in React
Creating a Navbar in React
Vidura Senevirathne
A Complete Guide to CSS Logical Properties, with Cheat Sheet
A Complete Guide to CSS Logical Properties, with Cheat Sheet
Ralph Mason
Using JSON Web Tokens with Node.js
Using JSON Web Tokens with Node.js
Lakindu Hewawasam
How to Build a Simple Web Server with Node.js
How to Build a Simple Web Server with Node.js
Chameera Dulanga
Building a Digital Fortress: How to Strengthen DNS Against DDoS Attacks?
Building a Digital Fortress: How to Strengthen DNS Against DDoS Attacks?
Beloslava Petrova
Crafting Interactive Scatter Plots with Plotly
Crafting Interactive Scatter Plots with Plotly
Binara Prabhanga
GenAI: How to Reduce Cost with Prompt Compression Techniques
GenAI: How to Reduce Cost with Prompt Compression Techniques
Suvoraj Biswas
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
Aurelio De RosaMaria Antonietta Perna
Quick Tip: How to Align Column Rows with CSS Subgrid
Quick Tip: How to Align Column Rows with CSS Subgrid
Ralph Mason
15 Top Web Design Tools & Resources To Try in 2024
15 Top Web Design Tools & Resources To Try in 2024
SitePoint Sponsors
7 Simple Rules for Better Data Visualization
7 Simple Rules for Better Data Visualization
Mariia Merkulova
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
SitePoint Team
Best Programming Language for AI
Best Programming Language for AI
Lucero del Alba
Quick Tip: How to Add Gradient Effects and Patterns to Text
Quick Tip: How to Add Gradient Effects and Patterns to Text
Ralph Mason
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Vultr
How to Optimize Website Content for Featured Snippets
How to Optimize Website Content for Featured Snippets
Dipen Visavadiya
Psychology and UX: Decoding the Science Behind User Clicks
Psychology and UX: Decoding the Science Behind User Clicks
Tanya Kumari
Build a Full-stack App with Node.js and htmx
Build a Full-stack App with Node.js and htmx
James Hibbard
Digital Transformation with AI: The Benefits and Challenges
Digital Transformation with AI: The Benefits and Challenges
Priyanka Prajapat
Quick Tip: Creating a Date Picker in React
Quick Tip: Creating a Date Picker in React
Dianne Pena
How to Create Interactive Animations Using React Spring
How to Create Interactive Animations Using React Spring
Yemi Ojedapo
10 Reasons to Love Google Docs
10 Reasons to Love Google Docs
Joshua KrausZain Zaidi
How to Use Magento 2 for International Ecommerce Success
How to Use Magento 2 for International Ecommerce Success
Mitul Patel
5 Exciting New JavaScript Features in 2024
5 Exciting New JavaScript Features in 2024
Olivia GibsonDarren Jones
Tools and Strategies for Efficient Web Project Management
Tools and Strategies for Efficient Web Project Management
Juliet Ofoegbu
Choosing the Best WordPress CRM Plugin for Your Business
Choosing the Best WordPress CRM Plugin for Your Business
Neve Wilkinson
ChatGPT Plugins for Marketing Success
ChatGPT Plugins for Marketing Success
Neil Jordan
Managing Static Files in Django: A Comprehensive Guide
Managing Static Files in Django: A Comprehensive Guide
Kabaki Antony
The Ultimate Guide to Choosing the Best React Website Builder
The Ultimate Guide to Choosing the Best React Website Builder
Dianne Pena
Exploring the Creative Power of CSS Filters and Blending
Exploring the Creative Power of CSS Filters and Blending
Joan Ayebola
How to Use WebSockets in Node.js to Create Real-time Apps
How to Use WebSockets in Node.js to Create Real-time Apps
Craig Buckler
Best Node.js Framework Choices for Modern App Development
Best Node.js Framework Choices for Modern App Development
Dianne Pena
SaaS Boilerplates: What They Are, And 10 of the Best
SaaS Boilerplates: What They Are, And 10 of the Best
Zain Zaidi
Understanding Cookies and Sessions in React
Understanding Cookies and Sessions in React
Blessing Ene Anyebe
Enhanced Internationalization (i18n) in Next.js 14
Enhanced Internationalization (i18n) in Next.js 14
Emmanuel Onyeyaforo
Essential React Native Performance Tips and Tricks
Essential React Native Performance Tips and Tricks
Shaik Mukthahar
How to Use Server-sent Events in Node.js
How to Use Server-sent Events in Node.js
Craig Buckler
Five Simple Ways to Boost a WooCommerce Site’s Performance
Five Simple Ways to Boost a WooCommerce Site’s Performance
Palash Ghosh
Elevate Your Online Store with Top WooCommerce Plugins
Elevate Your Online Store with Top WooCommerce Plugins
Dianne Pena
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Dianne Pena
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
Vultr
Enhance Your React Apps with ShadCn Utilities and Components
Enhance Your React Apps with ShadCn Utilities and Components
David Jaja
10 Best Create React App Alternatives for Different Use Cases
10 Best Create React App Alternatives for Different Use Cases
Zain Zaidi
Control Lazy Load, Infinite Scroll and Animations in React
Control Lazy Load, Infinite Scroll and Animations in React
Blessing Ene Anyebe
Building a Research Assistant Tool with AI and JavaScript
Building a Research Assistant Tool with AI and JavaScript
Mahmud Adeleye
Understanding React useEffect
Understanding React useEffect
Dianne Pena
Web Design Trends to Watch in 2024
Web Design Trends to Watch in 2024
Juliet Ofoegbu
Building a 3D Card Flip Animation with CSS Houdini
Building a 3D Card Flip Animation with CSS Houdini
Fred Zugs
How to Use ChatGPT in an Unavailable Country
How to Use ChatGPT in an Unavailable Country
Dianne Pena
An Introduction to Node.js Multithreading
An Introduction to Node.js Multithreading
Craig Buckler
How to Boost WordPress Security and Protect Your SEO Ranking
How to Boost WordPress Security and Protect Your SEO Ranking
Jaya Iyer
Understanding How ChatGPT Maintains Context
Understanding How ChatGPT Maintains Context
Dianne Pena
Building Interactive Data Visualizations with D3.js and React
Building Interactive Data Visualizations with D3.js and React
Oluwabusayo Jacobs
JavaScript vs Python: Which One Should You Learn First?
JavaScript vs Python: Which One Should You Learn First?
Olivia GibsonDarren Jones
13 Best Books, Courses and Communities for Learning React
13 Best Books, Courses and Communities for Learning React
Zain Zaidi
5 jQuery.each() Function Examples
5 jQuery.each() Function Examples
Florian RapplJames Hibbard
Implementing User Authentication in React Apps with Appwrite
Implementing User Authentication in React Apps with Appwrite
Yemi Ojedapo
AI-Powered Search Engine With Milvus Vector Database on Vultr
AI-Powered Search Engine With Milvus Vector Database on Vultr
Vultr
Understanding Signals in Django
Understanding Signals in Django
Kabaki Antony
Why React Icons May Be the Only Icon Library You Need
Why React Icons May Be the Only Icon Library You Need
Zain Zaidi
View Transitions in Astro
View Transitions in Astro
Tamas Piros
Getting Started with Content Collections in Astro
Getting Started with Content Collections in Astro
Tamas Piros
What Does the Java Virtual Machine Do All Day?
What Does the Java Virtual Machine Do All Day?
Peter Kessler
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Mayank Singh
Layouts in Astro
Layouts in Astro
Tamas Piros
.NET 8: Blazor Render Modes Explained
.NET 8: Blazor Render Modes Explained
Peter De Tender
Mastering Node CSV
Mastering Node CSV
Dianne Pena
A Beginner’s Guide to SvelteKit
A Beginner’s Guide to SvelteKit
Erik KückelheimSimon Holthausen
Brighten Up Your Astro Site with KwesForms and Rive
Brighten Up Your Astro Site with KwesForms and Rive
Paul Scanlon
Which Programming Language Should I Learn First in 2024?
Which Programming Language Should I Learn First in 2024?
Joel Falconer
Managing PHP Versions with Laravel Herd
Managing PHP Versions with Laravel Herd
Dianne Pena
Accelerating the Cloud: The Final Steps
Accelerating the Cloud: The Final Steps
Dave Neary
An Alphebetized List of MIME Types
An Alphebetized List of MIME Types
Dianne Pena
The Best PHP Frameworks for 2024
The Best PHP Frameworks for 2024
Claudio Ribeiro
11 Best WordPress Themes for Developers & Designers in 2024
11 Best WordPress Themes for Developers & Designers in 2024
SitePoint Sponsors
Top 10 Best WordPress AI Plugins of 2024
Top 10 Best WordPress AI Plugins of 2024
Dianne Pena
20+ Tools for Node.js Development in 2024
20+ Tools for Node.js Development in 2024
Dianne Pena
The Best Figma Plugins to Enhance Your Design Workflow in 2024
The Best Figma Plugins to Enhance Your Design Workflow in 2024
Dianne Pena
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Christopher Collins
Build Your Own AI Tools in Python Using the OpenAI API
Build Your Own AI Tools in Python Using the OpenAI API
Zain Zaidi
The Best React Chart Libraries for Data Visualization in 2024
The Best React Chart Libraries for Data Visualization in 2024
Dianne Pena
7 Free AI Logo Generators to Get Started
7 Free AI Logo Generators to Get Started
Zain Zaidi
Turn Your Vue App into an Offline-ready Progressive Web App
Turn Your Vue App into an Offline-ready Progressive Web App
Imran Alam
Clean Architecture: Theming with Tailwind and CSS Variables
Clean Architecture: Theming with Tailwind and CSS Variables
Emmanuel Onyeyaforo
How to Analyze Large Text Datasets with LangChain and Python
How to Analyze Large Text Datasets with LangChain and Python
Matt Nikonorov
6 Techniques for Conditional Rendering in React, with Examples
6 Techniques for Conditional Rendering in React, with Examples
Yemi Ojedapo
Introducing STRICH: Barcode Scanning for Web Apps
Introducing STRICH: Barcode Scanning for Web Apps
Alex Suzuki
Using Nodemon and Watch in Node.js for Live Restarts
Using Nodemon and Watch in Node.js for Live Restarts
Craig Buckler
Task Automation and Debugging with AI-Powered Tools
Task Automation and Debugging with AI-Powered Tools
Timi Omoyeni
Quick Tip: Understanding React Tooltip
Quick Tip: Understanding React Tooltip
Dianne Pena
12 Outstanding AI Tools that Enhance Efficiency & Productivity
12 Outstanding AI Tools that Enhance Efficiency & Productivity
Ilija Sekulov
React Performance Optimization
React Performance Optimization
Blessing Ene Anyebe
Introducing Chatbots and Large Language Models (LLMs)
Introducing Chatbots and Large Language Models (LLMs)
Timi Omoyeni
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Ampere Computing
Get the freshest news and resources for developers, designers and digital creators in your inbox each week