Why do CSS changes to ::after affect ::before as well?

Viewed 68

Why is it that setting either display:none or content:none on the ::after element in these blockquotes causes the ::before element to be half-hidden, except in the first element for some reason? You can see in the snippet that display:none is set on the ::after pseudoelement and if you remove it the quotes show up properly.

let quotes = document.querySelector('#quotes'),
        json = [
        {"author_name":"Socrates",
            "relative_time_description":"2395 years ago",
            "text":"Few persons ever reflect, as I should imagine, that from the evil of other men something of evil is communicated to themselves."},
      {"author_name":"Socrates",
            "relative_time_description":"2395 years ago",
            "text":"Then must we not infer that all these poetical individuals, beginning with Homer, are only imitators; they copy images of virtue and the like, but the truth they never reach? The poet is like a painter who, as we have already observed, will make a likeness of a cobbler though he understands nothing of cobbling; and his picture is good enough for those who know no more than he does, and judge only by colors and figures."},
      {"author_name":"Damon",
            "relative_time_description":"circa 3000 years ago",
            "text":"...when modes of music change, the fundamental laws of the State always change with them."}];
                
Object.keys(json).forEach(function(key){
  let r = json[key],
      tpl = document.querySelector('#tpl').content.cloneNode(true);

  tpl.querySelector('blockquote').childNodes[0].nodeValue = r.text;
  tpl.querySelector('.author').textContent = r.author_name;
  tpl.querySelector('.ago').textContent = r.relative_time_description;

  quotes.appendChild(tpl);
});
html{font-size:20px;}
#quotes {
    list-style: none;
    margin: 1em 0;
    padding: 1em 0;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-around;
    align-items: stretch;
}
#quotes li {
    flex: 1 1 auto;
    max-width: 10em;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: stretch;
    align-items: stretch;
}
html blockquote {
    position: relative;
    margin: 1em 0;
    padding: .618em 1.236em;
    border-left: 6px solid #bf0a30;
    background: #002868;
    color: #e6e6e6;
}
.quote {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: stretch;
    align-items: stretch;
    font-size: .8em;
}
cite{padding:1em 0 0;}
cite p{margin:0;}
html blockquote::before, html blockquote::after {
    position: absolute;
    top: 33%;
    font-size: 1em;
    font-weight: 700;
}
html blockquote::before {
    content: open-quote;
    left: .155em;
}
html blockquote::after {
    content: close-quote;
    right: .155em;
}
.quote::before,.quote::after{top:auto}
.quote::after{bottom:0; display:none;}
<ul id="quotes">
  
</ul>

<template id="tpl">
  <li>
    <blockquote class="quote">
      <cite>
        <p class="author"></p>
        <p class="ago"></p>
      </cite>
    </blockquote>
  </li>
</template>

Here's a fiddle if you prefer that: https://jsfiddle.net/nsr0m3oc

1 Answers

It seems to have something to do with the behavior of the open-quote and close-quote, which you are applying to :after and :before.

If you do want an open-quote, but NOT close-quote. You simply need to add no-close-quote instead.

Just like this:

html blockquote::after {
    content: no-close-quote;
    right: .155em;
    z-index: 1;
}

Also, remember to remove the display: none; that you put on :after, or else this wont work.

Let me know if it helped :)

EDIT TO ANSWER COMMENT

Because you haven't defined a quotes property on your blockquote element, the default value becomes: quotes: "“" "“" "'" "'";. Note: the default value is different for each language. See lang attribute.

The two first quotation marks in the quotes property will always be used on non-nested quotes, so "“" "“" will be used in this case.

The two last quotation marks will always be used on nested quotes, so "'" "'" will be used in this case.

In your case you removed all closing quotes. So technically your first quote never got closed. Because it was never closed, all following quotes technically became nested quotes - therefore "'" "'" was used for all quotes, except for the first quote.

By adding content: no-close-quote;, as I suggested above, you tell the browser that even though it shouldn't render a close-quote. The quote should still be closed. Therefore if you add content: no-close-quote;, all quotes following the first will use "“" "“" instead of "'" "'".

Hopefully my clarification made sense. Please let me know if it did.

Related