title: Why do the :before and :after pseudo-elements require a 'content' property?
body: <p>Given the following scenario, why does the <code>:after</code> selector require a content property to function?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.test {
      width: 20px;
      height: 20px;
      background: blue;
      position:relative;
  }
     
  .test:after {
      width: 20px;
      height: 20px;
      background: red;
      display: block;
      position: absolute;
      top: 0px;
      left: 20px;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="test"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Notice how you do not see the pseudo element until you specify the content property:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.test {
      width: 20px;
      height: 20px;
      background: blue;
      position:relative;
  }
     
  .test:after {
      width: 20px;
      height: 20px;
      background: red;
      display: block;
      position: absolute;
      top: 0px;
      left: 20px;
      content:"hi";
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="test"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Why is this the intended functionality?  You would think that the display block would force the element to show up.  Oddly enough, you can actually see the styles inside web debuggers; however, they do not display on the page.</p>