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
.
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 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 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.