We often spend forever learning the parts of a language, and the application, but we never read enough about how to solve problems when things go wrong.
I’d like to spend some time avoiding cool new tricks and fancy features, and instead present a basic process anyone at almost any skill level could follow for debugging and troubleshooting CSS
You’ve written CSS, you’ve written HTML. Things should work, but you’re not seeing your CSS being applied!
Let’s look at five big steps you can follow for figuring this out
- Is the code valid?
- Does the selector match intent?
- Does the property match intent?
- Is other code the problem?
- Does someone else have a better idea?
Is the code valid?
Check that you’ve correctly added styles to the markup:
A proper way to add an external stylsheet is
<link rel="stylesheet" type="text/css" href="/someFolder/somestyles.css" />
And a proper internal stylesheet is:
<style type="text/css"></style>
Check that the selector is valid
If your selector uses class names, did you miss a period?
title { // whoops. Should be .title }
Did you miss some whitespace, or add some?
# someId{ // should be #someId } a :hover { //meant to be a:hover }
Check your CSS to be sure that it uses a valid selector. Mistakes can happen when chaining selectors:
#someIdh1 { // should be h1#someId }
Check that the property is valid
Right click, inspect element. Does the browser show a little yellow warning next to the CSS property? If it does, you’ve probably got an invalid property.
- Did you miss a semicolon for the property above?
- Did you add whitespace where you shouldn’t have?
- Did you misspell the property?
.someClass { color: #3333; // not a valid color value font-size: 1.2 // missing unit and missing semicolon dipslay: block; // misspelled display, but won't show up anyway b/c of semicolon above flex-direction: reverse-column; // not a valid propery padding: 1em / 2em; // invalid syntax }
Does the Selector Match Intent?
Check that the selector intent corresponds with the markup
Did you use a class when it was an Id?
<h1 id="someTitle"></h1>
.someTitle { // whoops. should be #someTitle font-size: 2em; }
Does your series of classes not apply in this case?
<section class="articles"> <article class="article"> <h1 class="article__title">
.articleList .article .article__title { // whoops. this should be articles }
Especially when your selectors get long, read them the way the browser reads them: from right to left.
So the above should be read aloud as
an .article__title inside of an .article inside of .articleList
Look in your HTML and look at your markup the way the browser would; from inside out. Now it should be a little more obvious that .articleList
isn’t there in the markup, but .articles
is, and that’s why the ruleset won’t apply.
Most beginner CSS problems are with invalid code or poor selector intent.
Does the Property Match Intent
This is the hardest to explain because there are so many different ways that things could go wrong. It’s easiest to just tell you a fundamental truth:
CSS, like any other computer language, is GiGo; Garbage in, Garbage out. Styles only perform as well as they are written
In a nutshell, you need to know how the properties work.
- width and height don’t matter on
display: inline
elements position:absolute
won’t work unless it’s inside ofposition:relative
or some other positioned element- the box model affects how
padding
andheight
/width
play together - Margins collapse
Head over to CSS Tricks or the Mozilla Dev Network to make sure you’ve written CSS properties correctly.
Is Other Code the Problem?
The first two steps were confirming that it wasn’t a mistake specificially with the code in question. If there aren’t problems with these specific rulesets, then the problems are with other rulesets.
Check if there are duplicate rulesets later in the stylesheet
You may have written something like
.someTitle { font-size: 3em; }
But maybe 200 lines down, you’ve got this:
.someTitle { font-size: 1em; }
The way CSS works is that the last ruleset wins* … so the one occurring closest to the bottom will overwrite yours.
Check if there are other rulesets targeting the same element
Something really important to understand about CSS is that, no matter if your selector targets IDs, classes, or element names — they are all targeting elements. Fundamentally, every CSS selector targets an element. You just have different ways to target that same element.
Suppose you have this markup:
<section class="articles"> <article class="article"> <h1 class="article__title">
You could have ruleset 1
h1 { font-size: 2em; }
be overwritten due to the selector in ruleset 2
article h1 { font-size: 1em; }
which would be overwritten thanks to the selector in ruleset 3
.article h1 { font-size: 1.5em; }
which may be overwritten by the selector in ruleset 4
.articles h1 { font-size: 1.25em; }
Take note that these are four rulesets that target the same element: an h1
. You’ve simply got four different ways to target them.
This is where you rely on your browser’s developer tools to help:
- Right click on the misbehaving element
- select “inspect element”
- on the right side of your developer window, you will see a list of CSS rules that apply. The top-most rulesets are the ones that usually come later in the styles
- If your CSS properties have a line going through them (a strikethrough), that means another ruleset is overwriting it
- Check and see if there is another ruleset targetting your element with a higher specificity
Check if there is an !important
lurking somewhere
!important has a place and a purpose. It’s just not for writing ordinary, run-of-the-mill CSS. It’s useful for end-users, and it’s useful for utility classes. In all other cases, it shouldn’t be used. Of course, that doesn’t stop developers from using it.
Again, assuming this markup:
<section class="articles"> <article class="article"> <h1 class="article__title">
A properly written ruleset, placed at the end of the stylesheet, like this:
.articleTitle { font-size: 3em; }
will never apply. Ever. Not if someone wrote this anywhere:
article h1 { font-size: 1em !important; }
Again, check your developer tools. They may show properties with lines through them; all except the one with !important
Does Someone Have a Better Idea?
Have you tried reddit?
Reddit has a CSS subreddit that may be a place to start. This is good if you’re new to CSS and want to ask some questions and spark dialog.
Maybe it’s time for Stack Overflow
First, see if someone else has your problem. If they did, and there’s an answer, upvote both.
Second, if there is no answer, ask a question and give good code examples.
There is no perfect troubleshooting guide
This isn’t a comprehensive process, but it’s one that I find to be a useful place to begin. You start small and work from the inside out:
- Is the code valid?
- Does the selector work,
- and if so, is there something wrong with the property?
- Is other code affecting this?
- If everything seems to be in order, is there something else I don’t know?
And if you’ve got added steps, or additional thoughts, let me know what they are.