Skip to Content
Biggest CSS Mistakes To Avoid

Biggest CSS Mistakes To Avoid

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

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”.

Screenshot of a list item tag selected in the Dev Tools Chrome browser, the default display is set to 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:

Image showing a style added in Dev Tools to list items that sets their disply property to 'display:inline'. The list items on the website are no longer numbered or have bullet points and instead of being vertical they are now listed side by side horizontally

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.

image of an html emulator in which the sidebar and main areas of an html document are formatted with ol and ul lists set to display block instead

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.

On the right the heading for 'an ordered html list' with that is black and the heading for 'an unordered html list is black'.

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

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.

On the right the main area is above the grey area. On the left the sidebar is set to float leftx minimum width 300px and padding 5%, the main area is set to width 100%, max-width calc(100% - 300px -10%), float left, and padding 5%.

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.

On the right shows a main area and a sidebar with arrows pointing to the right and left of each with the number 10 next to each arrow. On the left the sidebar element and the main element have the style padding:10px; set

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?

the main area is set to float left with the calc set to 100% width minus 300 pixels and the aside is set to 300 pixels

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.

the main area of the design is above the aside area. the aside area is below the main area and to the right

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:

the container element that wraps the main and aside areas is set to flex and the float settings are commented out

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 break-word.

If you’re using a table, ensure your table children like th, td, etc. have a line-break set to ‘anywhere'.

the container has an overflow wrap setting to break-word that allows the linked header to wrap. the table head styles is set to line-break anywhere which also allows it to wrap

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.

anchor tags have a hover design of color orange. a visited design of color grey and an active design of color red

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

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.

Image of a snippet of HTML code which demonstrates the z-index properties of different elements on the page
  • 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.

On the right the pop up is under the sidebar but on top of the main area. The left has the CSS document an arrow points to the element with a class of pop-up set to 9999, the element with a class of sidebar is set to 2, and the main element is set to 2

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.

On the right the pop up is on top of the other elements, An arrow is pointing to the CSS document and style for the sidebar which has a z-index of 1

Using !important – But is it?

I thankfully see this less and less, but I still see the important directive being misused.


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:

  1. To overwrite an inline style that you can’t control
  2. To overwrite a dynamic style you can’t control and don’t want effecting your elements
  3. 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.

On the right the heading for 'an ordered html list' with a class of red and an id of blue is red and the heading for 'an unordered html list is black'. On the left the style .red is set to color: red!important; then #blue style is set to blue;

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.

On the right the heading for 'an ordered html list' with a class of red and an id of blue is red and the heading for 'an unordered html list is black'. On the left the style is set to color: red!important; the #blue style is set to blue !important;

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.

On the right the heading for 'an ordered html list' with a class of red and an id of blue is blue and the heading for 'an unordered html list is black'. On the left the style is set to color: red!important; then style is set to blue !important;


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.

Photo by Cookie the Pom on Unsplash