Based on your comments on others' answers, I believe your question is actually:
Why must the content property for pseudo-classes be set in the CSS, as
  opposed to the content of non-pseudo-classes, which may be set in
  either HTML or CSS?
The reason is that:  
- by definition, pseudo-classes are dynamically created for every single element specified by a page's HTML markup  
- all page elements, including pseudo-classes, must have a content property to be displayed.  
- HTML elements like <p>do as well, but you can set their content property quickly using markup (or with CSS declarations).
- Howver, unlike non-pseudo-class-elements, pseudo-classes cannot be given values in the markup itself.
 ∴ Therefore, all pseudo-classes are invisible (their 'content' properties have no value) unless you tell them not to be (by giving them value with CSS declarations).
Take this simple page:
<body>
<p> </p>
</body>
We know this page will display nothing, because the <p> element has no text.  A more accurate way to rephrase this, is that the <p> element's content property has no value.
We can easily change this, by setting the content property of the h1 element in the HTML markup:
<body>
<p>This sentence is the content of the p element.</p>
</body>
This will now display when loaded, because the content property of the <p> element has a value;  that value is a string:
"This sentence is the content of the p element."
Alternatively, we can cause the <p> element to be displayed by setting the content property of the <p> element in the CSS:
p { content: "This sentence is the content of the p element set in the CSS."; }
These two ways of injecting the string into the <p> element are identical.
Now, consider doing the same thing with pseudo-classes:
HTML:
  <body>
      <p class="text-placeholder">P</p>
  </body>
CSS:
  p:before { content: "BEFORE... " ; }
  p:after { content: " ...and AFTER"; }
The result: 
BEFORE...  P ...and AFTER
Finally, imagine how you would accomplish this example without using CSS.  It's impossible, because there is no way to set the content of the pseudo-class in the HTML markup.
You might be creative and imagine something like this might work:
<p:before>BEFORE... </p>
<p> P </p>
<p:after> ...and AFTER</p>
But, it doesn't, because <p:before> and <p:after> are not HTML elements.
In conclusion:  
- Pseudo classes exist for every markup element.  
- They are invisible by default, because they are initialized with no content property.  
- You CANNOT set the content property for pseudo classes with HTML markup.
 ∴ Therefore, pseudo-elements' content property must be declared with CSS declarations, in order to be displayed.