Snippets

Safari bug with gradients that fade to "transparent"

Say you have a gradient in CSS that goes from red to transparent. Easy, right? Like this:

Code language: CSS

.element {
  background: linear-gradient(
    to bottom,
    red, 
    transparent
  );
}

There is a pretty big gotcha here, though.

In Chrome (also Android), Firefox, and Edge, you’d be all good.

But in Safari (also iOS), you’d not be good.

The same test page as before, viewed in both the iOS simulator version of Safari, and the macOS version of Safari. The two rectangles, each with a gradient background colour are different this time. The red in the rectangle on the left fades from red to black, as it fades to transparent, which appears to be a bug. The rectangle on the right fades to transparent while still maintaining the red colour, as expected.
The element on the left in each browser demonstrates the problem.

The problem, the best I understand it, is that transparent is being interpreted (and interpolated) as “transparent black”.

To fix it, you have to set the color as a fully transparent version of that exact color. Like:

Code language: CSS

.element {
  background: linear-gradient(
    to bottom,
    red,
    rgba(255, 0, 0, 0)
  )
}

[…]

Sass can help out, if you are using that:

Code language: Sass

.element {
  background: linear-gradient(
    to bottom,
    #eb8fa9,
    rgba(#eb8fa9, 0);
  )
}

The limits of @supports

@supports may be very useful, but it can only tell you so much, especially in the case of browsers that will return true, technically supporting the feature, but having a buggy implementation. This is a case where we can often assume too much about a browser based on a reductive test that isn’t guaranteed to tell us what we think it does. PPK explains:

If a mobile browser doesn’t support background-attachment: fixed in practice, what happens when you do this?

Code language: CSS

@supports(background-attachment: fixed) {
	// CSS
}

Does it return false because the mobile browser doesn’t support it? Or does it return true because its desktop version supports it? With my background-attachment test data in hand I could now answer this question.

All mobile browsers return true for both fixed and local. Only 3 out of 23 browsers speak the truth here. See the test case and the inevitable table for more details.

[…]

What’s clear from these tests is that @supports is only useful when you’re detecting entire CSS modules such as flexbox. So the check below makes sense.

Code language: CSS

@supports (display: flex) {
	// flexbox layout
}
 
@supports not(display: flex) {
	// float layout
}

This example is likely safe. If a browser decides to support flexbox, display: flex is the first item on the agenda, so detecting it makes perfect sense. (It’s theoretically possible, though, that a browser fakes display: flex support in order to end up on the right side of some support detects. But as far as I know this is not the case today.)

On the other hand, if a browser has flaky support for, I don’t know, justify-content, a more precise check like this may or may not work, depending on how the CSS parser is written:

Code language: CSS

@supports (justify-content: space-around) {
	// may or may not fire correctly in case
	// of a browser bug
}

So this example is unsafe. Don’t use @supports for such detailed compatibility questions.

The Bias in What We Build

I’ve been thinking a lot lately about our biases and their influence on what we build and how. We’re all biased in some way—it’s an inevitable side-effect of living. We experience certain things, we live in a certain environment, we have certain interactions and over time all of these experiences and factors add up to impact the way we view ourselves and the way we view others.

These biases come into play over and over again in our work, and can have devastating consequences.

There was an interesting post on The Coral Project about anonymity and its impact—or rather, non-impact—on online behavior. A frequent refrain heard when we try to understand why online behavior is so frequently so poor is that the ability to be anonymous is one of the primary reasons for the problem. J. Nathan Matias argues differently, though:

Not only would removing anonymity fail to consistently improve online community behavior – forcing real names in online communities could also increase discrimination and worsen harassment.

We need to change our entire approach to the question. Our concerns about anonymity are overly-simplistic; system design can’t solve social problems without actual social change.

While the article cites a little bit of research questioning our assumptions about anonymity online, the bulk of the article is focused on reframing our perspective of the discussion. We often consider the question of bad behavior online from the perspective of the people misbehaving. What is it that makes them feel free to be so much more vindictive in an online setting? Matias instead builds his case by focusing on the victims of this behavior.

Revealing personal information exposes people to greater levels of harassment and discrimination. While there is no conclusive evidence that displaying names and identities will reliably reduce social problems, many studies have documented the problems it creates. When people’s names and photos are shown on a platform, people who provide a service to them – drivers, hosts, buyers – reject transactions from people of color and charge them more. Revealing marital status on DonorsChoose caused donors give less to students with women teachers, in fields where women were a minority. Gender- and race-based harassment are only possible if people know a person’s gender and/or race, and real names often give strong indications around both of these categories. Requiring people to disclose that information forces those risks upon them.

[…]

[O]ne thing we can state about removing anonymity is that it increases the risk for people on the receiving end of online harassment.

Removing anonymity online, then, is yet another example of how we reflect our own biases in the decisions we make and the things we build.

It is our biases that lead us to overlook accessibility or how an application performs on a low-powered device or spotty network.

It is our biases that lead us to develop algorithms that struggle to recognize women’s voices or show more high-paying executive jobs to men than women.

And it is our biases that lead us to frame the problem of online behavior from that of the attacker, leading to solutions that are dangerous for the people on the receiving end of that harassment.

In each of these situations, our biases don’t just lead us to build something that is hard to use; they cause us to actively, if unintentionally, exclude entire groups of people.

Vertical viewport units are unreliable on mobile

When I was first styling Resilient Web Design, I made heavy use of vh units. The vertical spacing between elements—headings, paragraphs, images—was all proportional to the overall viewport height. It looked great!

Then I tested it on real devices.

Here’s the problem: when a page loads up in a mobile browser—like, say, Chrome on an Android device—the URL bar is at the top of the screen. The height of that piece of the browser interface isn’t taken into account for the viewport height. That makes sense: the viewport height is the amount of screen real estate available for the content. The content doesn’t extend into the URL bar, therefore the height of the URL bar shouldn’t be part of the viewport height.

But then if you start scrolling down, the URL bar scrolls away off the top of the screen. So now it’s behaving as though it is part of the content rather than part of the browser interface. At this point, the value of the viewport height changes: now it’s the previous value plus the height of the URL bar that was previously there but which has now disappeared.

[…]

In my initial implementation of Resilient Web Design, the one where I was styling almost everything with vh, the site was unusable. Every time you started scrolling, things would jump around. I had to go back to the drawing board and remove almost all instances of vh from the styles.