Css width vs. flex-basis: what’s the Difference?

There is a time in every frontend developer’s life when they learn flexbox and ask: what is the difference between width and flex-basis? They look the same at first glance.

The answer is that in some cases they are them same. There are a couple edge cases you have to be aware of.

  • flex-basis by default is equal to width if set, or the width of the content.
  • If there is a width set, flex-basis can overwrite that.
  • width works horizontally, flex-basis works on the main axis. This is the most notable difference.
  • If you also set a min-width, that can overwrite your flex-basis setting.

It’s really that simple folks.

CSS Inheritance in Practice

Inheritance simply means that in certain cases a child element can inherit properties from the parent element. You can think of it like a default value for certain types of elements and its properties.

It is a common practice to set general text formatting on the body. Paragraphs will inherit those properties even several levels down, unless you don’t overwrite it at some level.

Links inherit the text size and font family, but they keep their default color and text decoration unless you specifically overwrite them.

Headings will inherit the font family and most related text properties, but they are bold by default. You will have to manually overwrite it if you need to.

CSS Specificity Explained in Simple Terms

To make our life easier, the designers of CSS created multiple levels of specificity depending on the selector. The three main kinds of selectors are:

  • element
  • class
  • id

There are also combinations of the above and pseudo elements and classes.

The traditional way of measuring specificity is to assign number values. Element selectors have a specificity of 1, classes 10, and ids 100. This isn’t really the case, because a class will be more specific then a combined selector with any number of elements.

This is more specific:

.list {
  color: #ccc;

Than this:

body main section div div div div div div div ul {
  color: red;

The least specific in the list is element, the most specific is id. Element selectors select html elements without giving them classnames or ids. Classes are more specific, but one class can still apply to multiple elements depending on where you are applying it. From one id, you can have only one instance, and that is the most specific of the three.

In case you have multiple selectors with the same specificity, the last one will overwrite the others. That’s cascading in action.

Specificity Best Practices

CSS seems simple at first, but as many discovered, with big project it can quickly become a hard to maintain monster. That’s why methodologies like BEM (Block Element Modifier) were created.

You should put general rules on element selectors like body, headings, paragraphs. Everything else should be selected with classes. It’s a generally accepted rule not to use id unless you absolutely must. It creates a high specificity that you won’t be able to overwrite later, hence you will have a hard time with maintenance.

Compound Selectors

If you follow some of the modern methodologies like the above mentioned BEM, you won’t use compound selectors much. Sometimes they do come up, so it’s important to understand how they affect specificity.

In the above example, there is a compound element selector. The specificity adds up, so it’s 11. Likewise, a selector like .list .item will have a specificity of 20.

Creating Links that Look like Buttons in CSS

I have written about styling links in CSS in another post. Creating the kind of buttons you see in website navigations is also done with simple links. The most widely used method to do it is to add display: inline-block; to the link and then apply padding. By default, links are inline elements, you applying padding would not work as expected. More about why here.

The ideal x / y padding ratio is usually around 1:2 or 1:3

The Wrong Solutions

Some people teach to apply a width and height instead of giving a padding. That would work, but it’s inferior to the padding solution. With padding, the links is centered by default. With the other solution you have to hack it in place.

It gets worse when you test it with varying lengths of links. With the padding solution, the size of the button will increase as needed, and the padding on the right will be there no matter the size. With the other solution, a longer link could even overflow.

Some people also apply padding to a container. That leads to a bad user experience where a user will be under the impression that he or she can click on the entire button, but in reality, the button will only work if they click on the link text.

An Example

.button {
  padding: 5px 15px;
  background-color: orange;

Styling Links with CSS

You can style links by applying styles to a elements.

a elements have five states that you can target with your styles:

  • link
  • visited
  • focus
  • hover
  • active

The order of these states in a stylesheet is very important. These states are additive, so even though a link is visited, the link style still applies to it. So the last one will overwrite the previous one. A good mnemonic to remember is LoVe HAte for link, visited, hover, active. In the middle is focus.

You can style these states with pseudoclasses:

a:visited {
  color: red;

The link state is the default one. Often the visited state will be the same. It makes sense to have a different visited state when you list a lot of external sites, like in the case of Google or Wikipedia.

The focus state is applied when you tab through a website. It is often the same as the hover state, but it can be different.

The hover state is applied when you hover over a link. The active state is triggered when you click with your mouse (hold it down to see it working).

There is another way to style links. You can first give a general style on the a selector. This would overwrite all states, and you can then modify the states as you need them.

a {
  color: red;
a:visited {
  color: white;

CSS Inline and Block Elements

Block level elements will start a new line and will stack on top of each other. Block elements by default are:

  • paragraphs
  • headings
  • lists and list items
  • divs
  • header
  • footer
  • main
  • section
  • and more.

Inline elements stay in an existing line. A good way to remember inline elements is to think about links. You know links, they stay inside the text and they don’t have their own line (unless you purposefully make it so). Inline elements are:

  • links
  • strong
  • em
  • span
  • images

Inline Element Quirks

Only inline elements can be nested inside inline elements. For example putting a link inside a strong or span element.

They don’t respect height and margin, padding, and borders on the top and the bottom. So you can expect them to work only on the left and right side. Padding will work to a degree (the box will be bigger), but elements around it will ignore it. This behavior is often manifested by a box covering surrounding elements.

CSS Margin and Padding

Margin is the spacing between elements, like heading and paragraphs. Browsers all have their defaults. For heading and paragraphs, the default is the font size for both margin-top and margin-bottom.

Centering with Margin

Setting the left and right margin to auto on an element will let you center it.

margin-left: auto;
margin-right: auto;

You can also do that in one step:

margin: 0 auto;

This sets the top and bottom margin to 0, and the left and right margins to auto. For margin-top and margin-bottom the auto actually means zero, so the most compact way to achieve the same result is:

margin: auto;

Collapsing Margins

If margins are not separated (they touch), they collapse together. That means that if you have two adjacent margins of e.g. 20px, the visible margin won’t be 40px, rather only 20px. If one is bigger, you will get that as the final margin. For example, if one element’s margin-bottom is 20px, and an adjacent element’s margin-top is 30px, the space between them will be 30px.

What can separate margins? Borders and padding. Check out my post about the box model.

Margin Collapse Quirks

If you set a margin top on a heading inside a container, it’s margin can merge together with the previous element. This can cause a situation when instead of pushing the heading down, you push down your entire container, just like if you’d have set that margin-top on the container. The solution is to set padding on the container first. Then you can apply margin inside it without having to worry about collapsing top margins.

Margins don’t collapse in Flexbox and Grids.

Typography Best Practices

It’s a well-known pattern to remove margin-top on typography related elements. That way we can use padding on the container.