Is there any way to bend a text with CSS or leave the text bent in a line?

5

Is there any way to put text in this format without having to use an image?

Or I would like to make some kind of crooked text, but I could not do it. The idea would be to do something close to that image, but only with code to facilitate quick editing etc ...

Doesanyoneknowifthereisanywaytodothiseffectinthetext?

I'vecomethisfar,butIhavenoideahowtomakethetextlinethecurveorsomethingclosetoit...

.box {
    background-color: peachpuff;
    text-align: center;
    width: 200px;
    height: 100px;
    position: relative;
    overflow: hidden;
}
.box::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    border-radius: 50%;
    border: 1px solid;
    width: 200px;
    height: 100px;
    box-sizing: border-box;
}
.box span {
    display: inline-block;
    font-weight: bold;
    font-size: 24px;
    line-height: 100px;
}
<div class="box">
    <span>
        NEW YORK
    </span>
</div>
    
asked by anonymous 21.09.2018 / 19:30

1 answer

5

There are several options to do the desired, but here I will present two solutions (the answer would get very large with all of them).

Some of the options are:

  • Canva
  • "pure" CSS
  • CSS with JavaScript (Example 1)
  • SASS
  • SVG and path (Example 2)

Could do with SASS, but the OS is not supported on the snippet. So let's do with a bit of JavaScript (which will apply CSS to elements).

  

Note: Before I understand what's happening with the code, I'll   that this is not the best solution, because there are   libraries, with Arctext.js that would do this in a simple way   for us, I'm just responding to the question request.

The biggest problem with this method is that if you change a word in div it would have to go back and tinker with JavaScript and CSS again. But anyway, see example 1:

let deg = 6;
for (let i = 1; i <= 20; i++) {
  let div = document.querySelector(".container div:nth-child(" + i + ")");
  div.style.transform = 'rotate(' + deg + 'deg)';
  deg = deg + 6;
}
.container {
  margin: auto;
  position: relative;
  transform-origin: bottom left;
  transform: rotate(-61deg);
  height: 200px;
  width: 200px;
}

.container div {
  display: inline-block;
  font: 900 1.5em Monaco, Monospace;
  color: #000000;
  height: 200px;
  width: 15px;
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: bottom center;
  text-align: center;
}
<div class="container">
  <div>c</div>
  <div>a</div>
  <div>r</div>
  <div>a</div>
  <div>m</div>
  <div>b</div>
  <div>a</div>
  <div> </div>
  <div>o</div>
  <div> </div>
  <div>c</div>
  <div>a</div>
  <div>r</div>
  <div>a</div>
  <div> </div>
  <div>é</div>
  <div> </div>
  <div>t</div>
  <div>o</div>
  <div>p</div>
</div>

If you look closely at my example you will realize that it is not 100% aligned, so I would have to have increased the precision of the rotation in div container (the reason: I have proof today).

Basically in this example we have a% container that will be rotated in any direction, and that would allow the arc to go anywhere (stay right, left, top ...).

Otherwise, we only need to apply the div property of CSS to each child element, so they can also rotate together. Also, always keep a pattern to rotate, in this example I did increasing 6 to every interaction of transform: rotate .

  

Note 2: Example 1 (with JavaScript) would make 100% with CSS, but the code would be extremely large since we would need to apply to each element that property by increasing 6 in rotation.

Understood the first example we can go to the second done with SVG and for . I think the best solution because it allows you to do several things with the text, not just an arc.

No more text and we will understand in stages:

Imagine this SVG with a path in the style of an arc, in it we will "write on top".

<svg viewBox="0 0 500 500">
  <path id="curve" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
</svg>

Now let's add text that will follow this path (path, logical not?).

<svg viewBox="0 0 500 500">
  <path id="curve" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
  <text width="500">
    <textPath xlink:href="#curve">
      Olha a curva vindo
    </textPath>
  </text>
</svg>

And best of all, just change the text and it still keeps going the way (so it's better, we do not need to refactor CSS and JavaScript).

But there is a problem, we do not want the curve to appear. Then let's change. To do this, just put the path property inside the path .

<svg viewBox="0 0 500 500">
  <path id="curve" fill="transparent" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
  <text width="500">
    <textPath xlink:href="#curve">
      Olha a curva vindo
    </textPath>
  </text>
</svg>

Now we have everything ready, just stylize with CSS and change the SVG a bit.

body {
  font-family: 'Luckiest Guy', cursive;
  font-size: 50px;
}

path {
  fill: transparent;
}

text {
  fill: #FF9800;
}
<svg viewBox="0 0 1000 1000">
    <path id="curve" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
    <text width="300">
      <textPath xlink:href="#curve">
        Olha a curva vindo
      </textPath>
    </text>
</svg>

References:

Curved Text

Path

    
21.09.2018 / 20:39