
Esta es una de esas cosas complicadas de CSS que veo surgir cada pocos meses. Supongo que qué mejor lugar para abordarlo que CSS-Tricks, ¿eh?
La situación involucra texto en línea irregular a la derecha. Como cuando un párrafo de texto pasa a la siguiente línea cuando la siguiente palabra no encaja (es decir, la mayoría del texto en Internet). Desea agregar un fondo detrás de ese texto que:
- Sigue el borde derecho irregular
- Está acolchado a lo largo del borde izquierdo y derecho de cada línea
Lo que no puede hacer es simplemente aplicar un fondo y un relleno a, digamos, el <p>
elemento. Los párrafos están a nivel de bloque, por lo que el fondo será simplemente un rectángulo y no seguirá la corrección irregular.
Tampoco puede simplemente aplicar el fondo y el relleno a un <span>
o un elemento en línea. El relleno izquierdo y derecho solo se aplicará a la primera y última línea. En cada una de las líneas medias, el fondo se alineará inmediatamente al lado del texto.
Describir esto es un poco inútil. Este es el problema visualmente:
Lo que queremos es que cada línea se rellene como el comienzo de esa primera línea y el final de esa última línea. No queremos recurrir a nada asqueroso como envolver cada línea en su propio tramo (donde las líneas se rompen es demasiado impredecible). Y no existe tal cosa como: nth-line desafortunadamente.
¡Sin embargo, hay algunas soluciones!
Método del pseudoelemento / espacio en blanco de Harry Robert
El gran truco aquí es usar white-space: pre-wrap;
Eso nos da el acolchado en las líneas irregulares a la derecha. Luego, para obtener el relleno a lo largo de la izquierda, se agrega un pseudo elemento a lo largo del borde izquierdo. Aquí está el original y luego mi bifurcación para mostrar los elementos en funcionamiento:
Vea el Pen BtpGo de Chris Coyier (@chriscoyier) en CodePen
Desafortunadamente, Firefox no cava en la forma en que se posiciona el pseudo elemento en esa técnica. Probablemente se pueda arreglar, pero podría haber una mejor manera …
Método de caja de sombra de Fabien Doiron
Resulta que puede usar la sombra de cuadro de propagación cero en un elemento en línea solo en el eje x para rellenar cada línea. Esencialmente:
.padded-multi-line {
display: inline;
background: orange;
box-shadow: 10px 0 0 orange, -10px 0 0 orange;
}
Aquí está el original y luego mi bifurcación para mostrar cómo funciona:
Vea el texto resaltado de envoltura de lápiz de Chris Coyier (@chriscoyier) en CodePen
Nota: tuve que actualizar este código cuando se cayó Firefox 32. Firefox requiere box-decoration-break: clone;
porque el valor predeterminado es box-decoration-break: split;
.
Método JavaScript / Unicode de Dave Rupert
Advertencia justa: Dave dice que no uses esto. Lo incluyo porque creo que es inteligente y, de alguna manera extraña, en realidad me parece menos hacker. La idea es revisar el texto de cada elemento y reemplazar los espacios con el carácter unicode u205f
, el carácter de ESPACIO MATEMÁTICO MEDIO. Esto funciona mejor con el acolchado en el borde derecho por la razón que sea. Para el borde izquierdo, solo usa un border-left
a lo largo del elemento padre a nivel de bloque.
Aquí está el original y mi tenedor desmontado:
Vea el texto resaltado de envoltura de lápiz de Chris Coyier (@chriscoyier) en CodePen
Es un poco complicado obtener la altura de la línea correcta para que el borde se alinee con el relleno, pero estoy seguro de que puede resolverlo. Probablemente haya incluso algunas matemáticas sofisticadas para asegurarse de que sea correcto.
Si JavaScript funciona para usted, también hay un complemento de jQuery wraplines en el que puede aplicar el relleno a cada línea individual. Manifestación.
Método del triple elemento de Matthew Pennell
Resulta que puedes hacer esto casi sin CSS o JS sofisticados, pero usando tres elementos. Necesita un padre a nivel de bloque para un borde izquierdo. Luego, un elemento en línea para aplicar el relleno y el fondo. Luego, otro elemento en línea para empujar el texto hacia la izquierda para obtener el relleno en los bordes derechos.
<div class="padded-multiline">
<h1>
<strong>
How do I add padding to subsequent lines of an inline text element?
</strong>
</h1>
</div>
.padded-multiline {
line-height: 1.3;
padding: 2px 0;
border-left: 20px solid #c0c;
width: 400px;
margin: 20px auto;
}
.padded-multiline h1 {
background-color: #c0c;
padding: 4px 0;
color: #fff;
display: inline;
margin: 0;
}
.padded-multiline h1 strong {
position: relative;
left: -10px;
}
El original está en este hilo y mi demostración:
Vea el Pen pvBFg de Chris Coyier (@chriscoyier) en CodePen
Si está viendo esto en Firefox, puede haber algunos problemas de altura de línea. Básicamente, no tengo idea de por qué es un poco frustrante, particularmente en situaciones como esta.
Método de caja-decoración-ruptura de Adam Campbell
Durante una discusión que surgió sobre esto, Adam señaló que hay una nueva propiedad CSS que es (según tengo entendido) específicamente para esto. Esto elimina la necesidad de tres elementos. Técnicamente, solo necesita uno, el elemento en línea, pero es probable que haga esto en un encabezado, por lo que probablemente terminará con un padre de bloque de todos modos, que es mejor para el espaciado.
Aquí está la demostración original y mi versión reducida:
Vea el Pen hIvFe de Chris Coyier (@chriscoyier) en CodePen
Esto funciona en Chrome y Safari, pero no Firefox ahora funciona en Firefox 32+, en mis pruebas rápidas. Chrome y Safari requieren que sea -webkit-box-decoration-break
.
Estado de la técnica
Las personas a las que atribuí en este artículo fueron las personas a las que vi por primera vez la técnica. Pero no necesariamente representan la primera persona absoluta en pensar en ello ™. En los comentarios a continuación, surgieron algunas publicaciones de blogs más antiguas que abordaron este mismo problema. Uno de Sergey Chikuyonok (ruso) y otro de HTeuMeuLeu (francés).