If you’re not a fan of CSS, or if you’re brand new to front end coding, you might run the risk of making needless errors when you’re developing the styling of your products. Learn the biggest CSS mistakes to avoid and how to prevent them, and even how to fix them when you find them.
Estimated reading time: 14 minutes
Why do I need to learn this? I hate CSS.
If you hate CSS, trust me when I say, the rest of us can tell. Regardless of your feelings on the language, best practices should always be followed, and CSS can be pretty cool actually. See my post here about CSS variables and Use Cases to see what I mean.
We need to know these things because Web Development is all about building on top of others’ code. CSS is no exception, it is in fact designed to build upon itself.
Whether you’re working with the latest supported version of a language, a new framework, or trying to make your product work with someone else’s code; to scale you need a solid foundation.
Let’s get right into The Biggest CSS Mistakes to Avoid:
- Not relying on Browser Defaults with your HTML
- Syntax & Parsing Errors
- Improper Use of Relative Measurements
- Don’t Use Float Layouts
- Avoid Side Scroll
- Not styling State
- Not testing Color Contrast
- Position & Z-Index
- Using !important – But is it?
Not relying on Browser Defaults with your HTML
That’s right, good CSS begins with sensible HTML! The Browser you’re using comes with default styles for each and every HTML tag out there. Because CSS resources can slow your page load time, it’s important to cut down on the amount of code we use. Utilizing browser defaults whenever possible can greatly reduce the amount of code you write.
A common CSS mistake I see is developers overwriting an HTML tag’s default display properties for no reason.
I’ve seen Lists used in places where it makes no sense for them to be used. Relying on HTML 5 tags would fix the problem in most cases.
For instance, the default display property of a List Item is “list-item”.
If you change the display property to “block”, be sure you know why.
In some cases it makes sense to change a List’s default properties. Like in the case of a horizontal navigation. The list items can be set to “inline”, like this:
This makes sense because a list has semantic properties that accessibility tools recognize and will behave for the user accordingly. A list of items in a <nav> tag is obvious to the user as a list of links to navigate the site.
But it doesn’t make as much sense for a sidebar area to have list items set to display “block”. It may not affect the way your sidebar looks, but it can affect the way accessibility tools navigate the sidebar, and it can cause you to write more code.
Using the HTML tags that already use the display block property makes more sense and will be more compatible with other products.
How to prevent it:
In this below image a sidebar and main area are using unordered and ordered lists with their styles set to display block.
As you can see the sidebar area and main content area are not aligned and the code is a little harder to follow.
Instead of an unordered list, use the HTML 5 aside tag as the main sidebar container and either the section, or div tags for elements inside the sidebar.
In this below image I have switched out the original HTML with Semantic Mark-up (meaning the main tag is a sibling of the aside tag) and I’ve removed the list item styles.
Now, not only are we using less code here, but it’s already fixed a styling issue (alignment), not to mention screen-readers and keyboards will be able to navigate this design much better.
Want to know more ways to improve your CSS game? Check out how to navigate dev tools to fix issues with a site’s CSS.
Syntax & Parsing Errors
Believe it or not, I’ve seen this common CSS mistake in production. Parsing errors cause major display issues and functional issues as well.
What happens when a semi-colon or a curly bracket is missing? It can have some nasty unintended consequences. You might see styles you’re adding to your site simply not applying. You might see entire stylesheets seem to disappear, especially if you’re using CSS minification.
How to prevent
- Use an IDE like VS Code that has CSS Language supports built in to find errors when they first occur
- You should also run your code through the Jigsaw CSS Validator here before you ship it to production.
Having trouble seeing your CSS on the front end? Learn how to track down parsing errors using dev tools.
Improper Use of Relative Measurements
You can make designs highly responsive by using relative measurements on your container’s width properties and on their box properties like margin and padding. Sometimes using relative measurements all the way can make sense, and in some cases it’s a really bad idea. Here’s why this is a CSS mistake to avoid.
Generally speaking, width and margin should always be relative. Padding can go either way. It just depends on you (and your teams) math skills.
Take this main content area and sidebar below for example. The styling here is using all relative measurements and the sidebar is not actually showing up on the side. The sidebar and the main area’s padding is set to 5%, a relative measurement.
How to fix it:
Relative is the operative word. As you can see the calc directive on the main content area is trying to make the content no larger than 100% minus the sidebar (300px) minus the 10% which is the left and right padding of the sidebar added together.
The problem is, the 10% we are trying to subtract is relative to the main container, not the sidebar container. Trying to calculate the padding is not so simple.
You can see the absolute measurement by checking the element’s box properties in dev tools but it’s going to change as the page grows or shrinks with the device.
The only way to use this method and figure out the percentage you need to subtract from the main area is with “Maffs” (aka Math), and if you’re anything like me, you’re not going to do that.
Now, in this below image, you can see the calc directive is much simpler to understand and ensures that the width of the main area keeps the sidebar next to the content.
The padding is set to 10px, so there will be 10px on the right and left of both containers. If you’re still with me on this, that’s 40px total that we can subtract from the width of the main section.
The calculation here is much easier and our content is where it needs to be.
Don’t Use Float Layouts
Float layouts were the way we designed most of our layouts before Flex and Grid hit the scene. Believe it or not, some people are still using float layouts to design for responsive web applications.
Let’s take the following code. The main is set to float left, and has a calc() width style of 100% – 300px. That means when I add my float right to my aside and make my aside 300px then everything should be fine and my layout is perfect, right?
If you look at the image below, you’ll see why this doesn’t work out of the box. The aside is not in fact to the right, it’s all the way down at the bottom. The borders help to demonstrate why, if you look closely at the top border on the aside element, you’ll see that there is overlap from the main area’s width as well as the aside’s.
Here’s how we Avoid this CSS mistake
Well you might be saying, “Ryan just do math” to that I say, not unless I have to. Yes it’s true I can subtract the border widths from the main area and aside area from the width of the aside area to make this design more responsive.
But I could also just wrap may main and aside areas into a div and set that div to display flex instead:
Why is this approach better? Well, for one we have replaced two lines of code with one. The second reason is that making float designs responsive for hand-held devices generally takes more thought, media queries, and managing the width of our elements more precisely than flex layout does.
Checkout my post on designing with Flex here for more cool tips and ideas.
Avoid Side Scroll
A common issue I see when reviewing websites is when the content doesn’t pass the Mobile Usability Test. This is a great tool for determining issues when they occur, but it’s better to prevent these issues before they happen.
Generally, the common CSS mistake here is not accounting for elements that don’t wrap by default.
Let’s see how we can avoid this CSS mistake before it occurs
Ensure your anchor tags, code elements, and other text nodes have either an
overflow-wrap setting to
break-word, or a
word-break set to
If you’re using a table, ensure your table children like th, td, etc. have a
line-break set to ‘
Not styling State
User’s should always be able to orient themselves in your application. In other words, they should know where they are.
Styling your :hover, :focus, :active, :visited states with these pseudo selectors are an important component in User Experience design.
How to prevent issues with perceived orientation
Ensure you understand what states need to be communicated to the user for the elements you’re designing. Like buttons would have different state behaviors than nav links would.
For example, in a list of links, the :visited, :active and :hover states would be essential so the user doesn’t repeat themselves by navigating back to a link that they’ve already visited. It also helps them know where they are when the active link is obvious.
Not testing Color Contrast
Foreground and background colors should always be checked against each other. There are several different kinds of vision that users may have. Some vision difficulties can prevent your designs from even being perceived. Contrast can help prevent these usability road-blocks.
How to prevent
- Test your foreground and background colors on WebAIM.
- Create a color palette that has high contrast to begin with to prevent accidents later on.
Position & Z-Index
I often see people using really high numbered z indexes, which is only really necessary when you are creating a dynamic element like a modal window, or a sticky video player.
The problem is, even if you are using a really high numbered z-index, if it’s relative parent element has a lower z-index than the parent element of another item using the z-index property, things start to get really weird and confusing.
Avoid this common CSS mistake by understanding how z-indexes work:
This below image shows that the main and sidebar areas have a relative position, while the pop up and centered paragraph inside the pop up have absolute positioning.
Any positioned element has a z-index property. Whether you add one or not, a positioned element’s default z-index is going to be 0.
- A Note from W3C: If two positioned elements overlap without a z-index specified, the element positioned last in the HTML code will be shown on top.
- That the pop up element is placed as a direct child of the main element.
- Also, in the HTML above, how the sidebar is the last element in the body tag of the HTML
The main and sidebar sections both have been set to a z-index of 2 and the pop up has a z-index of 9999.
I resolved this not by trying to make the pop up’s z-index even higher, but by changing the sidebar’s z-index to 1.
Using !important – But is it?
I thankfully see this less and less, but I still see the important directive being misused.
MOST IMPORTANTLY DON’T USE THIS UNLESS YOU HAVE TO! I’m begging you.
The important directive was not developed as a lazy hack, it was not developed to be used when you don’t know what else to do.
The best use cases for the !important directive are:
- To overwrite an inline style that you can’t control
- To overwrite a dynamic style you can’t control and don’t want effecting your elements
- When you need to control the behavior of an element so that it is always looking the way it needs to.
Below we have a heading with a class of red and an id of blue. Normally, an id would be more specific and would therefore take precedence, but because of this important directive the red style is taking priority.
Here’s how to fix it:
If you can’t delete the unneeded important directive straight out of the stylesheet, then the only way to overwrite it, is by using the important directive, along with specificity and the cascade. Here’s how we’re going to overwrite this common css mistake when we find it.
Important Directive; Yup! You have to use the important directive to overwrite the important directive. It sounds as dumb as it is. That’s why you should be very careful when implementing it.
Specificity; Make sure your selector is using an id if available and as many parent elements as it takes to get that important directive to stop.
In this below image the heading color is overwritten by the style that is more specific. The style using both the id and the class name along with the important directive.
Cascade; Make sure your style is implemented and read by the browser after the important directive you are trying to overwrite.
In this image below, both styles have the same selectors and directives but the winner comes last.
Poor CSS practices will always create a faulty foundation. Trying to build from that will ultimately crumble your efforts. Learn to avoid these mistakes and how to fix them when you find them. Hopefully now you’ve learned some great tips on what not to do when designing your web applications with CSS.