You could set `display: contents` on the outer element – this will put ::before in the parent flow instead. But then the quote mark becomes a text node and you can't pull that back without another wrapper element:
And then she said:
<char-hang><span>“</span></char-hang>Hello,
handsome! What a day, huh?
which will be rendered like this:
"And then she said: "
<!-- push: -->
<char-hang::before />
<!-- pull: -->
<span>“</span>
"Hello, handsome! What a day, huh?"
Without adding another element, you can use a hack though: make the quote mark transparent and use text-shadow to “move” it back instead: https://jsfiddle.net/utjxnv1r/3/
And if we allow JS, we can just create a custom element and avoid those hacks altogether (also you don't have to calculate / eyeball the offset you need anymore): https://jsfiddle.net/c72uLtma/
And if we allow JS, we can just create a custom element and avoid those hacks altogether (also you don't have to calculate / eyeball the offset you need anymore): https://jsfiddle.net/c72uLtma/