CSS :after not adding content to certain elements

Viewed 81051

I'm having trouble understanding the behavior of the CSS :after property. According to the spec (here and here):

As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content.

This doesn't seem to place restrictions on which elements can have a :after (or :before) property. However, it seems to only work with specific elements... <p> works, <img> doesn't, <input> doesn't, <table> does. I'm could test more, but the point is made. Note that this seems pretty consistent across browsers. What determines whether an object can accept a :before and :after property?

5 Answers

I've spent several hours plucking out my hair only to find that some other css override content (or display:none) property of my selector.

For example, if the following code is written in some other place, before or after element will never show:

#id > child:before {
  content: none!important;
}
<html>
<div id="id" class="class">
  <child>
    Before element is not showing
  </child>

</div>
<style>
  child:before {
    content: 'before';
    color: 'red';
  }
</style>

</html>

Just find the css which is overwriting your style and spam stronger selectors and !important to make it work

#id>child:before {
  content: none!important;
}
<html>
<div id="id" class="class">
  <child>
    Before element is <strong>showing</strong>
  </child>

</div>
<style>
  #id.class>child:before {
    content: 'before'!important;
    border: 1px solid red;
  }
</style>

</html>

<img> is a replaced element and using :before or :after pseudo-elements on it works if the image fails to load and otherwise it does not work. If you intend to have a fallback in case of image load failure, the following css useful:

img{ 
position: relative;
}

img:after{ 
position: absolute;
content: "Any allowed type of content including a fallback image";
left: 0;    
}

For a good example, please refer to https://css-tricks.com/7-practical-uses-for-the-before-and-after-pseudo-elements-in-css/

Elements that doesn't have closing tag are void elements and they can't display content inside them:

https://www.w3.org/TR/html5/syntax.html#void-elements

All Blink, Webkit and Quantum browsers allow you to create pseudo elements only on checkboxes but this is controversial since no spec allow this behavior.

Here an example: https://codepen.io/equinusocio/pen/BOBaEM/

input[type="checkbox"] {
  appearance: none;
  color: #000;
  width: 42px;
  height: 24px;
  border: 1px solid currentColor;
  border-radius: 100px;
  cursor: pointer;
  transition: all 100ms;
  background-size: 30%;
  outline: none;
  position: relative;
  box-sizing: border-box;
  background-color: #eee;
  transition: background-color 200ms;

  &::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    bottom: 2px;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background-color: currentColor;
    will-change: transform;
    transition: transform 200ms cubic-bezier(.01,.65,.23,1);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  }

  &:checked {
    background-color: aquamarine;

    &::before {
      transform: translateX(100%);
    }
  }
}
Related