Una guía completa para calc() en CSS

 

 

 


Índice
  1. calc()es para valores
  2. calc()es para longitudes y otras cosas numéricas
  3. No a las consultas de los medios
  4. ¿Unidades de mezcla?
  5. Comparación con las matemáticas del preprocesador
  6. mostrar las matemáticas
  7. Los operadores matemáticos decalc()
  8. Anidacióncalc(calc());
  9. Propiedades personalizadas de CSS y calc()?
  10. Herramientas del navegador
  11. Soporte del navegador
  12. Fiesta de casos de uso
  13. Otros engaños

CSS tiene una calc()función especial para realizar operaciones matemáticas básicas. En esta guía, cubriremos casi todo lo que hay que saber sobre esta función tan útil.

 

He aquí un ejemplo:

.main-content { /* Subtract 80px from 100vh */ height: calc(100vh - 80px);}

En esta guía, cubriremos casi todo lo que hay que saber sobre esta función tan útil.

calc()es para valores

El único lugar donde puedes usar la calc()función es en valores. Vea estos ejemplos en los que configuramos el valor para varias propiedades diferentes.

.el { font-size: calc(3vw + 2px); width: calc(100% - 20px); height: calc(100vh - 20px); padding: calc(1vw + 5px);}

También podría usarse solo para una parte de una propiedad, por ejemplo:

.el { margin: 10px calc(2vw + 5px); border-radius: 15px calc(15px / 3) 4px 2px; transition: transform calc(1s - 120ms);}

¡Incluso puede ser parte de otra función que forma parte de una propiedad! Por ejemplo, aquí se calc()usa dentro de las paradas de color de un degradado.

.el { background: #1E88E5 linear-gradient( to bottom, #1E88E5, #1E88E5 calc(50% - 10px), #3949AB calc(50% + 10px), #3949AB );}

calc()es para longitudes y otras cosas numéricas

Observe que todos los ejemplos anteriores se basan esencialmente en números. Llegaremos a algunas de las advertencias sobre cómo se pueden usar los números (porque a veces no necesitas una unidad), pero esto es para matemáticas numéricas, no cadenas ni nada por el estilo.

.el { /* Nope! */ counter-reset: calc("My " + "counter");}.el::before { /* Nope! */ content: calc("Candyman " * 3);}

Sin embargo, hay muchas longitudes de CSS y todas se pueden utilizar con calc():

  • píxeles
  • %
  • ellos
  • movimiento del ojo rapido
  • es
  • milímetros
  • cm
  • pt
  • ordenador personal
  • ex
  • ch
  • vh
  • VW
  • vmin
  • vmáx

Los números sin unidades también son aceptables. Por ejemplo, line-height: calc(1.2 * 1.2);así como ángulos como transform: rotate(calc(10deg * 5));.

Tampoco puedes realizar ningún cálculo y sigue siendo válido:

.el { /* Little weird but OK */ width: calc(20px);}

No a las consultas de los medios

Cuando calc()se usa correctamente (unidades de longitud utilizadas como valor para una propiedad), lamentablemente calc()no funcionará cuando se aplica a consultas de medios.

@media (max-width: 40rem) { /* Narrower or exactly 40rem */}/* Nope! */@media (min-width: calc(40rem + 1px)) { /* Wider than 40rem */}

Algún día sería genial porque podrías realizar consultas de medios mutuamente excluyentes de una manera bastante lógica (como arriba).

 

¿Unidades de mezcla?

Esta es quizás la característica más valiosa de calc()! Casi todos los ejemplos anteriores ya han hecho esto, pero solo para aclararlo, aquí se mezclan diferentes unidades:

/* Percentage units being mixed with pixel units */width: calc(100% - 20px);

Es decir: Tan ancho como sea el elemento, menos 20 píxeles.

Literalmente, no hay forma de calcular previamente ese valor solo en píxeles en una situación de ancho fluido. En otras palabras, no puedes preprocesar calc()con algo como Sass como un intento de completar un polirelleno. No es que sea necesario, ya que la compatibilidad con el navegador está bien. Pero el punto es que debe hacerse en el navegador (en “tiempo de ejecución”) cuando mezclas unidades de esta manera, que es la mayor parte del valor de calc().

Aquí hay algunos otros ejemplos de unidades de mezcla:

transform: rotate(calc(1turn + 45deg));animation-delay: calc(1s + 15ms);

Probablemente podrían preprocesarse, ya que mezclan unidades que no son relativas a nada que se determine en el tiempo de ejecución.

Comparación con las matemáticas del preprocesador

Acabamos de cubrir que no se pueden preprocesar las cosas más útiles que calc()se pueden hacer. Pero hay una pizca de superposición. Por ejemplo, Sass tiene matemáticas integradas, por lo que puedes hacer cosas como:

$padding: 1rem;.el[data-padding="extra"] { padding: $padding + 2rem; // processes to 3rem; margin-bottom: $padding * 2; // processes to 2rem; }

Incluso las matemáticas con unidades funcionan allí, sumando valores de la misma unidad o multiplicando por números sin unidades. Pero no se pueden mezclar unidades similares y tiene limitaciones calc()(por ejemplo, multiplicar y dividir deben realizarse con números sin unidades).

mostrar las matemáticas

Incluso si no estás utilizando una función que solo es posible con calc(), puedes usarla para “mostrar tu trabajo” dentro de CSS. Por ejemplo, digamos que necesita calcular exactamente 17 del ancho de un elemento…

.el { /* This is easier to understand */ width: calc(100% / 7); /* Than this is */ width: 14.2857142857%;}

Eso podría funcionar en algún tipo de API CSS de creación propia como:

[data-columns="7"] .col { width: calc(100% / 7); }[data-columns="6"] .col { width: calc(100% / 6); }[data-columns="5"] .col { width: calc(100% / 5); }[data-columns="4"] .col { width: calc(100% / 4); }[data-columns="3"] .col { width: calc(100% / 3); }[data-columns="2"] .col { width: calc(100% / 2); }

Los operadores matemáticos decalc()

Tienes +, -, *y /. Pero difieren en cómo se requiere su uso.

La suma ( +) y la resta ( -) requieren que ambos números sean largos

.el { /* Valid */ margin: calc(10px + 10px); /* Invalid */ margin: calc(10px + 5);}

Los valores no válidos invalidan toda la declaración individual.

 

La división ( /) requiere que el segundo número no tenga unidades

.el { /* Valid */ margin: calc(30px / 3); /* Invalid */ margin: calc(30px / 10px); /* Invalid (can't divide by 0) */ margin: calc(30px / 0);}

La multiplicación (*) requiere que uno de los números no tenga unidades.

.el { /* Valid */ margin: calc(10px * 3); /* Valid */ margin: calc(3 * 10px); /* Invalid */ margin: calc(30px * 3px);}

El espacio en blanco importa

Bueno, lo hace para la suma y la resta .

.el { /* Valid */ font-size: calc(3vw + 2px); /* Invalid */ font-size: calc(3vw+2px); /* Valid */ font-size: calc(3vw - 2px); /* Invalid */ font-size: calc(3vw-2px);}

Los números negativos están bien (p. ej. calc(5vw - -5px)), pero ese es un ejemplo de dónde el espacio en blanco no sólo es necesario, sino que también es útil.

Tab Atkins me dice que el motivo del espacio requerido +se -debe en realidad a problemas de análisis. No puedo decir que lo entiendo completamente, pero, por ejemplo, 2px-3pxse analiza como el número “2” y la unidad “px-3px” que no le hace ningún bien a nadie, y +tiene otros problemas como ser “consumido por la sintaxis numérica”. ”. Habría adivinado que el espacio en blanco tendría que ver con la --sintaxis de las propiedades personalizadas, ¡pero no! Recetas faciles y rápidas

La multiplicación y la división no necesitan espacios en blanco alrededor de los operadores. Pero creo que un buen consejo general es incluir espacio para la legibilidad y la memoria muscular de los demás operadores.

Los espacios en blanco alrededor del exterior no importan. Incluso puedes hacer saltos de línea si lo deseas:

.el { /* Valid */ width: calc( 100% / 3 );}

Pero tenga cuidado con esto: no hay espacios entre calc()el par inicial y el par inicial.

.el { /* Invalid */ width: calc (100% / 3);}

Anidacióncalc(calc());

Puedes pero nunca es necesario. Es lo mismo que usar un par de paréntesis extra sin la calc()pieza. Por ejemplo:

.el { width: calc( calc(100% / 3) - calc(1rem * 2) );}

No los necesitas adentro calc()porque los padres trabajan solos:

.el { width: calc( (100% / 3) - (1rem * 2) );}

Y en este caso el “orden de las operaciones” nos ayuda incluso sin los paréntesis. Es decir, la división y la multiplicación ocurren primero (antes de la suma y la resta), por lo que los paréntesis no son necesarios en absoluto. Podría escribirse así:

.el { width: calc(100% / 3 - 1rem * 2);}

Pero siéntete libre de utilizar los pares si crees que aporta claridad. Si el orden de las operaciones no funciona a su favor (por ejemplo, primero necesita hacer la suma o la resta), necesitará paréntesis.

 

.el { /* This */ width: calc(100% + 2rem / 2); /* Is very different from this */ width: calc((100% + 2rem) / 2);}

Propiedades personalizadas de CSS y calc()?

Además de la asombrosa capacidad de calc()mezclar unidades, lo siguiente más sorprendente calc()es usarlo con propiedades personalizadas. Las propiedades personalizadas pueden tener valores que luego usará en un cálculo:

html { --spacing: 10px;}.module { padding: calc(var(--spacing) * 2);}

Estoy seguro de que puedes imaginar una configuración de CSS en la que se realizan muchas configuraciones en la parte superior estableciendo un montón de propiedades personalizadas de CSS y luego dejando que el resto del CSS las use según sea necesario.

Las propiedades personalizadas también pueden hacer referencia entre sí. A continuación se muestra un ejemplo en el que se utilizan algunas matemáticas (tenga en cuenta la falta de una calc()función al principio) y luego se aplican. (En última instancia, tiene que estar dentro de un calc()).

html { --spacing: 10px; --spacing-L: var(--spacing) * 2; --spacing-XL: var(--spacing) * 3;}.module[data-spacing="XL"] { padding: calc(var(--spacing-XL));}

Puede que no le guste, ya que necesita recordar calc()dónde usa la propiedad en ese momento, pero es posible y potencialmente interesante desde una perspectiva de legibilidad.

Las propiedades personalizadas pueden provenir del HTML, lo cual a veces es algo bastante interesante y útil. (Vea cómo Splitting.js agrega índices a palabras/caracteres como ejemplo).

div ... /divdiv ... /divdiv ... /div
div { /* Index value comes from the HTML (with a fallback) */ animation-delay: calc(var(--index, 1) * 0.2s);}

Agregar unidades más tarde

En caso de que te encuentres en una situación en la que sea más fácil almacenar números sin unidades, o hacer matemáticas con números sin unidades con anticipación, siempre puedes esperar hasta aplicar el número para sumar la unidad multiplicando por 1 y la unidad.

html { --importantNumber: 2;}.el { /* Number stays 2, but it has a unit now */ padding: calc(var(--importantNumber) * 1rem);}

Jugando con los colores

Los formatos de color como RGB y HSL tienen números con los que puedes jugar calc(). Por ejemplo, establecer algunos valores base de HSL y luego modificarlos formando un sistema de su propia creación (ejemplo):

html { --H: 100; --S: 100%; --L: 50%;}.el { background: hsl( calc(var(--H) + 20), calc(var(--S) - 10%), calc(var(--L) + 30%) )}

No puedes combinar calc() y attr()

La attr()función en CSS parece atractiva, como si pudieras extraer valores de atributos de HTML y usarlos. Pero…

div data-color="red".../div
div { /* Nope */ color: attr(data-color);}

Desafortunadamente, aquí no hay "tipos" en juego, por lo que lo único attr()que se necesita son cadenas en conjunto con la contentpropiedad. Eso significa que esto funciona:

 

div::before { content: attr(data-color);}

Menciono esto porque puede resultar tentador intentar extraer un número de esa manera para utilizarlo en un cálculo, como:

div data-columns="7" data-gap="2".../div
.grid { display: grid; /* Neither of these work */ grid-template-columns: repeat(attr(data-columns), 1fr); grid-gap: calc(1rem * attr(data-gap));}

Afortunadamente, no importa mucho porque las propiedades personalizadas en HTML son igual de útiles o más.

div.../div
.grid { display: grid; /* Yep! */ grid-template-columns: repeat(var(--columns), 1fr); grid-gap: calc(var(--gap));}

Herramientas del navegador

Browser DevTools le tenderá a mostrarle el contenido calc()tal como lo creó en la hoja de estilo.

Si necesita calcular el valor calculado, hay una pestaña Calculado (en todas las DevTools del navegador, al menos las que conozco) que se lo mostrará.

Soporte del navegador

Estos datos de soporte del navegador son de Caniuse, que tiene más detalles. Un número indica que el navegador admite la función en esa versión y superiores.

Escritorio

Cromo Firefox ES DECIR Borde Safari
19* 4* 11 12 6*

Móvil/Tableta

androidcromo Android Firefox Androide Safari en iOS
125 126 125 6,0-6,1*

Si realmente necesita soporte muy atrás (por ejemplo, IE 8 o Firefox 3.6), el truco habitual es agregar otra propiedad o valor antes del que usa calc():

.el { width: 92%; /* Fallback */ width: calc(100% - 2rem);}

También hay bastantes problemas conocidos calc(), pero todos corresponden a navegadores antiguos. ¿Puedo usar… enumera 13 de ellos. Aquí hay algunos:

  • Firefox 59 no admite calc()funciones de color. Ejemplo: color: hsl(calc(60 * 2), 100%, 50%).
  • IE 9-11 no representará la box-shadowpropiedad cuando calc()se use para cualquiera de los valores.
  • Ni IE 9-11 ni Edge son compatibles width: calc()con las celdas de la tabla.

Fiesta de casos de uso

Le pregunté a algunos desarrolladores de CSS cuándo lo usaron por última vez calc()para que pudiéramos tener una buena idea de cómo lo usan otros en su trabajo diario.

Lo usé para crear una clase de utilidad completa: .full-bleed { width: 100vw; margin-left: calc(50% - 50vw); }diría que calc()está entre mis 3 mejores cosas de CSS.

Lo usé para dejar espacio para un pie de página adhesivo.

 

Lo usé para establecer algún tipo de fluido/tipografía dinámica... un cálculo font-sizebasado en mínimos, máximos y una tasa de cambio de las unidades de la ventana gráfica. No sólo el font-size, sino line-heighttambién.

Si lo está utilizando calc()como parte de una situación de tipo fluido que involucra unidades de ventana gráfica y similares, asegúrese de incluir una unidad que use remo empara que el usuario aún tenga cierto control sobre cómo aumentar o disminuir esa fuente al acercarla o alejarla como necesitan para.

Una que realmente me gusta es tener una propiedad personalizada de "ancho de contenido" y luego usarla para crear el espacio que necesito, como márgenes:.margin { width: calc( (100vw - var(--content-width)) / 2); }

Lo usé para crear un componente de letra capitular para varios navegadores. He aquí una parte de ello:

.drop-cap { --drop-cap-lines: 3; font-size: calc(1em * var(--drop-cap-lines) * var(--body-line-height)); }

Lo usé para hacer que algunas imágenes desbordaran su contenedor en la página de un artículo.

Lo usé para colocar una visualización correctamente en la página combinándola con relleno y vw/ vhunidades.

Lo uso para superar limitaciones background-position, pero especialmente limitaciones en la colocación de paradas de color en degradados. Como “detenerse 0.75emantes de llegar al fondo”.

Otros engaños

  • Una cuadrícula de dos páginas que se divide en una sola columna sin consulta de medios
  • Un componente de héroe con una relación de aspecto similar
  • Imponer colores de alto contraste
  • Ayuda con las coordenadas de un porcentaje.clip-path





SUSCRÍBETE A NUESTRO BOLETÍN 

No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.










Al suscribirte, aceptas nuestra política de privacidad y nuestros términos de servicio.






Tal vez te puede interesar:

  1. ¿Cómo se hace el tamaño máximo de fuente en CSS?
  2. Cambiar el tamaño de los valores en pasos en CSS
  3. ¿Qué hace “revertir” en CSS?
  4. CSS4 es una mala idea

Una guía completa para calc() en CSS

Una guía completa para calc() en CSS

calc()es para valorescalc()es para longitudes y otras cosas numéricasNo a las consultas de los medios¿Unidades de mezcla?Comparación con las matemáticas de

programar

es

https://pseint.es/static/images/programar-una-guia-completa-para-calc-en-css-1336-0.jpg

2024-06-13

 

Una guía completa para calc() en CSS
Una guía completa para calc() en CSS

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

 

 

Update cookies preferences