¿Por qué la altura de línea sin unidad se comporta de manera diferente al porcentaje o em en este ejemplo?


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 interlineado por defecto. El segundo párrafo tiene una palabra más pequeña. Pero no afecta el interlineado en ese párrafo. No es que debería, pero entonces -

Los dos párrafos siguientes tienen line-height: 150%. De nuevo, el segundo párrafo tiene una palabra que es más pequeña. Pero esta vez, por razones poco claras, la fuente más pequeña crea espacio adicional 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 solucionar. (Especulo que tiene algo que ver con que el navegador reduzca la palabra y luego la mueva hacia abajo verticalmente para realinear las líneas de base.)

Los dos párrafos siguientes tienen line-height: 1.5em. Mi entendimiento es que 1.5em es lo mismo que 150%. Y de hecho, el comportamiento es el mismo: espacio adicional entre las dos primeras líneas de la segunda apartado.

Pero aquí es donde se pone raro: los siguientes dos párrafos tienen line-height: 1.5 - ninguna unidad especificada. Esta vez, el problema del espacio extra desaparece.

En suma, CSS parece estar dando resultados consistentes de espaciado de línea cuando las alturas de línea del padre y el hijo son diferentes (a través de la herencia del valor sin unidad), pero resultados inconsistentes cuando las alturas de línea del padre y el hijo son las mismas.

Así mis preguntas:

  1. Sé que hay una diferencia semántica intencional en la especificación CSS entre 1.5 y 150% o su sinónimo, 1.5em. (A saber: un valor sin unidad se pasa al elemento hijo y su altura de línea se calcula utilizando el tamaño de fuente del hijo, mientras que un valor de porcentaje o em hará que se calcule una altura de línea para el padre, y luego ese valor calculado se pasa al hijo. Pero, ¿cómo explica esto la diferencia de comportamiento que se ve aquí? ¿Dónde está el espacio extra que viene? Si es una consecuencia de alguna regla de posicionamiento CSS, entonces ¿cuál es esa regla?

  2. O, si todos estos ejemplos deben representar de la misma manera, entonces ¿cuál se implementa incorrectamente? (Nota sobre la P2: El hecho de que la peculiaridad de renderizado ocurre 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).)

  3. En términos prácticos, ¿hay un inconveniente para cambiar a mediciones sin unidades como 1.5 para line-height? (Respuesta: no)

Author: Matthew Butterick, 0000-00-00

4 answers

Basado en las pistas en las respuestas propuestas, creo que el comportamiento de renderizado visto en estos ejemplos es contraintuitivo, pero correcto, y ordenado por la interacción de varias reglas en la especificación, y el modelo general de caja CSS .

  1. CSS calcula la L inicial necesaria para una caja por la fórmula line-height = L + AD, donde AD es " la distancia desde la parte superior hasta el inferior " de la fuente. Entonces " la mitad de la delantera se añade por encima de A y el otro la mitad por debajo de D." texto que tiene font-size:16px y line-height:24px tendrá 4px de delante por encima y por debajo. Texto que font-size:8px y line-height:24px tendrán 8px de liderazgo arriba y abajo.

  2. Por defecto, sin embargo, "el agente de usuario debe alinear los glifos ... por su pertinente líneas de base.". Esto empieza a explicar lo que está pasando aquí. Cuando line-height es especificado por porcentaje o em, un valor calculado es heredado por el niño (aquí, el intervalo smaller). Es decir, el intervalo smaller obtiene el mismo line-height que el bloque padre. Pero debido a la L + Fórmula de ANUNCIO, el texto de ese lapso tiene más liderazgo en la parte superior y inferior, y por lo tanto la línea de base se encuentra más alto en su caja. Navegador empuja hacia abajo el tramo smaller verticalmente para que coincida con las líneas de base.

  3. Pero entonces el navegador tiene un nuevo problema: cómo lidiar con la línea espacio en el bloque de cierre, que ha sido interrumpido por este línea de base-proceso de ajuste. La especificación resuelve esto también: line-height de un elemento a nivel de bloque " especifica el mínimo altura de cajas de línea dentro de la elemento " . Es decir, CSS no hace ninguna promesa de que obtendrá su exacta line-height, solo que obtendrás al menos esa cantidad. Así que el navegador empuja las líneas separadas en el bloque de cierre para que el la caja del niño realineada encajará.

La razón por la que esto es contradictorio es que es lo contrario de cómo funcionan la mayoría de los procesadores de texto y programas de diseño de páginas. En estos programas, un tramo más pequeño de texto dentro de un párrafo está alineado por su línea de base (como CSS) pero la altura de la 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 alrededor de un modelo de caja . Así que al final, podríamos decir que este comportamiento de espaciado es una consecuencia de ese modelo.

Eso aún nos deja explicar el comportamiento en el ejemplo con la altura de línea sin unidad:

  1. En primer lugar, tenga en cuenta que cuando no se especifica line-height, el navegador aplicará una altura de línea sin unidad por defecto. Esto es requerido por el spec : el valor inicial de line-height es normal, que se define como tienen " el mismo significado que ", 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 con line-height: 1.5 tienen el mismo comportamiento que los párrafos sin ajuste de altura de línea (es decir, están implícitamente llegar line-height: normal)

  2. Como otros han señalado, cuando el párrafo line-height: 1.5, el calculado línea-altura del párrafo es no heredado por el intervalo smaller. Más bien, el intervalo smaller calcula su propia altura de línea en función de su propio tamaño de fuente. Cuando el párrafo tiene line-height: 1.5; font-size: 14px, entonces su la altura de línea calculada es 14px * 1.5 = 21px. Y si el smaller span solo tiene la propiedad font-size: 50%, entonces su tamaño de fuente es 14px * 50% = 7px, y su altura de línea es 7px * 1.5 = 10.5 px (que generalmente se redondeará a un píxel completo). Pero en general, el smaller la caja es la mitad del tamaño del entorno texto.

  3. Como antes, el navegador alineará verticalmente el intervalo smaller para la línea de base adyacente. Pero esta vez, porque la caja alrededor smaller es más corto que el texto circundante, este realineamiento no tiene ningún efecto secundario en el bloque de cierre. Ya se ajusta, por lo que no hay necesidad de extender las líneas del párrafo padre, como había antes.

Ambos casos representan una implementación consistente del spec. Esas son buenas noticias, porque significa que podemos predecir el comportamiento del espaciado entre líneas.

Eso nos lleva de vuelta a la razón original de esta pregunta. Aunque ahora entiendo que el modelo de caja CSS requiere este comportamiento, como tipógrafo practicante, este rara vez es el comportamiento que quiero. 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 manera de hacer cumplir directamente la línea exacta espaciado en CSS como se puede en un procesador de textos o programa de diseño de página. Una vez más, esto se debe al modelo de caja CSS: no utiliza un modelo de espaciado de línea base a línea base, y line-height se especifica como una medida mínima, no máxima.

Pero al menos podemos decir que los valores de altura de línea sin unidad producen la mejor aproximación del espaciado de línea exacto en CSS. Los tipógrafos quisquillosos como yo deberían sentirse cómodos usándolos, porque los valores unitarios están respaldados por el spec , 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 CSS subyacente, ni las reglas de posicionamiento de caja CSS. Por lo tanto, es posible que en algunos casos extremos, no tengan el resultado deseado. Pero la vigilancia eterna es el precio de una buena tipografía. Ten cuidado ahí fuera.

 31
Author: Matthew Butterick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-28 19:01:01

EDITAR

He creado un codepen para demostrar el principio que se crea utilizando los diferentes valores. Esperemos que esto proporcione una mejor explicación.


Puedo responder a sus preguntas, pero solo teorizar (en este punto) sobre el espacio adicional que está viendo (y proporcionar una posible solución).

Sus preguntas

¿Hay una diferencia semántica intencional en CSS entre 1.5 y 150% que explica la diferencia en comportamiento?

Hay, en realidad!

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 porcentual (150%) se utiliza para calcular la altura de una línea en función del tamaño de fuente del elemento padre. El valor pre-calculado resultante es entonces heredado por sus descendientes.

O, si están destinados a ser los mismos, entonces cuál se implementa incorrectamente?

Son intencionalmente diferentes. (Véase la especificación del W3C )

En términos prácticos, ¿hay un inconveniente en cambiar a decimales sin procesar como 1.5 para la altura de línea?

Por lo general, es una ventaja utilizar los valores decimales, porque la altura de línea heredada se adaptará mejor. Pero hay casos en los que no se adapta a sus necesidades.


Cuestión de Espaciado adicional

Me di cuenta si pongo vertical-align en tu texto pequeño a middle o bottom, el problema no sucede. Pero esta no es una muy buena solución.

Estoy adivinando esto tiene que ver con el hecho de que el texto más pequeño está utilizando la altura de línea calculada heredada, combinada con su ubicación en la línea. Dado que el texto es más pequeño y se encuentra más bajo, pero tiene la misma altura de línea que la línea circundante, la mitad inferior inicial en realidad empujará más abajo, y la mitad superior inicial no alcanzará tan alta como el texto circundante.

Así que vamos a digamos que el tamaño de la fuente base es 16px, y la altura de la línea es 24px. El líder será 4px en cada lado ((24-16)/2). Cuando el tamaño de la fuente es 50%, es 8px, pero la altura de la línea permanece 24px. Así que el líder se convierte en 8px en cada lado ((24-8)/2).

Las líneas de base del texto se alinearán, por lo que, en igualdad de condiciones, se esperaría que el texto más pequeño se extendiera 4px por debajo del texto normal. Pero como el texto (y su área de contenido correspondiente) es más pequeño, la mitad inferior comienza más lejos volver, por lo que solo se ve un píxel o dos cambiar, y solo en ciertos porcentajes (conseguir más a medida que se hace más pequeño - probarlo)

Realmente debería usar imágenes para esto, pero no puedo en este momento... tal vez pueda añadir algo más tarde.

No se si eso ayuda en absoluto, pero definitivamente tengo una mejor comprensión de cómo line-height funciona 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 /

 5
Author: Tom Pietrosanti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-28 19:36:19

Parece que la respuesta simple a tu 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 percentage o ems para especificar la altura de línea de su elemento anidado <span class="small"> se calculará en función del valor computado heredado de 21px; 21*1.5 = 31.5, pero si usa el valor numérico para la altura de línea, calculado en función del tamaño real de la fuente; (14*0.5)*1.5 = 10.5.

Tienes una respuesta perfecta a tu pregunta aquí.

 0
Author: unitario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:11

Matthew, intenta agregar "line-height:1.5 em;" a la ".clase "más pequeña". Soluciona el problema de todas las declaraciones?

Creo que sí, y si es así, tiene que ser una cuestión de herencia. La diferencia entre 1.5 em/150% y 1.5 (sin ninguna unidad) es que los dos primeros calculan el valor y lo establecen 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 porcentaje.

Declarar la altura de línea sin una unidad, sin embargo, 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 calculará una vez más en el elemento hijo, lo que resulta en un valor relacionado con su propio tamaño de fuente y no con el de su padre.

Usted dice que la especificación define toda la versión de la misma manera y por lo tanto los resultados deben 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 fuente calculado del elemento. Los valores negativos son ilegales.

Esta es la diferencia: lo que realmente se calcula. Cuando se declara la línea-heght como un porcentaje (o utilizando ems) el valor calculado es la numérica resultante valor, mientras que, en el caso de la declaración unitless, el valor calculado es el mismo que el valor declarado, lo que permite que el elemento hijo vuelva a calcular.

Mientras tanto, he hecho la prueba y creo que tenía razón.

Cuando declara la line-height como un porcentaje (o usando ems), el valor calculado es heredado por el elemento span. Así que la altura de línea del elemento span será 24px en lugar de 13.5 px. Pero, dado que el tamaño de fuente del elemento span es de hecho más pequeño, el resultado anterior será más grande que el de su padre. (24px-9px)/2=7.5 px. Así que obtendrás 7.5 px a continuación en lugar de (24-16)/2 (4px). Terminas con una ventaja extra de 7.5 px-4px (3.5 px).

 0
Author: Sebastian Tomita,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-28 13:39:01