150

Can I stretch text in CSS? I don't want the font to be bigger, because that makes it appear bolder than smaller text beside it. I just want to stretch the text vertically so it's kind of deformed. This would be in one div, and then the normal text beside it would be in another div. How can I do this?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Matthew905
  • 1,571
  • 3
  • 12
  • 7

6 Answers6

264

Yes, you can actually with CSS 2D Transforms. This is supported in almost all modern browsers, including IE9+. Here's an example.

Actual HTML/CSS Stretch Example

span.stretch {
    display:inline-block;
    -webkit-transform:scale(2,1); /* Safari and Chrome */
    -moz-transform:scale(2,1); /* Firefox */
    -ms-transform:scale(2,1); /* IE 9 */
    -o-transform:scale(2,1); /* Opera */
    transform:scale(2,1); /* W3C */
}
<p>I feel like <span class="stretch">stretching</span>.</p>

TIP: You may need to add margin to your stretched text to prevent text collisions.

asmeurer
  • 86,894
  • 26
  • 169
  • 240
Timothy Perez
  • 20,154
  • 8
  • 51
  • 39
  • How can this be applied to a submit button text? (the text, not the button) – dstonek Sep 11 '12 at 13:12
  • 1
    Just change the

    tags to ... The style will affect anything in span tags with a "stretch" class.
    – Timothy Perez Sep 17 '12 at 17:53
  • 7
    You might also want to add transform-origin as be default it'll scale from the centre. transform-origin: left center; https://developer.mozilla.org/en-US/docs/CSS/transform-origin – Ric Jan 10 '13 at 09:29
  • 1
    You have the axes backwards. The asker wants to stretch the text *vertically*, not horizontally. – BoltClock Sep 27 '16 at 06:44
  • This is great, but unfortunately it doesn’t work with a pseudoselector such as ::first-letter. – Simone Dec 14 '18 at 17:07
  • This answer doesn't work like shown in the picture. It overlaps with other text. When using `transform-origin: left;` it still overlaps but then with text on the right side https://jsfiddle.net/ft0cqg3a/2/ – Flip Apr 10 '20 at 17:36
18

I'll answer for horizontal stretching of text, since the vertical is the easy part - just use "transform: scaleY()"

.stretched-text {
  letter-spacing: 2px;
  display: inline-block;
  font-size: 32px;
  transform: scaleY(0.5);
  transform-origin: 0 0;
  margin-bottom: -50%;
}
span {
  font-size: 16px;
  vertical-align: top;
}
<span class="stretched-text">this is some stretched text</span>
<span>and this is some random<br />triple line <br />not stretched text</span>

letter-spacing just adds space between letters, stretches nothing, but it's kinda relative

inline-block because inline elements are too restrictive and the code below wouldn't work otherwise

Now the combination that makes the difference

font-size to get to the size we want - that way the text will really be of the length it's supposed to be and the text before and after it will appear next to it (scaleX is just for show, the browser still sees the element at its original size when positioning other elements).

scaleY to reduce the height of the text, so that it's the same as the text beside it.

transform-origin to make the text scale from the top of the line.

margin-bottom set to a negative value, so that the next line will not be far below - preferably percentage, so that we won't change the line-height property. vertical-align set to top, to prevent the text before or after from floating to other heights (since the stretched text has a real size of 32px)

-- The simple span element has a font-size, only as a reference.

The question asked for a way to prevent the boldness of the text caused by the stretch and I still haven't given one, BUT the font-weight property has more values than just normal and bold.

I know, you just can't see that, but if you search for the appropriate fonts, you can use the more values.

Community
  • 1
  • 1
Dimitris K
  • 522
  • 5
  • 12
6

CSS font-stretch is now supported in all major browsers (except iOS Safari and Opera Mini). It is not easy to find a common font-family that supports expanding fonts, but it is easy to find fonts that support condensing, for example:

font-stretch: condensed;
font-family: sans-serif, "Helvetica Neue", "Lucida Grande", Arial;
SemanticZen
  • 1,141
  • 14
  • 21
6

Always coming back to this page when a designer stretches a font on me. The accepted solution works great, but I frequently run into issues with margins.

Would recommend using the transform on the height instead of the width if you're running into issues, was a life safer for me in my current project.

.font-stretch {
    display: inline-block;
    -webkit-transform: scale(1,.9);
    -moz-transform: scale(1,.9);
    -ms-transform: scale(1,.9);
    -o-transform: scale(1,.9);
    transform: scale(1,.9);
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
Ray Perry
  • 73
  • 2
  • 4
0

The only way I can think of for short texts like "MENU" is to put every single letter in a span and justify them in a container afterwards. Like this:

<div class="menu-burger">
  <span></span>
  <span></span>
  <span></span>
  <div>
    <span>M</span>
    <span>E</span>
    <span>N</span>
    <span>U</span>
  </div>
</div>

And then the CSS:

.menu-burger {
  width: 50px;
  height: 50px;
  padding: 5px;
}

...

.menu-burger > div {
  display: flex;
  justify-content: space-between;
}
Deividas Šimas
  • 184
  • 1
  • 8
0

Technically, no. But what you can do is use a font size that is as tall as you would like the stretched font to be, and then condense it horizontally with font-stretch.

Peter Kazazes
  • 3,600
  • 7
  • 31
  • 60
  • 2
    Note: This property has no effect if the selected font does not offer condensed or expanded faces! Please check this: https://www.w3schools.com/cssref/css3_pr_font-stretch.asp – QMaster Sep 04 '20 at 20:55