Textos en trayectos

La etiqueta <textPath>

Bootcamp ManzDev

¡Bootcamp gratuito!

¡Comiénzalo pulsando aquí!


En algunas ocasiones, es posible que nos interese definir un texto, pero no tenerlo en una disposición normal, sino que queremos que siga una forma específica o un trayecto personalizado. Para ello, tenemos a nuestra disposición la etiqueta <textPath>, que permite indicar un texto en un trayecto personalizado.

El elemento <textPath>

La etiqueta <textPath> se indica en el interior de una etiqueta <text> para modificar el texto y colocarlo en un trayecto personalizado mediante una forma específica o un trayecto <path>, que generalmente se colocará en el apartado de definiciones <defs>.

Con ello, podemos decirle a nuestro SVG, que el texto contenido en el elemento <textPath> debe seguir una forma concreta, generalmente indicada en el atributo href, mediante un id.

Estos son los atributos disponibles en el elemento <textPath>:

AtributoValor por defectoDescripción
hrefnoneReferencia a un trayecto previamente definido.
textLength0Distancia entre carácteres. Más información.
lengthAdjustspacingAjuste de carácteres. Más información.
spacingexactIndica como gestionar el espacio entre glifos. Valores: auto o exact.
startOffset0Espacio en el que comienza el desplazamiento.
🧪 methodalignRenderiza el texto estirando o alineando. Valores: stretch o align.
🧪 pathnoneUsa el valor del atributo d de un de SVG, en lugar de una figura indicada en href.
🧪 sideleftDefine en que lado va a definir el texto. Valores: left o right.

Veamos un ejemplo para entenderlo mejor.

Referencia a un trayecto

Antes de empezar, comencemos con un fragmento simple, donde solo tenemos un bloque de texto normal. Vamos a extraer algunos de sus atributos y externalizarlo en CSS, para enfocarnos en los puntos clave.

<svg viewBox="0 0 250 100" height="300">
  <text x="10" y="50" font-family="Jost" font-weight="800" font-size="8">
    ¿Experiencia única? Código Konami en Manz.dev
  </text>
</svg>

Ahora, vamos a crear un arco utilizando un <path>. Observa en la siguiente demo como se muestra el arco. A continuación vamos a meter este <path> en un bloque de definiciones <defs> para que no se muestre y utilizarlo posteriormente:

<svg viewBox="0 0 250 100" height="300">
  <path id="arc" d="M10,75 A20 10 0 0 1 240,75" stroke="black" fill="none">
</svg>

Una vez hecho esto, en el interior del elemento <text> indicamos un <textPath> al que hacemos referencia al id de nuestro arco. Con esto le estaremos diciendo que utilice el trayecto <path> como base para el texto, por lo que este se adaptará a su forma. Además, mediante los atributos textLength y dx que vimos en artículos anterior, ajustamos donde aparece el texto:

<svg viewBox="0 0 250 100" height="300">
  <defs>
    <path id="arc" d="M10,75 A20 10 0 0 1 240,75">
  </defs>

  <text x="10" y="50" dx="3" textLength="250">
    <textPath href="#arc">
      ¿Experiencia única? Código Konami en Manz.dev
    </textPath>
  </text>
</svg>

<p>Valor de <code>textLength</code>:
  <input class="tl" type="range" min="0" max="500" value="250">
  <output>250</output>
</p>
<p>Valor de <code>dx</code>:
  <input class="dx" type="range" min="0" max="50" value="3">
  <output>3</output>
</p>
const text = document.querySelector("text");
const tl = document.querySelector("input.tl");
const dx = document.querySelector("input.dx");

tl.addEventListener("input", () => {
  tl.nextElementSibling.value = tl.value;
  text.setAttribute("textLength", tl.value);
});
dx.addEventListener("input", () => {
  dx.nextElementSibling.value = dx.value;
  text.setAttribute("dx", dx.value);
});
text {
  font-family: "Jost";
  font-weight: 800;
  font-size: 8px;
  fill: indigo;
}

Observa que los atributos dx y textLength están ubicados en el elemento <text>.

Desplazamiento y espaciado

Mediante el atributo startOffset puedes definir en que momento del trayecto comienza a mostrarse el texto, ajustando su desplazamiento inicial. Funciona de una forma muy similar al atributo dx visto hasta ahora.

<svg viewBox="0 0 250 100" height="300">
  <defs>
    <path id="arc" d="M10,75 A20 10 0 0 1 240,75">
  </defs>

  <text x="10" y="50" textLength="250">
    <textPath href="#arc" spacing="auto" startOffset="20">
      ¿Experiencia única? Código Konami en Manz.dev
    </textPath>
  </text>
</svg>
text {
  font-family: "Jost";
  font-weight: 800;
  font-size: 8px;
  fill: indigo;
}

Por otro lado, el atributo spacing permite indicar entre los valores auto y exact (este último por defecto), donde indicas si el trayecto debería ser renderizado según un algoritmo del navegador o exactamente como está definido en los atributos del trayecto de base.

Cuidado con los atributos path, method y side, puesto que en la actualidad no tienen buen soporte en navegadores.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev