html - texto - ¿Por qué la altura de línea sin unidad se comporta de manera diferente de un porcentaje o em en este ejemplo?
line-width css (4)
EDITAR
Creé un códec para mostrar el líder creado con los diferentes valores . Espero que esto brinde una mejor explicación.
Puedo responder a sus preguntas, pero solo teorizo (en este punto) sobre el espaciado adicional que está viendo (y proporcione una solución potencial).
Tus preguntas
¿Existe una diferencia semántica intencional en CSS entre 1.5 y 150% que explique la diferencia en el comportamiento?
Hay, de hecho!
El factor numérico (1.5 en este caso) se hereda y se usa para calcular la altura de línea de cada descendiente, en relación con su tamaño de fuente.
El factor de porcentaje (150%) se usa para calcular una altura de línea basada en el tamaño de fuente del elemento principal. El valor resultante precalculado es heredado por sus descendientes.
O, si se supone que son iguales, ¿cuál se implementa incorrectamente?
Ellos son intencionalmente diferentes. (Ver la especificación W3C )
En términos prácticos, ¿hay una desventaja de cambiar a decimales sin procesar como 1.5 para la altura de línea?
Por lo general, es una ventaja usar los valores decimales, porque la altura de línea heredada se adaptará mejor. Pero hay casos en que no se ajusta a sus necesidades.
Problema de espacio extra
Me di cuenta de que si configuro vertical-align
en su texto pequeño a la middle
o bottom
, el problema no ocurre. Pero esta no es una muy buena solución.
Supongo que esto tiene que ver con el hecho de que el texto más pequeño usa la altura de línea calculada heredada, combinada con su ubicación en la línea. Como el texto es más pequeño y está más abajo, pero tiene la misma altura de línea que la línea circundante, la mitad inferior de la cuerda avanzará más hacia abajo, y la mitad superior no alcanzará tan alto como el texto circundante.
Entonces, digamos que el tamaño de fuente base es 16 px, y la altura de línea es 24 px. La ventaja será 4px en cada lado ((24-16) / 2). Cuando el tamaño de fuente es 50%, es 8px, pero la altura de línea permanece 24px. Entonces el líder se convierte en 8px en cualquier lado ((24-8) / 2).
Las líneas de base del texto se alinearán, por lo que, si todo sigue igual, es de esperar que el texto más pequeño se extienda 4px por debajo del texto normal. Pero dado que el texto (y su área de contenido correspondiente) es más pequeña, la mitad inferior de la partida comienza más atrás, por lo que solo ve un pixel o dos cambios, y solo en ciertos porcentajes (obteniendo más a medida que se vuelve más pequeño, pruébelo) fuera)
Realmente debería usar imágenes para esto, pero no puedo en este momento ... tal vez pueda agregar algo más tarde.
No sé si eso ayuda en absoluto, pero definitivamente entiendo mejor cómo funciona la line-height
en general ahora.
Referencias: http://www.w3.org/wiki/CSS/Properties/line-height http://meyerweb.com/eric/thoughts/2006/02/08/unitless-line-heights/ http://www.maxdesign.com.au/articles/css-line-height/
Estoy perplejo por el comportamiento del siguiente CSS, también ilustrado en este violín .
<style type="text/css">
p {
font-size: 14px;
}
.percentage {
line-height: 150%;
}
.em-and-a-half {
line-height: 1.5em;
}
.decimal {
line-height: 1.5;
}
.smaller {
font-size:50%;
}
.caption {
font-weight: bolder;
font-size: 80%;
}
</style>
<p class="caption">default line spacing</p>
<p>This tutorial provides a brief introduction to the
programming <span class="">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
<p>This tutorial provides a brief introduction to the
programming <span class="smaller">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
<p class="caption">line-height: 150%</p>
<p class="percentage">This tutorial provides a brief introduction to the
programming <span class="">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
<p class="percentage">This tutorial provides a brief introduction to the
programming <span class="smaller">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
<p class="caption">line-height: 1.5em</p>
<p class="em-and-a-half">This tutorial provides a brief introduction to the
programming <span class="">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
<p class="em-and-a-half">This tutorial provides a brief introduction to the
programming <span class="smaller">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
<p class="caption">line-height: 1.5</p>
<p class="decimal">This tutorial provides a brief introduction to the
programming <span class="">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
<p class="decimal">This tutorial provides a brief introduction to the
programming <span class="smaller">language</span> by using one of its picture-drawing
libraries. This tutorial provides a brief introduction to the programming language. This tutorial provides a brief introduction to the programming language.</p>
Los dos primeros párrafos tienen un espaciado de línea predeterminado. El segundo párrafo tiene una palabra que es más pequeña. Pero no afecta el espaciado de línea en ese párrafo. No es que debería, pero entonces -
Los siguientes dos párrafos tienen line-height: 150%
. De nuevo, el segundo párrafo tiene una palabra más pequeña. Pero esta vez, por razones poco claras, la fuente más pequeña crea espacio extra entre las dos primeras líneas (al menos en Safari, Chrome, Firefox y Explorer). Este es el problema original en mi CSS que estaba tratando de corregir. (Supongo que tiene algo que ver con que el navegador reduzca la palabra y luego la desplace verticalmente para realinear las líneas de base).
Los siguientes dos párrafos tienen line-height: 1.5em
. Mi entendimiento es que 1.5em
es igual al 150%
. Y, de hecho, el comportamiento es el mismo: espacio extra entre las dos primeras líneas del segundo párrafo.
Pero aquí es donde se pone raro : los siguientes dos párrafos tienen line-height: 1.5
- no se especifica unidad. Esta vez, el problema del espacio extra desaparece.
En resumen, CSS parece proporcionar resultados de espaciado de línea consistentes cuando las alturas de línea del padre y el hijo son diferentes (a través de la herencia del valor sin unidad) pero los resultados son inconsistentes cuando las alturas de línea del padre y el hijo son las mismas.
Por lo tanto, mis preguntas:
Sé que hay una diferencia semántica intencional en las especificaciones de CSS entre
1.5
y150%
o su sinónimo,1.5em
. (A saber: un valor sin unidades se pasa al elemento secundario y su altura de línea se calcula utilizando el tamaño de fuente del niño, mientras que un porcentaje o valor de em provocará que se calcule una altura de línea para el elemento primario y luego ese valor calculado se transfiere a el niño.) Pero, ¿cómo explica esto la diferencia de comportamiento que se ve aquí? ¿De dónde viene el espacio extra? Si es una consecuencia de alguna regla de posicionamiento de CSS, ¿cuál es esa regla?O, si todos estos ejemplos se procesan de la misma manera, ¿cuál se implementa de forma incorrecta? (Nota sobre Q2: El hecho de que la peculiaridad de renderización ocurra de la misma manera en diferentes navegadores sugiere fuertemente que ninguno de ellos se implementa incorrectamente, lo que lo llevará de vuelta a la pregunta (1)).
En términos prácticos, ¿hay una desventaja de cambiar a mediciones sin unidades como(Respuesta: no)1.5
paraline-height
?
Basándome en las pistas de las respuestas propuestas, creo que el comportamiento de representación que se ve en estos ejemplos es contrario a la intuición, pero es correcto y está ordenado por la interacción de varias reglas en la especificación y el modelo general de caja de CSS .
CSS calcula la L inicial que se necesita para una caja por la fórmula
line-height
= L + AD, donde AD es "la distancia desde la parte superior a la inferior" de la fuente. Luego, "la mitad de la ventaja se agrega por encima de A y la otra mitad por debajo de D." Así que el texto que tienefont-size:16px
yline-height:24px
tendrá 4px de anticipación arriba y abajo.font-size:8px
textofont-size:8px
yline-height:24px
tendrá 8px de anticipación arriba y abajo.Sin embargo, de forma predeterminada, "el agente de usuario debe alinear los glifos ... por sus líneas de referencia relevantes". . Esto comienza a explicar lo que está sucediendo aquí. Cuando
line-height
se especifica por porcentaje o em, el niño hereda un valor calculado (aquí, el lapsosmaller
). Es decir, el tramosmaller
obtiene la mismaline-height
que el bloque primario. Pero debido a la fórmula L + AD, el texto de ese tramo tiene más adelanto en la parte superior e inferior, y por lo tanto, la línea de base se encuentra más arriba en su cuadro. El navegador empuja hacia abajo el tramosmaller
verticalmente para que coincida con las líneas de base.Pero luego el navegador tiene un nuevo problema: cómo lidiar con el espaciado de línea en el bloque adjunto, que ha sido interrumpido por este proceso de ajuste de línea de base. La especificación también resuelve esto: la
line-height
deline-height
de un elemento de nivel de bloque "especifica la altura mínima de los cuadros de línea dentro del elemento" . Es decir, CSS no promete que obtendrás tuline-height
exacta, solo que obtendrás al menos esa cantidad. Por lo tanto, el navegador empuja las líneas separadas en el bloque delimitador para que la caja infantil realineada encaje.
La razón por la que esto es contradictorio es que es lo opuesto a cómo funcionan la mayoría de los procesadores de texto y los programas de diseño de página. En estos programas, un tramo más pequeño de texto dentro de un párrafo se alinea con su línea de base (como CSS), pero la altura de línea se impone como una distancia entre líneas de base, no como un cuadro que rodea el texto más pequeño. Pero eso no es un error: CSS está diseñado en torno a un modelo de caja . Entonces, al final, podríamos decir que este comportamiento de espaciado es una consecuencia de ese modelo.
Eso todavía nos deja explicar el comportamiento en el ejemplo con la altura de línea sin unidades:
En primer lugar, tenga en cuenta que cuando no se especifica
line-height
, el navegador aplicará una altura de línea sin unidades de forma predeterminada. Esto es requerido por la especificación : el valor inicial deline-height
deline-height
esnormal
, que se define para tener "el mismo significado que <número>", y la especificación recomienda un valor "entre 1.0 y 1.2". Y eso es consistente con lo que vemos en los ejemplos anteriores, donde los párrafos conline-height: 1.5
tienen el mismo comportamiento que los párrafos sin ajuste de altura de línea (es decir, implícitamente obtienenline-height: normal
)Como han señalado otros, cuando el párrafo tiene
line-height: 1.5
, la altura de línea calculada del párrafo no es heredada por el tramosmaller
. Por el contrario, el tramosmaller
calcula su propia altura de línea en función de su propio tamaño de fuente. Cuando el párrafo tieneline-height: 1.5; font-size: 14px
line-height: 1.5; font-size: 14px
, luego su altura de línea calculada es 14px * 1.5 = 21px. Y si el tramosmaller
solo tiene elfont-size: 50%
propiedadfont-size: 50%
, su tamaño de fuente es 14px * 50% = 7px, y su altura de línea es 7px * 1.5 = 10.5px (que generalmente se redondeará a un píxel entero) . Pero, en general, la cajasmaller
tiene la mitad del tamaño del texto circundante.Como antes, el navegador alineará verticalmente el tramo
smaller
con la línea de base adyacente. Pero esta vez, dado que el recuadrosmaller
es más corto que el texto circundante, esta realineación no tiene ningún efecto secundario en el bloque adjunto. Ya se ajusta, por lo que no es necesario extender las líneas del párrafo padre, como había antes.
Ambos casos representan una implementación consistente de la especificación. Es una buena noticia, porque significa que podemos predecir el comportamiento del espaciado de línea.
Eso nos lleva de vuelta al motivo original de esta pregunta. Si bien ahora entiendo que el modelo de recuadro CSS requiere este comportamiento, como tipógrafo practicante, este comportamiento rara vez es el que deseo. Lo que quiero es que las líneas dentro de un párrafo tengan un espaciado de línea constante y exacto, incluso si algunos tramos de texto dentro de ese párrafo son más pequeños.
Desafortunadamente, parece que no hay forma de aplicar directamente el espaciado de línea exacto en CSS como se puede hacer en un procesador de texto o programa de diseño de página. Nuevamente, esto se debe al modelo de caja de CSS: no utiliza un modelo de espaciado de línea entre la línea de base y la línea de base, y line-height
se especifica como una medida mínima, no máxima.
Pero podemos al menos decir que los valores de altura de línea sin unidades producen la mejor aproximación del espaciado de línea exacto en CSS. Los tipógrafos exigentes como yo deberíamos sentirnos cómodos utilizándolos, porque los valores sin unidades están respaldados por la especificación y producen resultados consistentes en todos los navegadores. No son un truco, ni están en desuso.
La advertencia es que todavía son solo una aproximación. Los valores de altura de línea sin unidad no cambian el modelo de caja de CSS subyacente, ni las reglas de posicionamiento de caja de CSS. Por lo tanto, es posible que, en algunos casos extremos, no tengan el resultado esperado. Pero la vigilancia eterna es el precio de una buena tipografía. Ten cuidado afuera.
Matthew, intente agregar "line-height: 1.5em;" a la clase ".smaller". ¿Resuelve el problema para todas las declaraciones?
Creo que sí, y si es así, tiene que ser una cuestión de herencia. La diferencia entre 1.5em / 150% y 1.5 (sin ninguna unidad) es que los dos primeros calculan el valor y lo configuran en una materia absoluta en su elemento, por lo tanto un hijo de ese elemento sin su propia declaración de altura de línea heredará el valor calculado, y no el porcentaje.
Sin embargo, declarar la altura de línea sin una unidad tiene un resultado diferente para ese elemento hijo porque lo que realmente se hereda es ese número (1,5 - en su caso) que se computará una vez más en el elemento hijo dando como resultado un valor relacionado a su propio tamaño de fuente y no a sus padres.
Usted dice que la especificación define toda la versión de la misma manera y que los resultados deberían ser los mismos, pero esto es lo que realmente se dice:
<number>
El valor utilizado de la propiedad es este número multiplicado por el tamaño de fuente del elemento. Los valores negativos son ilegales. El valor calculado es el mismo que el valor especificado .
<percentage>
El valor calculado de la propiedad es este porcentaje multiplicado por el tamaño de letra calculado del elemento . Los valores negativos son ilegales.
Esta es la diferencia: lo que realmente se calcula. Cuando declaras la línea-heght como un porcentaje (o usando ems), el valor calculado es el valor numérico resultante, mientras que, en el caso de la declaración sin unidades, el valor calculado es el mismo que el valor declarado que hace posible el elemento hijo para recalcular
Mientras tanto, hice la prueba y creo que tenía razón.
Cuando declara la altura de la línea como un porcentaje (o utilizando ems), el valor computado es heredado por el elemento span. Por lo tanto, la altura de línea del elemento span será de 24px en lugar de 13.5px. Pero, dado que el tamaño de fuente del elemento span es de hecho más pequeño, el resultado que se muestra a continuación será más grande que el de sus padres. (24px-9px) /2=7.5px. Por lo tanto, obtendrás 7.5px de ventaja a continuación en lugar de (24-16) / 2 (4px). Terminas con una ventaja extra de 7.5px-4px (3.5px).
Parece que la respuesta simple a su pregunta sería: herencia . line-height: 150%
y line-height: 1.5em
en su ejemplo hereda el valor de la computadora de su padre, mientras que un valor numérico no lo hace.
En su ejemplo, el padre <p>
tiene una altura de línea de 21px, si usa porcentajes o ems para especificar el alto de línea de su elemento anidado <span class="small">
se calculará basándose en el valor calculado heredado de 21px; 21 * 1.5 = 31.5, pero si usa el valor numérico para la altura de la línea, se calculará en función del tamaño real de la fuente; (14 * 0.5) * 1.5 = 10.5.
Tienes una respuesta perfecta para tu pregunta here .