Aman Explains

Settings

A few things you might not know about CSS

August 09, 2021• ☕️☕️ 8 min read

My initial career path was more focused on JavaScript; CSS was not part of my Jira tickets. I remember asking my colleague, who was good at CSS, that how long it would take for me to be an expert in CSS? He laughed and said, “It could take years!“.

And today, after this long on my CSS learning journey, I realise that he was totally right.

Sometimes, you might think that you know enough about CSS, and then soon find out about a basic concept that you never knew existed, or your understanding of that concept was different from what the CSS spec says. Isn’t that why we often see memes saying, “CSS IS AWESOME”.

In this article, I’ll share a few caveats, gotchas, and some ‘Aha’ moments in CSS, along with CodePen demos where possible. I am sure it will bring a smile to your face 😃. So, let’s get started.


Table of Contents

Position ‘fixed’ would change the width of the block level element

By default, all block level elements occupy the horizontal space of their parent element. But when you specify the position: fixed on a block level element, its default width will become the width of the content inside.

Check out the demo below. Add position: fixed to the “inner div”, and observe the changes to its width.

Position ‘sticky’ creates a parent sticky container

When you define an element with position: sticky  you’re automatically defining the parent element as a sticky container.

The container is the scope of the sticky item, and the item can’t escape from its sticky container. For example, if you wrap your sticky element with another div, as shown in the demo below, the item will not be sticky anymore.

Inherited property values have no specificity, not even zero

Imagine you have the following HTML and CSS:

* {
  color: black;
}
h2 {
  color: red;
}
<h2>This is an <em>emphasized</em> text.</h2>

What do you think will be the color of em text?

The answer is “black”. Even though, colour is an inherited property, as we’re using universal selector, which has a specificity of zero, it will override the inherited property.

The baseline of the inline-block element

The baseline of the inline-block element depends on content it has inside, and the overflow property. To identify the baseline of inline-block element:

  • It’s the baseline of the last content element in the linebox in the normal flow
  • If there’s an overflow property other than visible, then the baseline is the bottom edge of the margin-box
  • If there’s no in-flow content, then the baseline is the bottom edge of the margin-box

The following demo would make it easier to understand this:

Surrounding elements won’t respect vertical margin on inline elements

You can provide a vertical margin (margin-top/bottom) to inline elements, but the surrounding elements won’t respect that. It’s better to use inline-block as it will have all the properties of an inline, and the surrounding elements will respect that.

In the following demo, initially the inline span element has margin-bottom, but the paragraph element doesn’t respect that. But if you change the display of span elements to inline-block, you’ll notice how the ‘margin-bottom’ becomes visible in the layout.

The ‘flex’ has more priority than ‘width’ property

Considering the following example, do you think there will be an overflow?

<div class="container">
  <div class="one">Item 1</div>
  <div class="two">Item 2</div>
  <div class="three">Item 4</div>
  <div class="four">item 4</div>
</div>
.container {
  display: flex;
  width: 1000px;
}

.container > div {
  flex-basis: 250px;
  width: 300px;
  height: 200px;
}

The answer is no, and the final width of each child div will be 250px. The is because width is just a fallback when flex-basis is missing, and min-width and max-width are just upper and lower limits for the final flex-basis. Check out the demo below:

Why flexbox has no justify-self similar to Grid?

While laying out the design on the page, the Grid considers rows and columns at the same time; the Flexbox only considers a single row at a time and goes downward. Let’s understand what happens when you use justify-content:

  • First, the amount of space required to lay out the item is calculated
  • Then, the leftover space is distributed based on selected property value

For example, justify:content: flex-end will add extra space before the items, whereas justify-content: space-around will distribute the space on either side of the items in that dimension.

The key point to remember is that on the main axis, Flexbox deals with content as a group. It means justify-self property does not make sense in Flexbox as we are always dealing with moving the entire group of items around. Whereas, on the cross-axis, there can be some additional space available to move the single item at the start or end with align-self.

Why setting vertical margin to auto doesn’t vertically center the block level element?

You might have tried setting the following CSS on a block level element, in the hope that it would vertically centre the element:

margin-top: auto;
margin-bottom: auto;

But it doesn’t. The answer lies in the CSS specification, section 10.6.3 which states that if ‘margin-top’, or ‘margin-bottom’ are ‘auto’, their used value is 0.

Order of class selectors has no effect on the final computed styles

Consider the following example:

.green {
  color: green;
}
.red {
  color: red;
}
.blue {
  color: blue;
}
<h2 class="red blue green">Guess my color?</h2>

What do you think will be the colour of the heading? If you think it’s green, then you’re wrong. The correct answer is blue. The order in which classes are applied has no effect on the final style output. The class selector which is declared later in the stylesheet will win.

Having images inside a Flexbox? You might need min-width: 0

If you have multiple images inside a flex container, with flex: 1 applied to all the images, you might find an unexpected result of image items overflowing the container.

Consider the following example:

<div class="wrapper">
  <img src="image1.jpg" alt="" />
  <img src="image2.jpg" alt="" />
</div>
.wrapper {
  display: flex;
}
img {
  flex: 1;
}

If images are larger than the available space inside the container, an overflow will occur. The answer lies in the CSS spec, which states that by default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property.

img {
  flex: 1;
  min-width: 0;
}

Background on HTML element

I recently learned about this little fact in Stefan Judis’s newsletter, and was written by Chris Coyier at CSS tricks back in 2013. The fact is that, in the absence of a background on the html element, the body background will cover the page. If there is a background on the html element, the body background behaves just like any other element.

Try adding the following line and observe how the body background starts to behave like any other element:

html {
  background: white;
}
body {
  background: red;
}

Summary

Learning CSS can be daunting, but fun too. You don’t have to learn everything in one go. My advice would be to learn the fundamentals as described by Rachel Andrew. And if there’s something that behaves differently than what you have expected, try reaching out for specification rather than copy/pasting answer from StackOverflow.

This will allow you to understand these nuisances easily and eventually make you a good developer over a long run.  And the rest, as always, is CSS is Awesome 😛.


Amandeep Singh

Written by Amandeep Singh. Developer @  Avarni  Sydney. Tech enthusiast and a pragmatic programmer.