calc()
es una forma nativa de CSS para hacer cálculos matemáticos simples directamente en CSS como reemplazo de cualquier valor de longitud (o prácticamente cualquier valor numérico). Tiene cuatro operadores matemáticos simples: sumar (+), restar (-), multiplicar
y dividir (/). Ser capaz de hacer matemáticas en código es bueno y una adición bienvenida a un lenguaje que es bastante numérico.
¿Pero es útil? He forzado mi cerebro en el pasado tratando de pensar en casos obviamente útiles. Sin embargo, definitivamente hay algunos.
¿No pueden los preprocesadores hacer nuestras matemáticas? Todos los preprocesadores CSS tienen funciones matemáticas y son bastante útiles. Pero no son tan poderosos como las matemáticas nativas. calc()
La habilidad más útil dees su capacidad para mezclar unidades
, como porcentajes y píxeles. Ningún preprocesador podrá hacer eso. Es algo que tiene que suceder en el momento del render.
.thing {
width: 90%; /* fallback if needed */
width: calc(100% - 3em);
}
Sintaxis
Debe haber espacios alrededor del operador matemático. Puedes anidar.
Soporte del navegador
Es sorprendentemente bueno. ¿Puedo usar … siempre es bueno para verificar los detalles allí? En el escritorio, las preocupaciones serían IE 9+, Safari 6+ y no estará en Opera hasta que esté en Blink en 15+. En dispositivos móviles, Android y Opera Mini aún no lo admiten en absoluto e iOS solo en 6.0+.
Tendrá que hacer la llamada allí. Ya he podido usarlo en producción en ciertos escenarios.
Caso de uso n. ° 1: (Todo el alto – Encabezado) height: 100%
Un elemento hijo a nivel de bloque con
será tan alto como su elemento padre a nivel de bloque. En algunos casos, puede ser bueno hacer un módulo de color tan alto como el elemento padre. overflow-y: auto;
Pero ahora digamos que el elemento padre se vuelve demasiado pequeño para contener todo el contenido del módulo. Desea que el contenido se desplace, pero solo desea que se desplace el contenido, no todo el módulo. Solo configurar
* {
/* So 100% means 100% */
box-sizing: border-box;
}
html, body {
/* Make the body to be as tall as browser window */
height: 100%;
background: #ccc;
padding: 20px;
}
body {
padding: 20px;
background: white;
}
.area-one {
/* With the body as tall as the browser window
this will be too */
height: 100%;
}
.area-one h2 {
height: 50px;
line-height: 50px;
}
.content {
/* Subtract the header size */
height: calc(100% - 50px);
overflow: auto;
}
¿derecho? No del todo, porque overflow-y solo es útil si el elemento de contenido en sí tiene una altura establecida que puede desbordarse. No podemos hacer que el elemento de contenido sea 100% alto porque con el encabezado allí, será demasiado alto. Necesitamos el 100% menos la altura del encabezado. Si conocemos la altura del encabezado, ¡es factible! calc()
Puede quejarse de que el encabezado no debería tener un tamaño fijo. Podría ser genial algún día si
Check out this Pen!
podría restar tamaños medidos de elementos, pero eso aún no es posible. Puede configurar el encabezado para que se desborde con puntos suspensivos.
Caso de uso n. ° 2: X píxeles desde la esquina inferior derecha
background-image: url(dog.png);
background-position: 50px 20px;
Podemos colocar fácilmente X píxeles de la imagen de fondo desde la esquina superior izquierda. calc()
Eso pondría al perro a 50 px de la izquierda y 20 px de la parte superior del cuadro de elementos. Pero, ¿qué pasa si lo quieres a 50 píxeles de la derecha y 20 píxeles de la parte inferior? No es posible solo con valores de longitud recta. Pero
background-image: url(dog.png);
background-position: calc(100% - 50px) calc(100% - 20px);
Check out this Pen!
¡lo hace posible!
Caso de uso n. ° 3: canalones fijos sin padres
Digamos que quiere dos columnas una al lado de la otra. El primer 40% de ancho, el segundo 60%, pero con un espacio fijo de 1em entre las columnas. No lo piense demasiado Las rejillas tienen canaletas fijas, pero no son verdaderas canaletas en cierto sentido. Las propias columnas chocan entre sí y las columnas están formadas por un relleno interno dentro de esas columnas. calc()
Utilizando
.area-one {
width: 40%;
float: left;
margin-right: 1em;
}
.area-two {
width: calc(60% - 1em);
float: right;
}
, podemos hacer que la primera columna tenga un ancho de 40% con un margen derecho de 1em, luego hacer que la segunda columna tenga un ancho de 60% menos ese 1em.
Check out this Pen!
Podrías quitar la mitad de la canaleta de ambos si quisieras mantener la proporción más precisa. Ahora tiene dos columnas verdaderas separadas por un espacio fijo sin necesidad de elementos padres o usando el relleno interno.
Caso de uso n. ° 4: Mostrar matemáticas es más fácil de entender
.column-1-7 {
width: 14.2857%
}
.column-2-7 {
width: 28.5714%
}
.column-3-7 {
width: 42.8571%
}
Hablando de columnas, a veces las matemáticas de división se complican. Digamos que desea una cuadrícula de 7 columnas, es posible que tenga clases como:
.column-1-7 {
width: calc(100% / 7);
}
.column-2-7 {
width: calc(100% / 7 * 2);
}
.column-3-7 {
width: calc(100% / 7 * 3);
}
Check out this Pen!
No son exactamente números mágicos, pero son difíciles de entender de un vistazo.
Caso de uso n. ° 5: Reemplazo de tamaño de caja un poco cutre box-sizing: border-box;
Soy un fan de universal
debido a que significa que no tienes que hacer muchos cálculos matemáticos para averiguar qué tan grande es realmente un elemento, ajustamos esos cálculos cuando cambian cosas como el borde y el relleno. calc()
Si desea replicar lo que hace el tamaño de caja, puede usar
.module {
padding: 10px;
/* Same as box-sizing: padding-box */
width: calc(40% - 20px);
border: 2px solid black;
/* Same as box-sizing: border-box */
width: calc(40% - 20px - 4px);
}
para restar los valores según sea necesario. calc()
el tamaño de la caja tiene un soporte de navegador mucho mejor que
sin embargo, esto se usaría raramente.
¿El futuro?
Creo que será interesante cuando podamos usar la función attr () en lugares distintos a la propiedad del contenido. Con eso, podríamos extraer el valor de los elementos HTML, ejecutar cálculos sobre ellos y usar los nuevos números para hacer cosas de diseño. Como colorear las entradas en función de los números que contienen. <progress>
Quizás incluso podríamos usarlo para hacer cosas elegantes con el
/* Not real */
progress::progress-bar {
transform: rotate(calc(!parent(attr(value))*18)) + deg);
}
elementos como convertirlo en un velocímetro como en esta página. Quizás algo como: