Nesting pseudo-elements inside pseudo-elements

I have a :before for an opening 'quote' and an :after for a closing quote.

Now what I want is an :after:after for the 'cite' reference but I cant get it to work.

Does anyone know if this is possible?

My code so far:-

blockquote:before { content: '\201C'; }
blockquote:after { content: '\201D'; }

blockquote {
  font-size: 22px;
  line-height: 24px;
  text-indent:60px;
}
blockquote:before {
  font-size: 170px;
  margin-left: -136px;
  margin-top: 50px;
  opacity: 0.2;
  position: absolute;
  overflow:visible;
  float:left;
  width:135px;
}
blockquote:after {
  float: right;
  font-size: 170px;
  margin-right: 35px;
  margin-top: 33px;
  opacity: 0.2;
  overflow:visible;
  width:135px;
}
blockquote[cite]:after:after {
    display: block;
    text-align: right;
    content: "\2014\ " attr(cite);
    font-style: normal;
    font-size: 0.8em;
    }

Solution 1:

The idea of nesting ::before and ::after pseudo-elements has been proposed; see this section of the Generated and Replaced Content module. However, that module has been abandoned pending a complete rewrite, so I wouldn't hold my breath on this document ever receiving implementation until it's republished. And even then, whether nesting content pseudo-elements will still be a thing is as yet unknown.

Solution 2:

Regarding the content of the OP question i.e. creating generated content after blockquote to include citation along with close-quote.
We can use image in pseudo element's content ref:

content: url("data:image/svg+xml,<svg>...close-quote...</svg>") " \2014 "attr(cite);

blockquote {
  font-size: 22px;
  line-height: 24px;
  text-indent: 10px;
  position: relative;
}

blockquote:before {
  content: url("data:image/svg+xml, %3Csvg preserveAspectRatio='none' version='2.0' xmlns='http://www.w3.org/2000/svg' hei ='45px' width='25px' viewBox='0 0 191.029 191.029' x='0px' y='0px' %3E%3Cg transform='translate(0 -10) scale(0.8) '%3E%3E%3Cpath style='fill:%23777;' d='M44.33,88.474v15.377h38.417v82.745H0v-82.745h0.002V88.474c0-31.225,8.984-54.411,26.704-68.918%0AC38.964,9.521,54.48,4.433,72.824,4.433v44.326C62.866,48.759,44.33,48.759,44.33,88.474z M181.107,48.759V4.433%0Ac-18.343,0-33.859,5.088-46.117,15.123c-17.72,14.507-26.705,37.694-26.705,68.918v15.377h0v82.745h82.744v-82.745h-38.417V88.474%0AC152.613,48.759,171.149,48.759,181.107,48.759z' /%3E%3C/g%3E%3C/svg%3E");
  opacity: 0.5;
  padding-right: 10px;
}

blockquote[cite]:after {
  content: url("data:image/svg+xml,%3Csvg version='2.9' xmlns='http://www.w3.org/2000/svg' hei ='35px' width='25px' x='0px' y='0px' viewBox='0 0 349.078 349.078' preserveAspectRatio='none'%3E%3Cg transform='translate(0 90) scale(0.8) '%3E%3E%3Cpath style='fill:%23777;' d='M198.779,322.441v-58.245c0-7.903,6.406-14.304,14.304-14.304c28.183,0,43.515-28.904,45.643-85.961h-45.643 c-7.897,0-14.304-6.41-14.304-14.304V26.64c0-7.9,6.406-14.301,14.304-14.301h121.69c7.896,0,14.305,6.408,14.305,14.301v122.988 c0,27.349-2.761,52.446-8.181,74.611c-5.568,22.722-14.115,42.587-25.398,59.049c-11.604,16.917-26.132,30.192-43.155,39.437 c-17.152,9.304-37.09,14.026-59.267,14.026C205.186,336.745,198.779,330.338,198.779,322.441z M14.301,249.887 C6.404,249.887,0,256.293,0,264.185v58.257c0,7.896,6.404,14.298,14.301,14.298c22.166,0,42.114-4.723,59.255-14.026 c17.032-9.244,31.558-22.508,43.161-39.437c11.29-16.462,19.836-36.328,25.404-59.061c5.423-22.165,8.178-47.263,8.178-74.6V26.628 c0-7.9-6.41-14.301-14.304-14.301H14.301C6.404,12.327,0,18.734,0,26.628v122.988c0,7.899,6.404,14.304,14.301,14.304h45.002 C57.201,220.982,42.09,249.887,14.301,249.887z'/%3E%3C/g%3E%3C/svg%3E") " \2014 "attr(cite);
  font-size: 0.8em;
  position: relative;
  top: 10px;
  opacity: 0.5;
  padding-left: 10px;
}
<blockquote cite='Person'>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore accusamus ipsum cumque culpa natus magnam earum, inventore iure et harum.</blockquote>


But as per standards citation needs to be an URL:

If the cite attribute is present, it must be a valid URL potentially surrounded by spaces. To obtain the corresponding citation link, the value of the attribute must be parsed relative to the element's node document. User agents may allow users to follow such citation links, but they are primarily intended for private use (e.g., by server-side scripts collecting statistics about a site's use of quotations), not for readers.

Attribution for the quotation, if any, must be placed outside the blockquote element.

Above code can be rewritten as per standard:

blockquote {
  font-size: 22px;
  line-height: 24px;
  text-indent: 10px;
  position: relative;
  background: #eee;
  border-radius: 10px;
  padding: 10px;
}

blockquote:before {
  content: url("data:image/svg+xml, %3Csvg preserveAspectRatio='none' version='2.0' xmlns='http://www.w3.org/2000/svg' hei ='45px' width='25px' viewBox='0 0 191.029 191.029' x='0px' y='0px' %3E%3Cg transform='translate(0 -10) scale(0.8) '%3E%3E%3Cpath style='fill:%23777;' d='M44.33,88.474v15.377h38.417v82.745H0v-82.745h0.002V88.474c0-31.225,8.984-54.411,26.704-68.918%0AC38.964,9.521,54.48,4.433,72.824,4.433v44.326C62.866,48.759,44.33,48.759,44.33,88.474z M181.107,48.759V4.433%0Ac-18.343,0-33.859,5.088-46.117,15.123c-17.72,14.507-26.705,37.694-26.705,68.918v15.377h0v82.745h82.744v-82.745h-38.417V88.474%0AC152.613,48.759,171.149,48.759,181.107,48.759z' /%3E%3C/g%3E%3C/svg%3E");
  opacity: 0.5;
  padding-right: 10px;
}

blockquote[cite]:after {
  content: url("data:image/svg+xml,%3Csvg version='2.9' xmlns='http://www.w3.org/2000/svg' hei ='35px' width='25px' x='0px' y='0px' viewBox='0 0 349.078 349.078' preserveAspectRatio='none'%3E%3Cg transform='translate(0 90) scale(0.8) '%3E%3E%3Cpath style='fill:%23777;' d='M198.779,322.441v-58.245c0-7.903,6.406-14.304,14.304-14.304c28.183,0,43.515-28.904,45.643-85.961h-45.643 c-7.897,0-14.304-6.41-14.304-14.304V26.64c0-7.9,6.406-14.301,14.304-14.301h121.69c7.896,0,14.305,6.408,14.305,14.301v122.988 c0,27.349-2.761,52.446-8.181,74.611c-5.568,22.722-14.115,42.587-25.398,59.049c-11.604,16.917-26.132,30.192-43.155,39.437 c-17.152,9.304-37.09,14.026-59.267,14.026C205.186,336.745,198.779,330.338,198.779,322.441z M14.301,249.887 C6.404,249.887,0,256.293,0,264.185v58.257c0,7.896,6.404,14.298,14.301,14.298c22.166,0,42.114-4.723,59.255-14.026 c17.032-9.244,31.558-22.508,43.161-39.437c11.29-16.462,19.836-36.328,25.404-59.061c5.423-22.165,8.178-47.263,8.178-74.6V26.628 c0-7.9-6.41-14.301-14.304-14.301H14.301C6.404,12.327,0,18.734,0,26.628v122.988c0,7.899,6.404,14.304,14.301,14.304h45.002 C57.201,220.982,42.09,249.887,14.301,249.887z'/%3E%3C/g%3E%3C/svg%3E");
  position: relative;
  top: 10px;
  opacity: 0.5;
  padding-left: 10px;
}

blockquote + figcaption{
  float:right;
}
<figure>
  <blockquote cite="https://www.huxley.net/bnw/four.html">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore accusamus ipsum cumque culpa natus magnam earum, inventore iure et harum.
  </blockquote>
  <figcaption>—Person, <cite>Book</cite></figcaption>
</figure>


I know the bounty has been raised for info about nesting pseudo elements. Just trying to address the question in the original post.

Solution 3:

The W3C Recommendation is quite clearly against nesting pseudo-elements:

Only one pseudo-element may appear per selector, and if present it must appear after the sequence of simple selectors that represents the subjects of the selector.

Note: A future version of this specification may allow multiple pseudo-elements per selector.

However and interestingly enough, the Jigsaw validator does accept the following CSS code:

p::before { content: "test1"; }
p::before::before { content: "test2"; }

I’m not sure if that’s nothing but fluke.