CSS-Hacks

Firefox Fun

Dwight Doane

October 17, 2019

This was about a year ago. For the chat feature of our app at work, we relied on flexbox and column-reverse to set the order in which messages came in.

Part of the challenge was keeping the scroll position at the bottom of the window. There’s a bug in Firefox where it doesn’t scroll when you apply overflow-y and column-reverse.

initial css:
display: flex;
flex-direction: column-reverse;
height: 225px;
overflow-y: scroll;
border: 1px solid #eee;
border-radius: 4px;
padding: 2px 4px;

Taking advantage of the @supports feature query, I can apply Firefox specific stylings.

This Div should not scroll in firefox
  • this is a message 0
  • this is a message 1
  • this is a message 2
  • this is a message 3
  • this is a message 4
  • this is a message 5
  • this is a message 6
  • this is a message 7
  • this is a message 8
  • this is a message 9
  • this is a message 10
  • this is a message 11
  • this is a message 12
  • this is a message 13
  • this is a message 14
  • this is a message 15
  • this is a message 16
  • this is a message 17
  • this is a message 18
  • this is a message 19


So to get around that I tried to use css rotation.

I rotated the whole list 180deg, and then rotated each list item itself back 180deg so they are right side up.


@supports (-moz-appearance: none) {
  ul {
    border: 1px solid red !important;
    flex-direction: column !important;
    -moz-transform: rotate3d(1, 0, 0, 180deg);
    & li {
      -moz-transform: rotate3d(1, 0, 0, 180deg);
    }
  }
}

This div should be red in Firefox.
  • this is a message 0
  • this is a message 1
  • this is a message 2
  • this is a message 3
  • this is a message 4
  • this is a message 5
  • this is a message 6
  • this is a message 7
  • this is a message 8
  • this is a message 9
  • this is a message 10
  • this is a message 11
  • this is a message 12
  • this is a message 13
  • this is a message 14
  • this is a message 15
  • this is a message 16
  • this is a message 17
  • this is a message 18
  • this is a message 19

However if I recall correctly that caused issues with Safari 11. It flipped the scroll direction.

Unfortunately I don’t have access to Safari 11 to test or get screenshots. You’ll just have to trust me

So I had to go back to the drawing board.


This time I took advantage of css custom properties

I encode an order property on the list item as a css custom property.

export const WithoutRotation = () => (
  <WithoutRotation_>
    <StyledUl>
      {xs.map(n => (
        <li style={{ "--order": n * -1 }}>this is a message {n}</li>
      ))}
    </StyledUl>
  </WithoutRotation_>
)

Then in the css, only for Firefox I reset the ul’s flex direction to column and essentially reverse the order with the flexbox order property (multiplying it by -1).

@supports (-moz-appearance: none) {
  ul {
    border: 1px solid blue !important;
    flex-direction: column !important;
    & li {
      order: var(--order);
    }
  }
}
This div should be blue in Firefox.
  • this is a message 0
  • this is a message 1
  • this is a message 2
  • this is a message 3
  • this is a message 4
  • this is a message 5
  • this is a message 6
  • this is a message 7
  • this is a message 8
  • this is a message 9
  • this is a message 10
  • this is a message 11
  • this is a message 12
  • this is a message 13
  • this is a message 14
  • this is a message 15
  • this is a message 16
  • this is a message 17
  • this is a message 18
  • this is a message 19

Which as you can see almost works. The only problem is the scroll position is at the top. but the messages are in order.

I forget exactly what changed, but this hack is no longer in our codebase. I’ve been meaning to write about it for a while. Stay tuned for more.

*All snippets above are taken from the demo source code located in this repo. Not actual code from the app I work on.



A place to share awesome frontend hacks and workarounds