CSS: How to get the masked text effect from the Apple iPhone XR promo pages
I am a sucker for cool typography effects.
As most āgeeksā, I was aware of Appleās event this week, where they announced (among other stuff) some new iPhones.
When checking out the promo website for the new iPhones, some of the text and design caught my eye. I couldnāt remember immediately how it was done, so I thought it would be a fun opportunity to (re-) learn/visit a technique, and maybe write a little breakdown.
And here we are!
The Effect
Thereās a couple things I want to point out, but first, hereās the effect in question, as it appears on the promo page for the iPhone XR:
Itās got:
- Cool textured/colored āmaskedā text. Itās not an image!
- Some text thatās not masked, that appears to be in the same paragraph.
TL;DR
If you wanna skip right to the code for the first example, hereās the CodePen where I first broke down the effect as they used it:
Figuring it out
The first thing I did was pop open the Dev Tools and find out what was going on. For some reason, I was expecting something a bit more complicated, but I still want to break it down.
The innermost parts
Inspecting the actual paragraph, I noticed that itās actually made of two things: an h2
(heading tag)
followed by a regular paragraph (which is the text with the cool textured effect).
This screenshot of the dev tools is a little noisy, but I highlighted the important parts that weāll talk about firstā¦
Namely:
- Thereās a containing
div
with a couple of interesting class names:masked-copy
, andtexture-1
. Both good clues. - The heading tag has a class of
inline
, which does exactly what you might think. - The actual text paragraph.
The container and itsā background
That texture-1
class defines the color, and a particular ābackground imageā that
will be used for the paragraph(s) inside. Iām going to rename it for our
examples, hopefully to make it a little more clear. Itās defined something like this:
.texture-orange {
background-repeat: no-repeat;
background-image: url('path/to/texture-orange.jpg');
}
Those background images are actually some seriously bright, colorful, taller-than-they-are-wide, swirly, gradient texture images. Assuming theyāre still at the same URL, you can see one here.
Hereās a very small example of the kind of thing going on in that background image:
So, the container has a background image. Weāll come back to that!
The text color āfallbackā
Next, I noticed that the paragraph had a color set by the texture-1
class ā something in the neighborhood
of the background that would later be applied (in this case #e5895f
for the
orange and purple texture/gradient). That color is overridden, however, by
the masked-copy
rules, that specify a transparent ācolorā for the text. So
far, we have some rules that look like this:
.texture-orange {
color: #e5895f;
background-repeat: no-repeat;
background-image: url('path/to/texture-orange.jpg');
}
.masked-copy {
-webkit-background-clip: text;
color: transparent !important;
}
At this point, I havenāt taken a close enough look to determine their particular
reason for using !important
on that color rule. I didnāt notice any conflicting
selectors. Also, itās not necessary for the example weāll build up. So you can
ignore it in this case.
The important (no pun intended) thing to note here is that they provided a
solid color for the text, for browsers that donāt support the -webkit-background-clip: text
ruleā¦
background-clip, and -webkit-background-clip
This is where the magic happens!
This may be a simplification, but this rule tells the container to hide all parts of the background (image or color) except where the text is.
The background-clip
property is defined on MDN like:
The background-clip CSS property specifies if an elementās background, whether a <color> or an <image>, extends underneath its border.
ā¦ and when using the (experimental) text
value:
The background is painted within (clipped to) the foreground text.
Why the -webkit-
prefix?
Iām definitely not the expert, and so far have only spent a little time looking this up. From what I could tell from the compatibility charts on MDN and āCan I Useā¦ā, the version of background-clip
, particularly with the text
value, has better browser support when using the prefixed version. I could be wrong!
āCan I Useā¦ā has this in the Note section for CSS3 Background-image options:
Firefox, Chrome and Safari support the unofficial -webkit-background-clip: text (only with prefix)
As well, Iāve seen this work fine on Windows machines, in IE11 and Edge.
Building our own
The final version of this is available in this CodePen.
Hereās the step-by-step build up to the final result.
The minimum structure
You only need a few things to pull this off:
- a dark background
- a container with a background color or image
- a nice header (optional!?)
- and the paragraph that will look awesome
Hereās the HTML weāll work with (excluding the body and all that cruft):
<div class="masked-copy texture-orange big-type">
<h2 class="inline">Intelligent A12 Bionic.</h2>
<p>This is the smartest, most powerful chip in a smartphone,
with our next-generation Neural Engine. For amazing augmented reality
experiences. Incredible portraits with Depth Control. And speed and
fluidity in everything you do.</p>
</div>
Adding CSS styles
First, our dark background. Weāll just make the body
element have a black background color:
body {
background-color: black;
}
To make it look similar to Appleās design, weāll need some chunky/bold text.
.big-type {
/*
These rules were copied almost wholesale from the
Apple site CSS; I changed the font-stack to be more
generic
*/
font-size: 64px;
line-height: 1.0625; /* The height Apple used to tighten up the spacing a bit. */
font-weight: 600; /* Nice, chunky, bold! */
font-family: "Helvetica Neue","Helvetica","Arial",sans-serif;
}
Now, rules to set the background image on our container, and set a solid color font that some older browsers will show, instead of the clipped background:
.texture-orange {
/* Set the text color to a solid, in case our super cool effects don't work. */
color: #e5895f;
/*
This is from the Apple styles.
A word of caution: if your background image isn't at least as wide as
your container, leave this off! Otherwise, it will hide text that
falls outside of the background image.
*/
background-repeat: no-repeat;
/* You'll provide the URL to your texture background here. */
background-image: url('/path/to/texture-orange.jpg');
}
At this point, itās probably looking something like this:
As they did, letās make that header white. And while weāre at it, notice one of my favorite touches in this design: semantically, thereās a header and a paragraph. Visually, they pull the two together by changing the display property on the header and the paragraph elements from the default block
to inline
.
That change has to be applied to both elements.
.masked-copy p {
display: inline;
}
.masked-copy h2 {
color: white;
display: inline;
/* Get the font sizes and other features from those set on the parent */
font: inherit;
}
Without the background-clip and color: transparent
rules, you should see something like this:
Then, adding color: transparent
, youāll see the paragraph disappearā¦
.masked-copy {
color: transparent !important;
}
Finally, the star of the show, applying the -webkit-background-clip: text
rule will cause the background image of the selected element to be āclippedā, except for where the text exists, allowing the background-color of the body
element (or another container) to show through:
.masked-copy {
-webkit-background-clip: text;
color: transparent !important;
}
Final code
All available in this CodePen, and here for posterity:
HTML
<div class="masked-copy texture-orange big-type">
<h2>Intelligent A12 Bionic.</h2>
<p>This is the smartest, most powerful chip in a smartphone, with our next-generation Neural Engine. For amazing augmented reality experiences. Incredible portraits with Depth Control. And speed and fluidity in everything you do.</p>
</div>
CSS
body {
background-color: black;
width: 900px;
}
.big-type {
/*
These rules were copied almost verbatim from the
Apple site CSS; I changed the font-stack to be more
generic
*/
font-size: 64px;
line-height: 1.0625; /* The height Apple used to tighten up the spacing a bit. */
font-weight: 600; /* Nice, chunky, bold! */
font-family: "Helvetica Neue","Helvetica","Arial",sans-serif;
}
.texture-orange {
/* Set the text color to a solid, in case our super cool effects don't work. */
color: #e5895f;
/*
The Apple stylesheet supplies a `background-repeat: no-repeat;` rule here.
You can do the same, as long as your background image
is at least as large as your text will be. Otherwise,
text that falls outside of the background image will be
invisible, and that's (usually) not what you want!
*/
/* background-repeat: no-repeat; */
/* You'll provide the URL to your texture background here. */
background-image: url('/path/to/texture-orange.jpg');
}
.masked-copy p {
display: inline;
}
.masked-copy h2 {
color: white;
display: inline;
/* Get the font sizes and other features from those set on the parent: */
font: inherit;
}
.masked-copy {
/* This is it! */
-webkit-background-clip: text;
color: transparent !important;
}
Final thoughts
Using a regular background image isnāt the only way to go! You
can just as easily do it in pure CSS by providing a gradient background. That would also eliminate any accidental text clipping oddities that might occur if you use no-repeat
backgrounds, etc.
See the links in the references below for more examples using background-clip
.
Also, donāt be afraid of the -webkit
prefix! This property has fantastic browser support, as mentioned before.
And remember that āfallbackā text color?
Hereās a shot of good olā IE 9, on Windows Vistaā¦
You can see the font in the āfallbackā color, and no background. Not bad!
References
I am so late to this party! This effect has been really well covered in a few other places, at least as early as 2013!
- Divya Manian covered the effect, and alternatives, in fewer and better words than I could, back in 2013!
- Of course, CSS Tricks has āHow To Do Knockout Textā
- MDN CSS docs on
color
, becausetransparent
is apparently an option. - Can I useā¦ CSS3 Background-image options. Browser support is pretty great!
- The CodePen I made to accompany this post.