text-decoration and pointer-events of anchor pseudo-elements
I have a big confusion regarding this topic. With the attached html, I am getting what's in the attached screenshot:
- Why is it showing an underline as text-decoration for the ::after, but not the ::before
- Why is the underline on the ::after not gone, even though I've set it to
text-decoration: none
- Why is pointer-events: none
ignored?
I suppose "it's just how anchors work". This means I have to break them into three individual html elements? Would be very unfortunate and a big loss in hygiene of my markup 😐20 Replies
It would be best if you set up a Codepen or similar with your code. That would make it easier for somebody to help you.
Seems to be login-walled and I don't have an account
it's free to sign up to codepen
or use jsfiddle, which doesn't require an account, but everything is publicly shared
Thanks for posting the code. I don't think that that was there when I answered yesterday though I was looking at it on the mobile so maybe it wasn't showing up on my device.
Some interesting questions here.
"Why is it showing an underline as text-decoration for the ::after, but not the ::before"
I believe that this is because you have converted the
::before
element into a block element by using display: inline-grid;
.
According to the spec block elements must not be underlined:
https://www.w3.org/TR/CSS21/text.html#propdef-text-decoration
...For all other elements it is propagated to any in-flow children. Note that text decorations are not propagated to floating and absolutely positioned descendants, nor to the contents of atomic inline-level descendants such as inline blocks and inline tables. Underlines, overlines, and line-throughs are applied only to text (including white space, letter spacing, and word spacing): margins, borders, and padding are skipped. User agents must not render these text decorations on content that is not text. For example, images and inline blocks must not be underlined."Why is the underline on the ::after not gone, even though I've set it to text-decoration: none" As I understand it, I think that that is explained in the same link as before by this section:
The 'text-decoration' property on descendant elements cannot have any effect on the decoration of the ancestor.I further tested this by adding an inline span to your link and, despite giving that a
text-decoration: none;
, it still had the underline.
Note, you can, of course, override this by using what is explained in the answer to your first question, that is by converting the element into a block element, for example with display: inline-block;
"Why is pointer-events: none ignored?"
I have not had time to investigate this one but I suspect that the reason is similar to the previous explanation. A child element can't override the parent link basic properties. As the ::a is within the link, it has the parent pointer events.
However, if I have time, I will look for more details on this one.basically, the
pointer-events: none
is doing what it should: no pointer events to the (pseudo-)element
which means, when you out the mouse over the ::before or ::after, there are no pointer events for it
but you know what there is? there's a link taking the space
so, the pointer event will "go through" ::before and ::after, and trigger it on whatever is next on the stack: the <a>
if you dont want the ::before or ::after to allow clicking the link, you need to set position: absolute
to the elementI also just tested this by moving the pseudo element outside of the bounds of it's parent using
translate
and, as you say, it doesn't have the pointer-events 👍that works too
this is when thinking about in 3 dimentions is important
Edit fiddle - JSFiddle - Code Playground
Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.
check that: only the one with the ::after outside the flow (with position absolute) isnt triggering the link
Hi, thanks for getting back. The code had been there from the beginning but nvm.
This is a little frustrating as it seems several things are fighting with one another (hidden descendantry shenanigans, "go through" stuff you cannot win against).
I refrain from using
position: absolute
as much as possible as the alignment across browsers never seems to be 100% consistent for me, and it also makes the code more complicated in general.
No matter if I use display: inline-block
, the issues all persist.
I'm quite gutted about it, but I'm afraid I cannot use pseudo-elements and instead must complicate my markup with actual elements to style them the way I want 😦or just use an <u> tag for the text
and you dont have to fight for styles
about the pointer events, it is working exactly as it should
if you put a transparent pane of glass on a table, you expect to clearly see whats under
the pseudo-element with pointer-events set to none becomes a pane of glass
the pointer events are triggered because it is still inside the parent
there is nothing wrong with that, there is no fighting, there are no conflicts
it's doing exactly what it should
Okay
I'm going to wrap my anchors into a div, and give the ::before and ::afters to that. That way the CSS can stay the same, and the anchor text-decoration and pointer-events are under control. Still, an additional div wrapping I would've preferred to avoid.
if you do that, you don't need to mess about with
pointer-events
and depending on what you want to do, you shouldn't use a <div>
Yeah I can leave out pointer-events
I want to do what I have in my code in the OP
to do exactly that, with just a link and no changes to the code, you have to do "hacks"
also, you don't need to do any positioning with
position: absolute
Yeah I figured. I've accepted the added markup. Was hoping it would be possible to it done without to keep it cleaner. But thanks for trying to help 🙏
you're welcome
unfortunately, what you want to do is a bit more annoying than it looks like
haha yeah, I keep running into these things
Another pet peeve of mine is to align several items with text and ::before icons on the same baseline, but when they're nested in different divs. I think sub-grid can do some tricks with that. But, for another thread.
yeah, aligning stuff gets annoying