Skip links

Es posible que necesitemos algo entre la raíz del «elemento básico» y la unidad CSS relativa

CSS nos proporciona valores raíz y relativos.

  • El valor raíz es como rem y rlh – Están escritos en :root Selector (más común html elemento).
  • El valor relativo es como em,,,,, lh,,,,, ch Hay varios otros, están con font-size En ese elemento particular.

Me he dado cuenta de que tal vez necesitamos tener una unidad entre la raíz y el valor relativo. Tener tales unidades nos permite tamaño sin complejidad em o lh calcular.

Déjame darte un ejemplo: prosa

A principios de este año Jen Simmons Escrito usar lh unidad estilo margin y padding mejor Imprimir ritmo vertical.

p { margin-block: 1lh; } 

Podemos ampliar aún más el concepto para incluir todos los demás espacios alrededor del texto. Una forma es Tecnología de «búho lobotomizado» Eso Pickering de Haydn Se hizo popular no hace mucho.

* + * {
  margin-top: 1lh;
}

Hoy también podemos usarlo :not(:first-child) Para lograr el mismo efecto, esto puede ser más legible.

*:not(:first-child) {
  margin-top: 1lh;
}

A menudo, necesitamos limitar estos selectores para que no se desborden en todas partes y rompan el resto de la página. Una gran clase es .prose.

.prose {
  *:not(:first-child) {
    margin-top: 1lh;
  }
}

Es simple y bueno, pero ¿qué sucede si incluye otros tamaños de diseños? Verás esta descomposición pronto (porque 1lh uno <h2> Los elementos pueden ser muy grandes).

Una forma de resolver este problema es usar Flexbox En el elemento principal. Al hacer esto podemos configurar gap llegar 1lh Y no tenemos que lidiar con eso 1lh Cambiar h2 elemento. (Bonificación, no tenemos que lidiar con el margen. Colapsar)

.prose {
  display: flex; 
  flex-direction: column;
  gap: 1lh;
}

Pero presentamos una nueva pregunta aquí: Cerca del caos.

El siguiente contenido <h2> pertenecer <h2>. Pero el contenido anterior <h2> Pertenece al título de la sección anterior. Idealmente, debemos hacer que el espacio sea exclusivo para aclarar su relación.

La forma más fácil es agregar un pequeño margen arriba <h2>.

Pero no podemos agregar un margen en él <h2> y lh desde lh Valor abierto <h2> Será diferente de los elementos circundantes.

Tenemos que usar algunas estafas CSS y margin-bottom (o equivalente lógico) el elemento anterior <h2>. Aquí acabamos de configurar margin-bottom llegar 1lh Como usamos FlexBox, no tenemos que lidiar con los accidentes de margen. (Si tiene que lidiar con accidentes de margen, debe configurarlo margin-bottom llegar 2lh)

¿Hay una mejor manera? Ok, ¡ese es el propósito de este artículo!

Sin embargo, antes de ir allí, consideremos una interfaz de usuario con problemas similares, para que pueda comenzar a ver las mayores consecuencias de este problema (y la importancia de la solución).

Aquí está el segundo ejemplo: componente de la tarjeta

Ahora, supongamos que tenemos un componente de tarjeta que se divide en dos partes, título y contenido.

En estos componentes, el título generalmente tiene diferentes estilos font-size Compare contenido.

Ejemplo de componente de la tarjeta. El gran encabezado negro dice. Hay un límite entre el título y el párrafo del texto del marcador de posición.

Para crear una tarjeta como esta, el marcador más fácil podría ser:

<div class="card">
  <h2 class="title">Card Title</h2>
  <div class="content">Card Content</div>
</div>

Desafortunadamente, no podemos usarlo lh Crear unidades de relleno en la tarjeta: hacerlo dará como resultado un margen <h2> ¡Los elementos (increíblemente) son desproporcionados!

Por supuesto, hay muchas maneras de lidiar con esta situación.

Una forma posible es cambiar el marcado para que <h2> Viviendo en <header> elemento. Cuando lo hacemos, podemos <header>omitir la expansión 1lh pregunta.

<div class="card">
  <header class="title">
    <h2>Card Title</h2>
  </header>
  <div class="content">Card Content</div>
</div>

Resolvió el problema al cambiar la etiqueta, lo cual no es ideal, porque probablemente no queremos crear un extra header Elementos a menos que sea necesario …

Ok, otra forma posible es usar un valor raíz similar rlh. Esto permite <h2> y content Para usar la misma unidad base, puede crear el mismo relleno.

Pero si .card Necesita ser extendido a diferente font-size valor. Imagina que quieres hacer una tarjeta más pequeña, ahora 1rlh Dado que el valor de relleno es demasiado proporcional al contenido, no se ve correcto.

¿Qué podemos hacer?

Una solución fácil es cambiar padding Dependiendo del valor de la variante de soporte del componente, pero esto es un poco codificado y no muy amigable …

.card-sm { --padding: 0.75rlh; }
.card-md { --padding: 1rlh; }
.card-lg { --padding: 1.25rlh; }

¿Qué otras opciones?

Aquí es donde el intermediario entre la raíz y la unidad relativa puede ser útil.

Unidad interna conveniente

Esta sección es CSS puramente especulativo para ilustrar un punto. Tomaremos una manera fácil de practicar en una parte posterior de hoy, así que espera y siga conceptualmente por el momento.

Supongamos que tenemos una celda para obtener su valor de referencia del elemento especificado. Lo llamamos base Unidad, debido a la falta de mejores nombres.

  • Entonces 1 base La celda de tamaño de fuente puede ser 1bem.
  • y 1 base La unidad de altura de línea puede ser 1blh.

Es muy fácil en este momento.

Imagine que podemos usar esta unidad básica para dar forma a la tarjeta. Entonces simplemente podemos usar 1blh Cuantifica el relleno, todo lo demás tendrá un tamaño adecuado:

.card {
  > * { padding: 1blh; }  
}

.card-sm { font-size: 0.8em; }
.card-md { font-size: 1em; }
.card-lg { font-size: 1.2em; }

¿alegría?

Atar esto en .prose Por ejemplo, es probable que pueda resolver bien el caos de proximidad sin complejar nuestros selectores:

.prose {
  h2:not(:first-child) {
    margin-top: 2blh;
  }
}

¿Cómo puede funcionar esto?

Para que esta característica sea fácil de agregar al CSS moderno, puedo pensar en dos formas posibles:

  1. Adjuntarlo a la consulta del contenedor.
  2. Define la sintaxis similar al posicionamiento de anclaje.

Método de consulta de contenedores

Ya tenemos algo similar cqw y cqh expresar Ancho de contenedor y valores de altura del contenedor. Di que podemos tener uno cqem (Consulta de contenedores em) Unidad o cqlh (Contenedor consulta-algodón de línea).

Este método tiene desventajas.

Primero, el contenedor debe definirse en el elemento principal. Esto requiere más marcado y hace que el código sea algo complejo e poco intuitivo. El siguiente código puede ser una posible implementación:

<div class="container">
  <div class="card">
    <h2 class="title">Card Title</h2>
    <div class="content">Card Content</div>
  </div>
</div>
.container {
  container-type: inline-size; 
}

.card {
  > * { padding: 1cqbl; }
}

Manejar contenedores anidados no es un problema, porque siempre podemos configurarlo container-name Queremos heredar. Sin embargo, si queremos usar diferentes referencias de contenedores, puede ocurrir una colisión cqbl y cqw.

Imaginar:

<!-- We might want to inherit the cqem or cqbl from here -->
<div class="container-base">

  <!-- But we might need cqw or cqh from here -->
  <div class="two-column-grid"> 
    <div class="card">...</div>
    <div class="card">...</div>
  </div>

</div>

Un poco está terriblemente restringido por colisiones de contenedores.

Sintaxis de posicionamiento de anclaje

En este caso, primero decidimos la base para heredar. Podemos llamarlo base-anchoro algo así.

Aquí podemos establecer un nombre básico de anclaje explícitamente e incluso mantenerlo como none Si no queremos nombrarlo. Los elementos restantes en el interior se pueden heredar de este valor base inmediatamente:

.card {
  base-anchor: --card; /* or perhaps none */
  > * { padding: 1blh; }
}

Si necesitamos hacer referencia a este ancla de un componente completamente no relacionado, podemos aprovechar el nombre del ancla, solo haga esto:

.far-away-comp {
  base-name: --card; 
  /* Then use blh from here */
}

Ancla

Un aspecto interesante que se me ocurra es un caso de uso potencial de doble anclaje base Los componentes pueden heredar su font-size o valor de otra base o su elemento principal.

Esta flexibilidad nos permite crear cambios de componentes basados en el tamaño de la fuente sin depender de la complejidad em calcular.

Aquí hay un ejemplo de lo que estoy hablando:

.prose {
  base-anchor: --prose;
  font-size: 1em;
  line-height: 1.5;
}

/* Inherits font-size from .prose */
/* This is automatic if base-name is not provided */
.card {
  base-anchor: none;
  base-name: --prose;

  /* In this case, 1blh could be 1.5em */
  > * { padding: 1blh; }
}

/* After inheriting the font size, since we have a base-anchor in the card, we adjust the font-size value accordingly, so: 
  - 1bem would mean 0.8em further in the card
  - 1blh could then mean 0.8 * 1.5em = 1.2em 
*/
.card.card-sm {
  font-size: 0.8em;
}

Encantador, ¿verdad? Esto trae nuevas posibilidades al crear componentes reutilizables.

Ponlo en práctica hoy

Permítanme mencionar el prefacio de esta sección a los siguientes hechos bem y blh No existe hoy. Por lo tanto, cualquier implementación que se me ocurra es solo una medida de estadía imperfecta.

Hoy estamos seguros de que podemos usarlo em Unidades para este propósito – Pero esto requiere más cálculos porque em Es un pariente, no una unidad básica.

El primer paso es confirmar base Elementos – y base Tamaño de fuente: podemos configurarlo base-size propiedad:

.card { 
  --base-size: 1em; 
  font-size: var(--base-size);
}

.card-sm { 
  --base-size: 0.8em; 
}

Entonces podemos simular bem (de acuerdo a em) Se esperan unidades asignando font-size y base-size:

.card {
  h2 {
    --font-size: 2em;
    font-size: calc(var(--font-size) / var(--base-size));  
  }
}

Desafortunadamente, el código anterior no se puede usar porque no podemos ejecutarlo calc() Divisionamiento de valor unitario. Por lo tanto, lo mejor que podemos hacer --base-size.

Cuando hacemos esto, necesitamos ejecutar otro calc() Crear un real en el elemento básico font-size propiedad:

.card { 
  --base-size: 1; 
  font-size: calc(var(--base-size) * 1em);
}

Luego ejecutamos lo mismo calc() existir <h2> Crear su tamaño de fuente:

.card {
  h2 {
    --font-size: 2;
    font-size: calc(var(--font-size) / var(--base-size) * 1em);  
  }
}

Todo comenzó a convertirse en un poco de «ugh».

Nadie quiere todo este código básico. Por lo tanto, es mejor usar mezclas o incluso características para abstraerlo. Si usa Sass, puede imaginar algo como esto:

@mixin base-anchor() {
  font-size: calc(var(--base-size) * 1em);
}

Si usa vientos de cola, tal vez pueda imaginar que la utilidad de los vientos de cola puede hacer lo mismo. después de todo, La utilidad del viento de cola se puede ver como una conveniente mezcla de Sharth.

@utility base-anchor {
  font-size: calc(var(--base-size) * 1em);
}

Luego podemos aplicar esta utilidad a los elementos básicos. El código se ve un poco limpio:

.card {
  @apply base-anchor; 
  --base-size: 1; 
}

.card-sm { --base-size: 0.8; }

para <h2>podemos crear otra utilidad para realizar cálculos para nosotros. Se parece a esto:

@utility text-relative {
  font-size: calc(var(--text-size) / var(--base-size) * 1em);
}

Entonces podemos usar una utilidad como esta:

.card .title {
  @apply text-relative;
  --text-size: 2; 
}

Ahora calcule padding Tarjeta .title Elementos, necesitamos revertir font-size conseguir base-size valor. Mejor usado Función CSSno ampliamente compatible hoy, ¡pero con suerte pronto!

@function --bem(--multiplier) {
  result: calc(var(--text-size / var(--base-size) * 1em * --multiplier));
}

Entonces podemos usar --bem Calcule el relleno del título de la tarjeta:

.card .title {
  /* ... */
  padding-block: --bem(0.5);
  padding-inline: --bem(1);
}

Mencionamos anteriormente lh El valor se puede usar para márgenes y relleno, ya que conserva el ritmo vertical. Entonces, ¿por qué no crear uno? --blh ¿La función es la misma?

En este caso podemos agregar --leading La función puede ser de:

@function --blh(--multiplier, --lh-multiplier) {
  result: calc(
    var(
      --text-size / var(--base-size) * 1em * --multiplier *
        var(--lh-multiplier, var(--leading))
    )
  );
}

Entonces podemos usar --blh Como esto:

.card .title {
  /* ... */
  padding-block: --blh(0.5);
  padding-inline: --blh(1);
}

En el espíritu de hoy

No podemos usar --bem y --blh En producción, todos los navegadores aún no están disponibles porque la función CSS aún no está disponible. Con el espíritu de producción bem Trabajar Ahorapodemos crear una utilidad para calcular --base-font-size De --font-size.

Tenga en cuenta que se llama a esta nueva variable --base-font-sizeNo --base-sizedesde --base-size Usado. (No podemos anular las variables CSS).

/* I multiplied the value by 1em here to make it easy for you to use the value */
@utility base-font-size {
  --base-font-size: calc(var(--base-size) / var(--font-size) * 1em);
}

También podemos crear una utilidad llamada base-line-height Obtener valor line-height. Cuando hacemos esto, si también pasamos --leading Cambiable:

@utility base-line-height {
  --base-leading: calc(var(--base-font-size)* var(--leading));
}

Entonces podemos usar calc existir --base-leading Para obtener el valor que queremos:

.card .title {
  @apply text-relative;
  @apply base-font-size;
  @apply base-line-height;
  --font-size: 2; 
  padding-inline: var(--base-line-height);
  padding-block: calc(var(--base-line-height) * 0.5);
}

Armar todo esto

Primero resumamos las utilidades y funciones necesarias en la implementación de hoy:

/* The necessary utilities */
@utility base-anchor {
  font-size: calc(var(--base-size) * 1em);
}

@utility text-relative {
  font-size: calc(var(--font-size) / var(--base-size) * 1em);
}

/* To use this today */
@utility base-font-size {
  --base-font-size: calc(var(--base-size) / var(--font-size) * 1em);
}

@utility base-line-height {
  --base-line-height: calc(var(--base-font-size)* var(--leading));
}

/* Easier usage when CSS Functions become available */
@function --bem(--multiplier) {
  result: calc(var(--font-size / var(--base-size) * 1em * --multiplier));
}

@function --blh(--multiplier, --lh-multiplier) {
  result: calc(
    var(
      --font-size / var(--base-size) * 1em * --multiplier *
        var(--lh-multiplier, var(--leading))
    )
  );
}

Ahora es .card Código para implementar la funcionalidad de viento de cola de la que estamos hablando. Puedes verlo aquí.

/* What we can actually use today */
.card {
  @apply base-anchor;
  --base-size: 1;
  --leading: 1.5;
  
  > * { padding: 1lh; }

  .title {
    @apply text-relative;
    @apply base-font-size;
    @apply base-line-height;
    --font-size: 2; 
    padding-inline: var(--base-line-height);
    padding-block: calc(var(--base-line-height) * 0.5);
  }
}

.card-sm {
  --base-size: 0.8;
  .title {
    --font-size: 1.2;
  }
}

/* What we can use when CSS Functions are available */
.card {
  @apply base-anchor;
  --base-size: 1;
  
  > * { padding: calc(--blh(1)); }

  .title {
    @apply text-relative;
    --text-size: 2; 
    padding-block: calc(--blh(0.5));
  }
}

Todavía no es tan bueno como bem y blh La versión que le mostré arriba, pero al menos, implementamos algún tipo de funcionalidad, ¿verdad? ¡Y se ve bastante bien!

Úselo con el brillante laboratorio hoy

Excelente estilo – Sucursales Excelente laboratorio Mango de diseño y estilo: contiene el código que puede usar hoy.

También incluimos --bem y --blh Versión, si también quieres jugar con ellos.

Para usar excelentes estilos, descargar la biblioteca e importar base-font-size Documentos, ¡haga el trabajo anterior que acaba de ver!

npm i @splendidlabz/styles
@import '@splendidlabz/styles/typography/base-font-size.css'

¡Eso es todo!

Ahora, si está interesado en todas las herramientas que estoy cocinando para facilitar el desarrollo web, puede obtener descuentos para las primeras aves Excelente embalaje profesional Hoy, ¡todos los lectores de CSS -Tricks pueden usarlo!

(Podría agregar una opción de por vida al paquete de estilo porque evoluciona por completo. Pero podría ser un año más o menos).

Ok, suficiente promoción. Volvamos aquí.

¿Cómo piensas en esta unidad entre la raíz y el valor relativo?

Dudo en llamarlo «básico» em Porque «básico» puede significar muchas cosas. Pero eso también suena bien.

  • Hacer bem y blh ¿Tiene sentido para ti?
  • ¿Crees que creo que este aspecto de diseño es demasiado?
  • ¿Quizás tengas un mejor nombre?

Me encantaría saber de ti, ¡así que siéntete libre de compartir tus pensamientos a continuación!

Leave a comment

Home
Account
Cart
Search
¡Hola! ¡Pregúntame lo que quieras!
Explore
Drag