The CSS property you didn't know you needed 👈
Francesco Vetere

Francesco Vetere @francescovetere

About: Frontend Dev particularly passionate about Web Design and the CSS world 😄

Joined:
Nov 2, 2023

The CSS property you didn't know you needed 👈

Publish Date: Nov 18 '23
122 25

Hi folks! 👋 Today I wanna talk about a CSS feature that, in my opinion, doesn't get too much attention... but it should! I'm talking about the isolation property! 🪄

➡️ It basically provides more control over how elements interact with the rest of the document, and it is often an elegant solution for z-index issues.

Let's start with a practical example. I've built this simple card:

Card without quotation mark

The HTML for it is pretty straightforward, and it looks something like this:

<article class="card">
  <header class="card__header">
    <img class="card__avatar" src="..." alt="..." />
    <span class="card__name">Daniel Clifford</span>
    <span class="card__role">Verified Graduate</span>
  </header>

  <p class="card__summary">I received ...</p>

  <p class="card__description">I was an EMT ...</p>
</article>
Enter fullscreen mode Exit fullscreen mode

Some styles have been applied too, in order to set up colors, typography and layout. However, we can completely ignore them as they will not play any role in what we are going to do now.

Now, let's say that we want to add a quotation mark image to the top-right corner of the card, as a little decorative element. Something like this:

Card with quotation mark

🤔 How can we achieve that?

💡 We could treat the quotation mark image as a pseudo-element, and use position: absolute to place it over the card! Let's give it a try 💪

.card {
  /* We want the .card element to be the containing block for its children .card::before */
  position: relative;
}

.card::before {
  /* This is a pseudo-element, so we need to give it a content by definition */
  content: "";

  /* We position our image over the card, with a little offset from the right */
  position: absolute;
  right: 2em;

  /* We define a size for our image */
  width: 150px;
  aspect-ratio: 1; /* This makes sure that the image is a square */

  /* We bring in our image through a background-image */
  background-image: url(https://raw.githubusercontent.com/francescovetere/testimonial-grid-section/main/images/bg-pattern-quotation.svg);
  background-repeat: no-repeat;
  background-size: contain; /* This makes sure that the background actually fills all the available space (150px x 150px) */
}
Enter fullscreen mode Exit fullscreen mode

This is the result we get:

Card with quotation mark

It looks good, except for one little issue: we want to push this image behind the text!

Here's where our z-index comes into play. A little z-index: -1 should do the trick, right? Well... not exactly 😕

Card with quotation mark

😱 It... disappeared?!

Well, if you think about it, that makes perfect sense: every element, by default, gets a z-index: 0. So, it's like saying that each element on the page lives on the very same layer, by default.

When we declare a z-index: -1 on our pseudo-element, we are actually pushing it under the defaut layer!

🤔 How can we solve this?

Ideally, we would like to have a local, scoped z-index: when I say that I want my pseudo-element to have a z-index: -1, what I really mean is: "go behind everything, but NOT behind the card itself!"

✅ This concept is actually built-in into CSS, and it's called stacking context!

A stacking context basically is defined by an element, that acts as the root for its children's z-index declarations. In particular, the children can never escape behind their stacking context, no matter how low their z-index are.

By default, a plain HTML document will have a single stacking context, and every element refers to it. That's why, when we assigned z-index: -1 to our pseudo-element, it was pushed all the way back: there was only one, global stacking context!

💡 BUT, of course, we can also create new stacking contexts on arbitrary elements!

There are a number of ways we can create a new stacking context on an element. Some of them are:

  • Assigning a transform to it;
  • Assigning a filter to it;
  • Assigning an opacity to it;
  • ...

You can find the full list of properties here.

All these methods have one, big issue: they also come with side-effects! 😢

Yes, they create a stacking context, which is what we want, but they also do something else, which maybe we don't necessarily want!
I mean, why should I be forced to apply an opacity to an element in order to create a stacking context, even if I didn't want to apply any opacity at all in the first place?

🪄 Luckily, there's an easy solution, and it's called isolation!

isolation is a special property whose sole and unique purpose is to create a new stacking context on the element it is applied to, with no other side-effects. 😄

It accepts two values, auto and isolate. Of course, isolate is what we want.

✅ So, that's it! The final solution to this problem reveals to be extremely simple:

.card {
  position: relative;
  isolation: isolate;
}
Enter fullscreen mode Exit fullscreen mode

Here's the result with all the code, if you want to mess around with it! ☺️


And that's all! Feel free to leave a comment and let me know if you already knew about this awesome property! 😉

Till next time! 👋

Buy Me A Coffee

Comments 25 total

  • Nicholas Warwick
    Nicholas WarwickNov 18, 2023

    Nice, thanks for sharing Francesco!

  • Farzad Farzanehnya
    Farzad FarzanehnyaNov 18, 2023

    Absolutely fantastic! Your tip is greatly appreciated. Thank you so much!

  • Yeom suyun
    Yeom suyunNov 19, 2023

    Can this be utilized for GPU acceleration?

    • Francesco Vetere
      Francesco VetereNov 19, 2023

      From my understanding, whether or not a property will determine some kind of GPU acceleration, depends on a variety of factors, including the browser, the OS, the available hardware, etc...

      However, there are some properties that can "encourage" this acceleration: some of them are transform, will-change, filter, ... I'm not sure about isolation, as I don't find anything about it on the web. However, if you want to dig more into it, I found these articles which explains these concepts really well:

      smashingmagazine.com/2016/12/gpu-a...

      stackoverflow.com/questions/263567...

  • Jeremy Farrance
    Jeremy FarranceNov 19, 2023

    I agree, I didn't know I needed that and I do! That was almost better than rediscovering Drivers Seat (by Sniff n the Tears) yesterday. This was very well written and I really appreciate the explanation and details!

  • Best Codes
    Best CodesNov 20, 2023

    This will solve a lot of my problems. Thanks!

  • Potpot
    PotpotNov 20, 2023

    Doesn't position: relative already do that?

    • Francesco Vetere
      Francesco VetereNov 20, 2023

      Nope, position: relative alone doesn't create a new stacking context, and you can easily verify that by looking at the first code snippet I showed.

      You could obtain a stacking context with the conjuction of position: relative AND a z-index value other than auto, but position: relative alone doesn't work.

      isolation: isolate is still a better solution in my opinion, because it is very explicit in what it's doing, and causes no other side-effects ☺️

      • Potpot
        PotpotNov 20, 2023

        oops, I missed the z-index value other than auto part. Thank you for your explanation!

  • Luli Hashimoto
    Luli HashimotoNov 20, 2023

    This was a helpful read, I am sure it will be of use soon! It was fun to learn about a solution that’s so simple and doesn’t create undesired side-effects.
    Thank you for sharing!

    • Francesco Vetere
      Francesco VetereNov 20, 2023

      So glad it helped! Yeah, it's really powerful and I really wanted to share this with the community to help as many people as possible 😊 Thanks for stepping by!

  • Francesco Vetere
    Francesco VetereNov 20, 2023

    First of all, thanks for your contribution!

    This card that you see here was part of a bigger challenge on frontendmentor.io, a platform where you can find ready-made challenges and just build them starting from pre-existing designs.

    I actually solved this challenge some time ago: frontendmentor.io/solutions/testim...

    And here's the codepen for it: codepen.io/francescovetere/pen/Bax...

    So, a few considerations:

    1) About accessibility/colors/fonts... well, that was the design, and I just recreated it 😅

    2) About the CSS reset, it was there because I always include it every and each of my projects, no matter what. I especially love Andy Bell's reset these days. Of course I don't do it for small demos, but as I said, this wasn't originally a demo, it was something more complex. I just thought that I could create a new codepen, extract one card from that grid and use it without worrying too much about the details (as I said in the article, there is some "other" styling applied, but it can be ignored for the purpose of this article).

    3) Of course you could use a background for the quotation mark instead of a pseudo-element, and guess what? Originally, I did so! 😂 If you check the codepen I just linked you, you'll see that the quotation mark is in fact a background-image, not a pseudo-element. As you know, there is more than a way to obtain the same result, especially in CSS... I just figured this was a good example to show, in a very simple manner, what isolation really is. There are some better use cases for it? Of course! But this was just a simple example by which I think it is very easy to grasp the idea of it, and that was my goal.

    4) For the row-gap thing, yes, I understand, that's reasonable! Anyway, I link you to a video that really made me realize that sometimes using grid or flexbox just to "create" space, may not be always the best idea: youtube.com/watch?v=Gx0iZrN-0L4

    Again, thanks for your contribution, I appreciate it!

  • Scott Reno
    Scott RenoNov 21, 2023

    Awesome post

  • Julien Bouvet
    Julien BouvetNov 24, 2023

    Easy yet so powerful. Thanks for this great tip !

    • Francesco Vetere
      Francesco VetereNov 24, 2023

      I agree! Pretty easy concept, but also really handy once you know it exists! Thanks for stepping by 😉

  • Chris Coyier
    Chris CoyierNov 29, 2023

    If anyone like learning via video I remember a Kevin Powell video that uses the "large quote" example as well:

    twitter.com/kevinjpowell/status/15...

  • Daniele
    DanieleDec 3, 2023

    Amazing tip, I never heard about this property.
    I learned something new in my Frontend study journey.
    Thanks for sharing with us ✌️

Add comment