The Top 5 CSS Gotchas, and a few bonus…

Flexbox is quite amazing and incredibly useful for every developer out there to know, it can help with almost any layout.

The problem is that if you don’t know exactly how flexbox works, it can be pretty dumbfounding figuring out why things are just not working and not sizing exactly as you would expect.

Here is a small explanation of the flex property – flex-basis, flex-grow and flex-shrink.

Flex-basisflex-basis is like the width property.

It dictates the width that the element should have before any shrinking or growing occurs.

If flex-grow and flex-shrink are set to 0, the width of the element will be equal to the flex-basis.

For example:flex: 0 0 200px; would make the element always have a width of 200px.

It would never shrink or grow if the width of the viewport changed.

Try it out in the pen below:Flex-growIf there is more space than the flex-basis of the element, then it has the capacity to grow.

flex-grow comes in effect.

So if there is free space, it will be divided among elements with a flex-grow value above 0, proportionally.

For example, if you have 3 elements, each with flex-grow: 1; and 300px of free space after flex-basis is applied for all elements, then each element will get 100px extra width.

Overall, if you understand that flex-grow only comes into effect after flex-basis is determined, all works as expected.

Notice in the example below how the items grow if there is space available, but they will not shrink under 300px wide each (because flex-shrink is set to 0, and flex-basis is 300px).

Flex-shrinkflex-shrink is more tricky.

Similarly to how flex-grow only applies after flex-basis has been allocated, so does flex-shrink.

But flex-shrink does not reduce space proportionally, not in all circumstances anyway.

Instead, flex-shrink shrinks space from each element, so all elements reach their min-content width (the width where their content would overflow if they got any smaller), at roughly the same time.

For example, consider the pen below:Notice how if you resize the viewport, block-1 shrinks much faster than block-2, even though both their flex-shrink values are 1.

They do not shrink proportionally like with flex-grow, instead items with more room to shrink reduce in size faster, so that all items reach their min-content width somewhat evenly.

Of course changing their flex-shrink values does change the behavior, but just note that things do not shrink exactly proportionally.

Margin in flexboxAlso note that using margin: auto; in flexbox perfectly centers an item.

More than that, margin-top and margin-bottom work just like margin-left and margin-right work everywhere else in CSS.

In comparison, in the normal box model, margin: auto; becomes 0 for the top and bottom.

Consider the pen below:Notice how just by using margin: auto; on the block, it is perfectly centered in the flexbox.

For more information on flexbox in general, please see the guides on MDN.

The first part is Basic concepts of flexbox (MDN), then look at the sidebar for the rest.

Worthwhile mentionsBorders don’t accept percentage valuesAs the heading says, you can’t use percentages with borders.

This applies to more than just borders too, for example box shadows.

It can be confusing because you can use percentages for content size (width and height), padding and margins, but not borders.

Just keep it in mind.

Responsive iframes (and other embedded content) that retain their aspect ratioUnfortunately this requires a hack to accomplish with CSS right now.

To find out how to do it, see Aspect ratio boxes (CSS-Tricks).

Z-indexz-index can be complicated if you don’t fully know how it works.

The first thing you should know is the default stacking order for elements.

Non-positioned blocks (statically positioned).

Floating blocks.

Positioned blocks (anything other than statically positioned).

Knowing the above, z-index can help us further control where an individual element appears.

Here’s how it works:Firstly, note that z-index only works on positioned elements.

If an element is not positioned, z-index will have no effect.

Secondly, z-index only works relative to its closest ancestor which forms a stacking context.

In other words, an element will never go below its stacking context.

For example, the root element (html) always forms a stacking context.

An element will never stack below the root element, regardless of its z-index.

If another element forms a stacking context, then a child element will never stack behind it.

There are many ways to form stacking contexts, with the most common way probably being giving an element a position of absolute or relative along with a z-index.

Finally, elements with z-index only compete against each other if they share the same stacking context.

This can be quite a handful to understand the first time round.

For a much more thorough explanation please see Understanding CSS Z-index (MDN).

Percentages in transforms are not relative to the parent containerWith the box model, percentages are given an actual value based on the parent.

For example, if a parent is 100px wide, and a direct child has 10% width of the parent, it will be 10px wide.

If that child is then relatively positioned with left: 100%; it would end up to the right of the parent, outside of it.

But when using transforms, percentages don’t work the same way.

With transforms, percentages are relative to the element itself, not its parent.

Consider the pen below:Notice that the element with transform: translateX(100%); does not end up outside of its parent.

That’s because the 100% in this case is relative to the element itself.

It only moves to the right 100% of its width, not 100% of its parent’s width.

In contrast, the relatively positioned element works as you would expect and ends up outside the parent element.

For more information on transforms, please see the guide on using CSS transforms (MDN)InheritanceThis is a very minor point and a fairly basic concept, but I thought I’d mention it here for the beginners among us.

In short, some CSS properties are inherited and some are not.

Inherited properties include things like font-family and color.

This effectively means that you can set font-family on the body element and all elements in the page will inherit it and have the same font-family.

Most other properties are not inherited, such as margin and padding.

They have to be set individually on elements.

It’s worth understanding this concept so that you know whether you have to explicitly write a declaration or you can just count on it being inherited.

There are also special keywords that allow you to explicitly inherit properties that otherwise are not inherited, and also to prevent inheritance and such.

For more information, please see Cascade and inheritance (MDN).

Where to go from hereCSS is a tricky beast.

On the one hand it is quite easy to learn and use, and on the other hand it has many unexpected cases and surprises.

This article mentioned the most significant and most common ones, the ones you’re most likely to repeatedly encounter throughout your career.

When you’re learning CSS, I recommend using these as a checklist to gauge how much of it you really know.

To be the best professional you can be, you should ideally know about all of these cases.

Sidenote: If you know why some of these cases work in this way, especially some of the more unexpected ones like margin-collapsing and flex-shrink, then please let us know in the comments!Good luck and study well!.

. More details

Leave a Reply