Search code examples
htmlcsspseudo-elementcss-content

Why is the pseudo content :after not shown after but in the corresponding div?


The following example shows a box div with an :after content, which should be a separate block.

div.box {
    background-color: #FAA;
    width: 10em;
    overflow: scroll;
}
div.box:after {
    content: "☑";
    display: block;
    background-color: #AFA;
    width: 5em;
    overflow: auto;
}
<div class="box">x</div>

But the after content is placed inside the scroll bars. My expectation was that it comes actually after the scrollable area.


Solution

  • The :after content comes within the scrollable area because even though the element is named :after, it is in actual terms a child of the div.box and hence will be positioned within the .box element (that is within the scrollable area).

    From MDN: The CSS ::after pseudo-element matches a virtual last child of the selected element.

    (emphasis mine)

    So the code in question in essence becomes the same as the following snippet.

    div.box {
        background-color: #FAA;
        width: 10em;
        overflow: scroll;
    }
    div.box .after {
        display: block;
        background-color: #AFA;
        width: 5em;
        overflow: auto;
    }
    <div class="box">x
      <div class="after">☑</div>
    </div>


    If you want it positioned outside the div.box then you would have to use the :after on a container (or) use absolute positioning.

    div.box {
        background-color: #FAA;
        width: 10em;
        overflow: scroll;
    }
    div.container:after {
        content: "☑";
        display: block;
        background-color: #AFA;
        width: 5em;
        overflow: auto;
    }
    <div class="container">
      <div class="box">x</div>
    </div>