I have an element on which I use a pseudo-element (::after
) to style an overlay. For technical reasons I cannot/don't want to use another element (e.g. div
) to add the overlay. The pseudo-element is absolutely positioned and appears in front off the actual element. I was surprised to see that the text inside the div
is still selectable, "through" the pseudo-element. I've played around with z-index
and pointer-events
, without success. See this fiddle for an (external) example.
Why is this happening? Why can the text still be selected with the mouse? Is there any other solution apart for user-select
?
div {
position: relative;
}
div::after {
position: absolute;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0.4;
background-color: black;
}
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sollicitudin dui nec neque rutrum, eu auctor nulla accumsan. Quisque non eleifend nibh. Fusce aliquet imperdiet odio vitae pretium. Nam tincidunt mattis ante, nec consectetur diam maximus
vel. Fusce at lectus porttitor, feugiat purus sed, porta felis. Morbi tempus ante a orci finibus rhoncus. Nullam a porta enim. Sed id eros convallis, consectetur turpis a, gravida nunc. Nullam sed dui interdum diam placerat suscipit sit amet nec mi.
Maecenas ultricies metus massa, id vestibulum nisi posuere facilisis. Aliquam erat volutpat. Quisque blandit condimentum augue. Nullam pulvinar turpis libero, id luctus dolor ultricies quis.</p>
</div>
As for your question:
Why is this happening?
It's seems to due to the fact that generated content itself is not selectable. see How can I make generated content selectable?)
Try selecting the text in the following snippet:
div:before {
content: 'generated content - before... ';
}
div:after {
content: '...generated content - after';
}
<div>Only content of div is selectable</div>
So apparently, selection is about selecting only elements which appear in the DOM and according to the CSS 2.1 spec:
Neither pseudo-elements nor pseudo-classes appear in the document source or document tree.
So when selecting on the overlay - the overlay is ignored, and instead the text in the div is selected
That being said, the spec here seems to say that generated content should be selectable
Generated content should be searchable, selectable, and available to assistive technologies
...but to my knowledge that bit of the spec has not been implemented in any browser.
If you don't want to use user-select: none
an alternative can be to set as transparent the ::selection
.
p::selection {
background-color: transparent;
}
This doesn't just hide the selection but also make it impossible to highlight. It is compatible with most of the browser except mobile ones and Firefox (you have to use ::-moz-selection
).
div::after {
position: absolute;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0.4;
background-color: black;
}
p::selection {
background-color: transparent;
}
p::-moz-selection {
background-color: transparent;
}
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sollicitudin dui nec neque rutrum, eu auctor nulla accumsan. Quisque non eleifend nibh. Fusce aliquet imperdiet odio vitae pretium. Nam tincidunt mattis ante, nec consectetur diam maximus
vel. Fusce at lectus porttitor, feugiat purus sed, porta felis. Morbi tempus ante a orci finibus rhoncus. Nullam a porta enim. Sed id eros convallis, consectetur turpis a, gravida nunc. Nullam sed dui interdum diam placerat suscipit sit amet nec mi.
Maecenas ultricies metus massa, id vestibulum nisi posuere facilisis. Aliquam erat volutpat. Quisque blandit condimentum augue. Nullam pulvinar turpis libero, id luctus dolor ultricies quis.</p>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With