So I have some text which I make upright
and I want to have a different background
behind each letter.
For my actual use case, the list of backgrounds is randomly generated by a function that gets fed the number of letters.
Now the question is... how much vertical space does a letter occupy? I'm using a monospaced font here and I've set the line-height
to 1
(this is a value I can pick, so I picked 1
thinking this would simplify things).
Here's a mock Sass version of the code:
$c: #448aff, #1565c0, #009688, #8bc34a, #ffc107, #ff9800, #f44336, #ad1457;
$n: length($c);
$m: .5*$n;
$l: ();
@for $i from 0 to $m {
$l: $l,
conic-gradient(from random(360)*1deg
at random(100)*1% random(100)*1%,
nth($c, $i + 1), nth($c, $i + $m + 1),
nth($c, $i + 1))
0 $i*1em
}
div {
box-shadow: 0 0 0 6px;
background: $l;
background-repeat: no-repeat;
background-size: 100% 1em;
font: 900 clamp(1em, 18vmin, 18em)/ 1 monospace;
writing-mode: vertical-lr;
text-orientation: upright;
text-transform: uppercase
}
So with a line-height
of 1
, I would think a letter occupies 1lh
or 1em
... but that's not enough!
div {
box-shadow: 0 0 0 6px;
background:
conic-gradient(from 37deg at 54% 48%, #448aff, #ffc107, #448aff),
conic-gradient(from 264deg at 8% 31%, #1565c0, #ff9800, #1565c0) 0 1em,
conic-gradient(from -61deg at 92% 2%, #009688, #f44336, #009688) 0 2em,
conic-gradient(from -5deg at 41% 95%, #8bc34a, #ad1457, #8bc34a) 0 3em;
background-repeat: no-repeat;
background-size: 100% 1em;
font: 900 clamp(1em, 18vmin, 18em)/1 monospace;
writing-mode: vertical-lr;
text-orientation: upright;
text-transform: uppercase
}
<div>play</div>
What am I missing? How much vertical space does a letter occupy in this scenario? How do I size and position my gradients so that I have one behind each letter?
Splitting the text into letters, each wrapped in an element with its own background
is absolutely NOT an option here. Not interested in that.
Playing with line-height
won't work because it will adjust the horizontal space and not the vertical one
div {
box-shadow: 0 0 0 6px;
font: 900 clamp(1em, 18vmin, 18em)/4 monospace;
writing-mode: vertical-lr;
text-orientation: upright;
text-transform: uppercase
}
<div>play</div>
So I think you are left with the default behavior of 1.2em
but not sure if you can rely on it since it depends on the font and the browser implementation
Depends on the user agent. Desktop browsers (including Firefox) use a default value of roughly 1.2, depending on the element's font-family. ref
If you combine it with the use of percentage on background-position
, you will have only one value to "guess" so if you know the font-family it can work.
div {
box-shadow: 0 0 0 6px;
background:
conic-gradient(from 37deg at 54% 48%, #448aff, #ffc107, #448aff) 0 calc(0*100%/3),
conic-gradient(from 264deg at 8% 31%, #1565c0, #ff9800, #1565c0) 0 calc(1*100%/3),
conic-gradient(from -61deg at 92% 2%, #009688, #f44336, #009688) 0 calc(2*100%/3),
conic-gradient(from -5deg at 41% 95%, #8bc34a, #ad1457, #8bc34a) 0 calc(3*100%/3);
background-repeat: no-repeat;
background-size: 100% 1.2em; /* you will have to adjust this */
font: 900 clamp(1em, 18vmin, 18em)/1 monospace;
writing-mode: vertical-lr;
text-orientation: upright;
text-transform: uppercase
}
<div>play</div>
Edit: as per @Ana comment, we can also use percentage for the size and no more depend on font metrics
div {
box-shadow: 0 0 0 6px;
background:
conic-gradient(from 37deg at 54% 48%, #448aff, #ffc107, #448aff) 0 calc(0*100%/3),
conic-gradient(from 264deg at 8% 31%, #1565c0, #ff9800, #1565c0) 0 calc(1*100%/3),
conic-gradient(from -61deg at 92% 2%, #009688, #f44336, #009688) 0 calc(2*100%/3),
conic-gradient(from -5deg at 41% 95%, #8bc34a, #ad1457, #8bc34a) 0 calc(3*100%/3);
background-repeat: no-repeat;
background-size: 100% calc(100%/4);
font: 900 clamp(1em, 18vmin, 18em)/1 monospace;
writing-mode: vertical-lr;
text-orientation: upright;
text-transform: uppercase
}
<div>play</div>
This said, you can create the same thing differently. A bit hacky but it can be a good workaround:
div {
width: 1ch; /* limit the width to one character */
word-break: break-all; /* allow the word to break */
/* you can use 1lh everywhere */
background:
conic-gradient(from 37deg at 54% 48%, #448aff, #ffc107, #448aff),
conic-gradient(from 264deg at 8% 31%, #1565c0, #ff9800, #1565c0) 0 1lh,
conic-gradient(from -61deg at 92% 2%, #009688, #f44336, #009688) 0 2lh,
conic-gradient(from -5deg at 41% 95%, #8bc34a, #ad1457, #8bc34a) 0 3lh;
background-repeat: no-repeat;
background-size: 100% 1lh;
/* you can use percentage with background-position as well
background-position:
0 calc(0*100%/3),
0 calc(1*100%/3),
0 calc(2*100%/3),
0 calc(3*100%/3); */
font: 900 clamp(1em, 18vmin, 18em)/1 monospace;
display: inline-block;
margin: 5px;
padding-inline: .2em;
box-shadow: 0 0 0 6px;
vertical-align: top;
text-transform: uppercase
}
<div>play</div>
<div style="line-height: 2">play</div>
<div style="line-height: .9">play</div>