0

I have a pseudo class on a <label> tag to show a check when the option has been checked. It was doing all these crazy things with positioning, throwing all of the pseudo elements into the top corner, and even showing two of the same ::after element on hover.

I finally figured out that I had filter: brightness(.9) on :hover, but no filter: brightness on the base <label> CSS. Once I added filter: brightness(1) to the base element, the problem vanished.

Here is a fiddle. First, hover over the check(s) in the top right corner and the blue buttons to see the issue. Then uncomment the filter: brightness(1) line to see the fix. I made it a bit ugly so the problem would be readily visible.

But now I'm left scratching my head. What was going on? It seems like by not having the filter on, the CSS forgot which element was the parent element and just referenced the last non-statically positioned element. Why would this happen? Are there any other cases like this?

Benny Hinrichs
  • 1,393
  • 9
  • 17
  • 2
    Your label is missing `position: relative` so of course the check mark will fly to the top – Huangism Jan 10 '19 at 17:32
  • 2
    Also note that a filter (other than `none`) creates a new [stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context), and IIRC that includes making it relative (which is why adding `filter` to the label works) – chazsolo Jan 10 '19 at 17:36
  • Thanks! Upvotes to both of you. Is there any reason why it creates two when you hover the element? – Benny Hinrichs Jan 10 '19 at 17:37
  • 1
    @BennyHinrichs what do you mean it creates two? you mean when you hover the top right checkmark? It doesn't create 2, when you hover, it applies filter which in turn changes the element to a containing block (position relative, basically) once this occurs, the checkmark returns to the correct position in the button, but now it is no longer hovered and returns to the top right. This repeats as long as you are hovered and thus it is why it flashes – Huangism Jan 10 '19 at 17:43
  • Right, thanks! I actually figured that out like 10 seconds before you answered, and was going to edit my comment, but you beat me to the punch – Benny Hinrichs Jan 10 '19 at 17:45
  • I left an answer in case these comments gets lost – Huangism Jan 10 '19 at 17:47

1 Answers1

2

The original issue is that your label is missing

position: relative;

So that the arrow is at the top since it is absolute, not contained in the button.

When you add filter to it, the element is changed to a containing block (it's what filter does) so it has the effect of position: relative and it is why everything looks normal.

In your fiddle, when you hover, it applies filter which in turn changes the element to a containing block (position relative, basically) once this occurs, the checkmark returns to the correct position in the button, but now it is no longer hovered and returns to the top right. This repeats as long as you are hovered and thus it is why it flashes

Huangism
  • 16,278
  • 7
  • 48
  • 74