CSS

CSS CSS

CSS 3link image 0

Partes de CSS (selector, propiedades, valores)link image 1

En CSS se pueden hablar de 3 partes principales:

  • Selector: Es la parte que selecciona el elemento al que se le va a aplicar el estilo.
  • Propiedad: Es la parte que define el estilo que se le va a aplicar al elemento.
  • Valor: Es la parte que define el valor de la propiedad que se le va a aplicar al elemento.

Para añadir comentarios en CSS se utiliza /* comentario */.

A la línea que tiene propiedad: valor; se le llama declaración.

selector {
          propiedad: valor;   /* comentario */
      }
      

Selectoreslink image 2

Hay varios tipos de selectores:

  • Selector universal: Selecciona todos los elementos de la página. Se utiliza el asterisco *.
  • Selector de tipo: Selecciona todos los elementos de un tipo. Se utiliza el nombre del tipo de elemento. Por ejemplo, p selecciona todos los párrafos.
  • Selector de clase: Selecciona todos los elementos que tengan una clase. Se utiliza el nombre de la clase. Por ejemplo, .clase selecciona todos los elementos que tengan la clase clase. Esto es útil, porque si queremos que todos los botones sean iguales, en el html ponemos <button class="boton"> y en el css ponemos .boton . Así todos los botones tendrán los mismos estilos, y queremos que un botón sea diferente, le ponemos otra clase.
  • Selector de pseudo-clase: Selecciona todos los elementos que tengan una pseudo-clase. Se utiliza el nombre de la pseudo-clase. Por ejemplo, :hover selecciona todos los elementos que estén siendo seleccionados por el ratón. Esto es útil, porque si queremos que un botón cambie de color cuando el ratón esté encima, en el css ponemos .boton:hover . Así el botón tendrá los estilos que queramos cuando el ratón esté encima. Algunas pseudo-clases son:
    • :hover: Selecciona todos los elementos que estén siendo seleccionados por el ratón.
    • :active: Selecciona todos los elementos que estén siendo seleccionados por el ratón y estén siendo pulsados.
    • :focus: Selecciona todos los elementos que estén siendo seleccionados por el ratón y estén siendo pulsados, y además tengan el foco.
    • :first-child: Selecciona todos los elementos que sean el primer hijo de su padre. Esto es útil por ejemplo con los <li> de las listas, porque si queremos que el primer elemento de la lista tenga un estilo diferente, en el css ponemos li:first-child . Así el primer elemento de la lista tendrá los estilos que queramos.
    • :last-child: Selecciona todos los elementos que sean el último hijo de su padre. Esto es útil por ejemplo con los <li> de las listas, porque si queremos que el último elemento de la lista tenga un estilo diferente, en el css ponemos li:last-child . Así el último elemento de la lista tendrá los estilos que queramos.
    • :nth-child(n): Selecciona todos los elementos que sean el n-ésimo hijo de su padre. Por ejemplo, :nth-child(2) selecciona todos los elementos que sean el segundo hijo de su padre.
    • :nth-last-child(n): Selecciona todos los elementos que sean el n-ésimo hijo de su padre, empezando desde el final. Por ejemplo, :nth-last-child(2) selecciona todos los elementos que sean el segundo hijo de su padre, empezando desde el final.
    • :nth-of-type(n): Selecciona todos los elementos que sean el n-ésimo hijo de su padre, del mismo tipo. Por ejemplo, :nth-of-type(2) selecciona todos los elementos que sean el segundo hijo de su padre, del mismo tipo.
    • :nth-last-of-type(n): Selecciona todos los elementos que sean el n-ésimo hijo de su padre, del mismo tipo, empezando desde el final. Por ejemplo, :nth-last-of-type(2) selecciona todos los elementos que sean el segundo hijo de su padre, del mismo tipo, empezando desde el final.
    • :first-of-type: Selecciona todos los elementos que sean el primer hijo de su padre, del mismo tipo.
    • :last-of-type: Selecciona todos los elementos que sean el último hijo de su padre, del mismo tipo.
    • :only-child: Selecciona todos los elementos que sean el único hijo de su padre.
    • :only-of-type: Selecciona todos los elementos que sean el único hijo de su padre, del mismo tipo.
    • :empty: Se selecciona todos los elementos que no tengan hijos.
  • Selector de id: Selecciona un elemento que tenga un id. Se utiliza el nombre del id. Por ejemplo, #id selecciona el elemento que tenga el id id. Esto es útil, porque si queremos que un elemento sea único, en el html ponemos <p id="unico"> y en el css ponemos #unico . Así ese elemento tendrá los estilos que queramos, y si queremos que otro elemento sea igual, le ponemos otra clase.
  • Selectores combinados: Seleccionan elementos que cumplan varias condiciones. Se utilizan los selectores que queramos, separados por un espacio. Por ejemplo, p .clase selecciona todos los elementos que tengan la clase clase y sean hijos de un párrafo. Esto es útil, porque si queremos que todos los botones que estén dentro de un párrafo sean iguales, en el html ponemos <p class="parrafo_que_quiero_cambiar"><button class="boton"> y en el css ponemos .parrafo_que_quiero_cambiar .boton . Así todos los botones que estén dentro de un párrafo con la clase parrafo_que_quiero_cambiar tendrán los mismos estilos, y queremos que un botón sea diferente, le ponemos otra clase.
  • Selector combinado de primer nivel: Seleccionan elementos que cumplan varias condiciones, pero solo si están en el primer nivel. Se utilizan los selectores que queramos, separados por un >. Por ejemplo, p > .clase selecciona todos los elementos que tengan la clase clase y sean hijos directos de un párrafo. Esto es útil, porque si queremos que todos los botones que estén dentro de un párrafo sean iguales, en el html ponemos <p class="parrafo_que_quiero_cambiar"><button class="boton"> y en el css ponemos .parrafo_que_quiero_cambiar > .boton . Así todos los botones que estén dentro de un párrafo con la clase parrafo_que_quiero_cambiar tendrán los mismos estilos, y queremos que un botón sea diferente, le ponemos otra clase.
  • Selector combinado de hermanos: Seleccionan elementos que cumplan varias condiciones, pero solo si están en el mismo nivel. Se utilizan los selectores que queramos, separados por un ~. Por ejemplo, p ~ .clase selecciona todos los elementos que tengan la clase clase y estén en el mismo nivel que un párrafo. Esto es útil, porque si queremos que todos los botones que estén en el mismo nivel que un párrafo sean iguales, en el html ponemos <p class="parrafo_que_quiero_cambiar"></p><button class="boton"> y en el css ponemos .parrafo_que_quiero_cambiar ~ .boton . Así todos los botones que estén en el mismo nivel que un párrafo con la clase parrafo_que_quiero_cambiar tendrán los mismos estilos, y queremos que un botón sea diferente, le ponemos otra clase.
  • Selector combinado de hermanos adyacentes: Seleccionan elementos que cumplan varias condiciones, pero solo si están en el mismo nivel y son adyacentes. Se utilizan los selectores que queramos, separados por un +. Por ejemplo, p + .clase selecciona todos los elementos que tengan la clase clase y estén en el mismo nivel y sean adyacentes a un párrafo. Esto es útil, porque si queremos que todos los botones que estén en el mismo nivel y sean adyacentes a un párrafo sean iguales, en el html ponemos <p class="parrafo_que_quiero_cambiar"></p><button class="boton"> y en el css ponemos .parrafo_que_quiero_cambiar + .boton . Así todos los botones que estén en el mismo nivel y sean adyacentes a un párrafo con la clase parrafo_que_quiero_cambiar tendrán los mismos estilos, y queremos que un botón sea diferente, le ponemos otra clase.

Lo normal es utilizar el selector de clase, porque así podemos reutilizar los estilos.

Estiloslink image 3

Colorlink image 4

El color se puede poner de varias formas:

  • Nombre: Se puede poner el nombre del color. Por ejemplo, red es rojo.

  • Hexadecimal: Se puede poner el color en hexadecimal. Por ejemplo, #ff0000 es rojo.

    Si se quiere añadir transparencia, se puede poner #ff000080, que es rojo con 50% de transparencia.

    Si solo se ponen 3 números, se repiten. Por ejemplo, #f10 es lo mismo que #ff1100. Si se quiere añadir transparencia, se puede poner #f108, que es lo mismo que #ff110088.

  • RGB: Se puede poner el color en RGB. Por ejemplo, rgb(255, 0, 0) es rojo.

    Si se quiere añadir transparencia, se puede poner rgb(255 0 0 / 0.5), que es rojo con 50% de transparencia. También se poner la transparencia en porcentaje, rgb(255 0 0 / 50%). Puedes encontrar la transparencia de una forma legacy con rgba(255, 0, 0, 0.5), que es rojo con 50% de transparencia, pero lo mejor es utilizar la forma moderna.

  • HSL: Se puede poner el color en HSL. Por ejemplo, hsl(0, 100%, 50%) es rojo.

  • OKLCH: Se puede poner el color en OKLCH. Por ejemplo, oklch(0 100% 50%) es rojo.

En HSL y OKLCH hay más escala de colores que en RGB, por lo que si necesitas más colores, es mejor utilizar HSL o OKLCH.

También se puede añadir la transparencia añadiendo la declaración color:transparent.

Current Colorlink image 5

Hay un valor de color que es currentColor, que es el color actual. Por ejemplo, si tenemos un texto y configuramos su color a rojo, y luego a este texto le añadimos un borde, si ponemos border: 1px solid currentColor;, el borde será rojo.

p {
          color: red;
          border: 1px solid currentColor;
      }
      

Herencialink image 6

Cuando se pone un estilo a un elemento, este estilo se hereda a los elementos hijos. Por ejemplo, si tenemos un div con un texto, y le ponemos el color rojo al div, el texto también será rojo.

<div>
          <p>Texto</p>
      </div>
      
div {
          color: red;
      }
      

Al hacer esto, el texto será rojo.

Podemos indicar en el hijo qué estilos se heredan, por ejemplo supongamos que tenemos un padre y un hijo

<div class="padre">
          <p class="hijo">Texto</p>
      </div>
      
.padre {
          color: red;
      }
      
      .hijo {
          color: inherit;
      }
      

Al hacer esto, el texto será rojo, porque el hijo hereda el color del padre.

Las posibles opciones son:

  • inherit: Hereda el estilo del padre.
  • initial: Pone el estilo por defecto.
  • unset: Resetea el estilo
  • revert: Revierte el estilo

No todos los estilos se herean, por ejemplo, el background no se hereda. Para no poner todos los estilos que se heredan, una forma de saberlo es llendo a MDN y mirando si el estilo tiene la propiedad Inherited a yes (Dentro de Formal definition).

Fuenteslink image 7

A la hora de cargar las fuentes, se pueden cargar de varias formas:

  • Local: Se puede cargar una fuente local. Por ejemplo, font-family: Arial; carga la fuente Arial.
  • URL: Se puede cargar una fuente de una URL. Por ejemplo, font-family: url(https://fonts.googleapis.com/css2?family=Roboto); carga la fuente Roboto de Google Fonts.
  • Genérica: Se puede cargar una fuente genérica. Por ejemplo, font-family: sans-serif; carga una fuente sin serifa. Esta fuente depende del sistema operativo, por lo que en Windows será Arial, en Mac será Helvetica y en Linux será DejaVu Sans.

Se pueden cargar varias fuentes, y si una no está disponible, se carga la siguiente. Por ejemplo, font-family: Arial, sans-serif; carga Arial, y si no está disponible, carga una fuente sin serifa.

También se puede cargar una fuente con varios estilos. Por ejemplo, font-family: Arial, sans-serif; font-weight: 700; carga Arial en negrita, y si no está disponible, carga una fuente sin serifa en negrita.

Como sans-serif es una fuente genérica, lo ideal es siempre ponerla la última, para que si no está disponible la fuente que queremos, se cargue la genérica.

p {
          font-family: url(https://fonts.googleapis.com/css2?family=Roboto), url(https://fonts.googleapis.com/css2?family=Roboto+Slab), Ubuntu, sans-serif;
      }
      

Border y Outlinelink image 8

Podemos ponerle un borde a un elemento con border: 1px solid red;. Esto pone un borde de 1px de grosor, sólido y rojo.

Si queremos poner un contorno, podemos utilizar outline: 1px solid red;. Esto pone un contorno de 1px de grosor, sólido y rojo.

La diferencia entre border y outline es que border ocupa espacio, y outline no. Por ejemplo, si tenemos un div con un texto, y le ponemos un borde, el texto se moverá para que el borde se vea. Si ponemos un contorno, el texto no se moverá, porque el contorno no ocupa espacio. Esto se puede apreciar si cambiamos el estilo en la pseudo-clase :hover. Si ponemos un borde, cuando pasemos el ratón por encima, el texto se moverá, pero si ponemos un contorno, el texto no se moverá.

Cascadalink image 9

La cascada es el orden en el que se aplican los estilos. El orden es:

  1. Estilos del usuario: Son los estilos que el usuario ha configurado. Por ejemplo, si el usuario tiene configurado que el texto sea de color rojo, el texto será rojo.
  2. Estilos del autor: Son los estilos que el autor ha configurado. Por ejemplo, si el autor ha configurado que el texto sea de color azul, el texto será azul.
  3. Estilos del navegador: Son los estilos del navegador. Por ejemplo, si el navegador tiene configurado que el texto sea de color verde, el texto será verde.

Prevalecen los estilos del usuario sobre los del autor, y los del autor sobre los del navegador.

Pero dentro de los estilos del autor, prevalecen los estilos que estén más abajo en el código. Por ejemplo, si tenemos un div con un texto, y le ponemos el color rojo, y luego le ponemos el color azul, el texto será azul.

<div>
          <p>Texto</p>
      </div>
      
div {
          color: red;
      }
      
      div {
          color: blue;
      }
      

En este ejemplo, el texto será azul. Se sobreescribe el color rojo con el color azul.

Fallbacklink image 10

Uno de los beneficios de la cascada es que podemos poner un estilo muy nuevo, pero por si el navegador que esté usando el usuario no lo soporta, podemos poner un estilo más antiguo antes por si acaso. Por ejemplo, estilar el color con oklch es algo nuevo, que puede que el navegador que el usuario esté usando no lo soporte, por lo que podemos poner un estilo más antiguo antes por si acaso.

p {
          color: rgb(255, 0, 0);
          color: oklch(0 100% 50%);
      }
      

De esta manera el navegador primero intentará estilar con oklch, y si no puede, estilará con rgb.

Especificidadlink image 11

Puede ser que un elemento html tenga varias formas de referirnos a él. Por ejemplo

<p class="clase" id="id">Texto</p>
      
p {
          color: red;
      }
      
      .clase {
          color: blue;
      }
      
      #id {
          color: green;
      }
      

En este ejemplo, el texto será verde. Esto es porque el selector de id tiene más especificidad que el selector de clase, y el selector de clase tiene más especificidad que el selector de tipo. Por lo que el selector de id sobreescribe al selector de clase, y el selector de clase sobreescribe al selector de tipo.

Si en el css tuviésemos

p {
          color: red;
      }
      
      p.clase {
          color: blue;
      }
      

El texto sería azul. Esto es porque el selector de clase tiene más especificidad que el selector de tipo, por lo que el selector de clase sobreescribe al selector de tipo.

Los estilos en línea tienen más especificidad que los estilos del autor. Por ejemplo

<p style="color: red;">Texto</p>
      
p {
          color: blue;
      }
      

En este ejemplo, el texto será rojo. Esto es porque el estilo en línea tiene más especificidad que el estilo del autor.

Si se pone !important al final de la declaración, esta declaración tendrá más especificidad que cualquier otra. Por ejemplo

<p class="clase" id="id">Texto</p>
      
p {
          color: red;
      }
      
      .clase {
          color: blue;
      }
      
      #id {
          color: green;
      }
      
      p.clase {
          color: yellow !important;
      }
      

En este ejemplo, el texto será amarillo. Esto es porque la declaración con !important tiene más especificidad que cualquier otra.

Unidadeslink image 12

Unidades de longitudlink image 13

Unidades absolutaslink image 14

Si queremos poner un tamaño fijo, podemos utilizar unidades absolutas. Por ejemplo, px es un píxel, cm es un centímetro, mm es un milímetro, in es una pulgada, pt es un punto, pc es una pica.

Unidades relativaslink image 15

Sin embargo, si queremos que el tamaño sea relativo, podemos utilizar unidades relativas. Por ejemplo, em es el tamaño de la fuente, rem es el tamaño de la fuente del elemento raíz, vw es el ancho de la ventana, vh es el alto de la ventana, vmin es el ancho o el alto de la ventana, dependiendo de cuál sea menor, vmax es el ancho o el alto de la ventana, dependiendo de cuál sea mayor, ch es el ancho de un carácter, ex es la altura de una x, fr es una fracción del espacio disponible.

Modelo de la cajalink image 16

En html todo son cajas, pero hay dos tipos de maneras de ver las cajas, inline y block. Por ejemplo, los <span> son inline, y los <div> son block.

Cajas inlinelink image 17

Cuando el elemento es inline, el ancho y el alto no se pueden configurar, y el elemento se comporta como si fuese texto. Por ejemplo, si tenemos un span con un texto, y le ponemos un ancho y un alto, el ancho y el alto no se aplicarán, y el elemento se comportará como si fuese texto.

<span>Texto</span>
      
span {
          width: 100px;
          height: 100px;
      }
      

En este ejemplo, el ancho y el alto no se aplicarán, y el elemento se comportará como si fuese texto.

Además, cuando el elemento es inline, si se ponen varios elementos juntos en el html, estos elementos se mostrarán juntos. Por ejemplo, si tenemos varios span con un texto, y los ponemos juntos en el html, estos elementos se mostrarán juntos.

<span>Texto</span>
      <span>Texto</span>
      <span>Texto</span>
      

En este ejemplo, los elementos se mostrarán juntos ==> TextoTextoTexto.

Pero si queremos que los elementos se muestren en diferentes líneas, podemos utilizar display: block;. Por ejemplo, si tenemos varios span con un texto, y les ponemos display: block;, estos elementos se mostrarán en diferentes líneas.

<span>Texto</span>
      <span>Texto</span>
      <span>Texto</span>
      
span {
          display: block;
      }
      

En este ejemplo, los elementos se mostrarán en diferentes líneas

Texto

Texto

Texto

Cajas blocklink image 18

Cuanod el elemento es block, el ancho y el alto se pueden configurar, y el elemento se comporta como si fuese un bloque. Por ejemplo, si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
      }
      

En este ejemplo, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

Además, cuando el elemento es block, si se ponen varios elementos juntos en el html, estos elementos se mostrarán uno debajo del otro. Por ejemplo, si tenemos varios div con un texto, y los ponemos juntos en el html, estos elementos se mostrarán uno debajo del otro.

<div>Texto</div>
      <div>Texto</div>
      <div>Texto</div>
      

En este ejemplo, los elementos se mostrarán uno debajo del otro

Texto

Texto

Texto

Pero si queremos que los elementos se muestren en la misma línea, podemos utilizar display: inline;. Por ejemplo, si tenemos varios div con un texto, y les ponemos display: inline;, estos elementos se mostrarán en la misma línea.

<div>Texto</div>
      <div>Texto</div>
      <div>Texto</div>
      
div {
          display: inline;
      }
      

En este ejemplo, los elementos se mostrarán en la misma línea ==> TextoTextoTexto.

Margin, Border, Padding y Contentlink image 19

Ahora que sabemos en en html todo son cajas, podemos ver que cada caja tiene 4 partes:

  • Margin: Es el espacio que hay entre la caja y las demás cajas.
  • Border: Es el borde de la caja.
  • Padding: Es el espacio que hay entre el borde y el contenido.
  • Content: Es el contenido de la caja.

Margin, Border, Padding y Content

Todas estas propiedades se pueden configurar. Por ejemplo, si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          margin: 10px;
          border: 10px solid red;
          padding: 10px;
      }
      

Como son propiedades de tamaño, se pueden poner unidades de longitud. Por ejemplo:

  • Si queremos que el margen sea de 10 píxeles, ponemos margin: 10px;.
  • Si queremos que solo sea el margen izquierdo, ponemos margin-left: 10px;.
  • Si queremos que solo sea el margen derecho, ponemos margin-right: 10px;.
  • Si queremos que solo sea el margen superior, ponemos margin-top: 10px;.
  • Si queremos que solo sea el margen inferior, ponemos margin-bottom: 10px;.
  • Si queremos que cada margen sea de un tamaño, ponemos margin: 10px 20px 30px 40px;. El orden es arriba, derecha, abajo, izquierda, como si fuesen las agujas del reloj.
  • Si queremos cambiar los tamaños en el eje horizontal y vertical, ponemos margin: 10px 20px;. El orden es arriba y abajo (10px), izquierda y derecha (20px).

Tamaño de la caja al cambiar el paddinglink image 20

Si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px.

Pero si ahora le aplicamos un padding de 10px, el ancho y el alto se mantendrán, pero el tamaño de la caja será de 120px, porque el padding se añade al ancho y al alto.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          padding: 10px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px, pero el tamaño de la caja será de 120px.

Tamaño de la caja al cambiar el borderlink image 21

Si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px.

Pero si ahora le aplicamos un border de 10px, el ancho y el alto se mantendrán, pero el tamaño de la caja será de 120px, porque el border se añade al ancho y al alto.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          border: 10px solid red;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px, pero el tamaño de la caja será de 120px.

Tamaño de la caja al cambiar el marginlink image 22

En el caso de los márgenes, el tamaño de la caja no cambia, pero el espacio entre las cajas sí. Por ejemplo, si tenemos dos div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      <div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
      }
      

De esta manera los div tendrán un ancho y un alto de 100px.

Pero si ahora le aplicamos un margin de 10px, el ancho y el alto se mantendrán, pero el espacio entre los div será de 20px, porque el margin se añade al espacio entre los div.

<div>Texto</div>
      <div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          margin: 10px;
      }
      

De esta manera los div tendrán un ancho y un alto de 100px, pero el espacio entre los div será de 20px.

Tamaño de la cajalink image 23

Por tanto lo que ocupa la caja es:

  • Ancho: width + padding + border.
  • Alto: height + padding + border.

El margen no cuenta, porque el margen es el espacio entre las cajas.

Box-sizinglink image 24

Por defecto, la propiedad box-sizing está configurada a content-box. Esto significa que el ancho y el alto no incluyen el padding ni el border. Por ejemplo, si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px.

Pero si ahora le aplicamos un padding de 10px, el ancho y el alto se mantendrán, pero el tamaño de la caja será de 120px, porque el padding se añade al ancho y al alto.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          padding: 10px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px, pero el tamaño de la caja será de 120px.

Si cambiaramos la propiedad box-sizing a border-box, el ancho y el alto incluirían el padding y el border. Por ejemplo, si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          box-sizing: border-box;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px.

Pero si ahora le aplicamos un padding de 10px, el ancho y el alto se mantendrán, y el tamaño de la caja también será de 100px, porque el padding no se añade al ancho y al alto.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          box-sizing: border-box;
          padding: 10px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px, y el tamaño de la caja también será de 100px.

Hay que tener en cuenta que cuando se cambia la propiedad box-sizing a border-box, el ancho y el alto incluyen el padding y el border, por lo que no podemos poner un ancho y un alto menor que el padding y el border. Por ejemplo, si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          box-sizing: border-box;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px.

Pero si ahora le aplicamos un padding de 110px, el ancho y el alto se mantendrán, pero el tamaño de la caja será de 220px, porque el padding se añade al ancho y al alto.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
          box-sizing: border-box;
          padding: 110px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px, pero el tamaño de la caja será de 220px.

Overflowlink image 25

Uno de los memes más famosos de CSS es el siguiente

CSS is awesome

Y esto se produce cuando el tamaño del contenido es mayor que el tamaño de la caja. Por ejemplo, si tenemos un div con un texto, y le ponemos un ancho y un alto, el ancho y el alto se aplicarán, y el elemento se comportará como si fuese un bloque.

<div>Texto</div>
      
div {
          width: 100px;
          height: 100px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px.

Pero si ahora le aplicamos un texto muy largo, el texto se saldrá de la caja, porque el tamaño del contenido es mayor que el tamaño de la caja.

<div>Texto muy largo</div>
      
div {
          width: 100px;
          height: 100px;
      }
      

De esta manera el div tendrá un ancho y un alto de 100px, pero el texto se saldrá de la caja.

Esto ocurreo porque en CSS la propiedad overflow está configurada a visible. Esto significa que el contenido se puede salir de la caja. Pero tenemos otras opciones:

  • hidden: El contenido no se puede salir de la caja, y se corta.
  • scroll: El contenido no se puede salir de la caja, y se añade una barra de desplazamiento.
  • auto: El contenido no se puede salir de la caja, y se añade una barra de desplazamiento si es necesario. En este caso depende del dispositivo, porque si el dispositivo tiene una barra de desplazamiento, se añadirá una barra de desplazamiento, y si el dispositivo no tiene una barra de desplazamiento, no se añadirá una barra de desplazamiento.

Entre scroll y auto el recomendado es auto, porque si el dispositivo tiene una barra de desplazamiento, se añadirá una barra de desplazamiento, y si el dispositivo no tiene una barra de desplazamiento, no se añadirá una barra de desplazamiento.

aoverflow

Overflow hiddenlink image 26

En el caso de elegir hidden, el contenido no se puede salir de la caja, y se corta. En este caso tenemos la propiedad text-overlow, que nos permite configurar qué se hace con el texto que se sale de la caja. Las opciones son:

  • clip: El texto se corta.
  • ellipsis: El texto se corta, y se añade ... al final del texto.

En el futuro se podrá poner un símbolo personalizado, pero de momento no se puede.

Estilado de la barralink image 27

En caso de tener desbordamientos se puede estilar la barra, pero es recomendable no estilar la barra de la página y solo hacerlo en barras de cajas internas. Por ejemplo, si en la página hay un índice en el lateral, y queremos cambiar el tamaño y el color de la barra para que se vea mejor, podemos hacerlo.

En scrollbar.app tenemos un editor para poder estilar la barra y obtener el código necesario

Positionlink image 28

En html los elementos se van apilando, se posicionan por defecto de manera estática, esto es porque por defecto en CSS tienen el atributo position con el valor static. Esto significa que el elemento se posiciona de manera estática, y no se puede mover. Los posibles valores son

  • static: El elemento se posiciona de manera estática, y no se puede mover.
  • relative: El elemento se posiciona de manera relativa, y se puede mover.
  • absolute: El elemento se posiciona de manera absoluta, y se puede mover.
  • fixed: El elemento se posiciona de manera fija, y se puede mover.
  • sticky: El elemento se posiciona de manera pegajosa, y se puede mover.

Position

Position relativelink image 29

Cuando queremos que la posición de un elemento sea relativa a otro usamos position: relative;. Pero hay que poner position: relative; en el padre, y position: absolute; en el hijo. Por ejemplo, si tenemos un div con un texto, y queremos que el texto esté en la esquina superior derecha del div, podemos hacerlo.

<div>
          <p>Texto</p>
      </div>
      
div {
          position: relative;
      }
      
      p {
          position: absolute;
          top: 0;
          right: 50px;
      }
      

De esta manera el texto estará en la esquina superior derecha del div.

Position absolutelink image 30

Cuando el elemento es absolute, el elemento se posiciona de manera absoluta al primer elemento padre que no sea static. En el ejemplo anteriore hemos visto que si tenemos un div con un texto, y queremos que el texto esté en la esquina superior derecha del div, podemos hacerlo.

<div>
          <p>Texto</p>
      </div>
      
div {
          position: relative;
      }
      
      p {
          position: absolute;
          top: 0;
          right: 50px;
      }
      

En este ejemplo, el div tiene position: relative;, por lo que el p se posiciona de manera absoluta al div, en la esquina superior derecha.

En caso de que no haya ningún elemento padre que no sea static, el elemento se posiciona de manera absoluta al body, es decir, a la página.

<p>Texto</p>
      
p {
          position: absolute;
          top: 0;
          right: 50px;
      }
      

En este ejemplo, el p no tiene ningún elemento padre que no sea static, por lo que el p se posiciona de manera absoluta al body. Es decir en la parte superior derecha de la página.

Gracias a las propiedades relative y absolute podemos centrar un div horizontalmente y verticalmente. Por ejemplo, si tenemos un div con un texto, y queremos que el texto esté centrado horizontalmente y verticalmente, podemos hacerlo.

<div>
          <p>Texto</p>
      </div>
      
div {
          position: relative;
      }
      
      p {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          margin: auto;
      }
      

En este ejemplo, el div tiene position: relative;, por lo que el p se posiciona de manera absoluta al div, en la esquina superior derecha. Además, el p tiene top: 0;, right: 0;, bottom: 0; y left: 0;, por lo que el p ocupa todo el div. Por último, el p tiene margin: auto;, por lo que el p se centra horizontalmente y verticalmente.

Esta no es la mejor manera de centrar el contenido en un div, pero puede ser muy útil en algunos casos, como por ejemplo en un modal.

Position fixedlink image 31

Cuando el elemento es fixed, el elemento se posiciona de manera fija a la ventana. Es parecido a absolute, pero en vez de posicionarse al primer elemento padre que no sea static, se posiciona a la ventana. Además, si la ventana se mueve, el elemento se mueve con ella, es decir, que si hacemos scroll, el elemento siempre estará en la misma posición.

Por ejemplo, si tenemos un div con un texto, y queremos que el texto esté en la esquina superior derecha de la ventana, podemos hacerlo.

<div>
          <p>Texto</p>
      </div>
      
p {
          position: fixed;
          top: 0;
          right: 50px;
      }
      

En este ejemplo, el p se posiciona de manera fija a la ventana, en la esquina superior derecha y al hacer scroll, el p siempre estará en la misma posición.

Position stickylink image 32

Cuando el elemento es sticky, el elemento se posiciona de manera pegajosa al primer elemento padre que no sea static.

Es parecido a relative, pero cuando el elemento llega a la parte superior de la ventana, el elemento se posiciona de manera fija a la ventana. Además, si la ventana se mueve, el elemento se mueve con ella, es decir, que si hacemos scroll, el elemento siempre estará en la misma posición.

Por ejemplo, si tenemos un div con un texto, y queremos que el texto esté en la esquina superior derecha del div, podemos hacerlo.

<div>
          <p>Texto</p>
      </div>
      
div {
          position: relative;
      }
      
      p {
          position: sticky;
          top: 0;
          right: 50px;
      }
      

En este ejemplo, el div tiene position: relative;, por lo que el p se posiciona de manera relativa al div, en la esquina superior derecha. Además, el p tiene top: 0;, por lo que el p se posiciona de manera pegajosa al div. Es decir, que cuando el p llega a la parte superior de la ventana, el p se posiciona de manera fija a la ventana.

sticky

Z-indexlink image 33

Como hemos visto al cambiar el position de un elemento, el elemento se posiciona encima de los demás elementos. Por lo que necesitamos tener control de qué elemento está o se verá por encima de los demás. Para ello tenemos la propiedad z-index. Por defecto, todos los elementos tienen z-index: auto;, pero podemos cambiarlo. Por ejemplo, si tenemos un div con un texto, y queremos que el texto esté encima del div, podemos hacerlo.

<div>
          <p>Texto</p>
      </div>
      
div {
          position: relative;
          z-index: 0;
      }
      
      p {
          position: absolute;
          top: 0;
          right: 50px;
          z-index: 1;
      }
      

En este ejemplo, el div tiene position: relative; y z-index: 0;, por lo que el div se posiciona de manera relativa al div, y el div tiene un z-index de 0. Además, el p tiene position: absolute;, top: 0;, right: 50px; y z-index: 1;, por lo que el p se posiciona de manera absoluta al div, en la esquina superior derecha, y el p tiene un z-index de 1. Por lo que el p estará encima del div.

Si no se indica el z-index, los hijos tienen un z-index mayor que los padres. Pero por ejemplo, en el caso de position: sticky;, el z-index del elemento hijo es mayor que el z-index del de su padre, pero a la hora de hacer scroll, si en algún momento coincide el hijo con otro padre, el otro padre estará por encima.

Si queremos que ese hijo se vea por encima de los otros padres podemos controlarlo con el z-index.

En el curso de CSS de Goolge se puede ver muy bien cómo funciona el z-index.

Flexbox y Gridlink image 34

Hay dos maneras de hacer layouts en CSS, con flexbox y con grid. Flexbox es más antiguo, y grid es más nuevo. Flexbox es unidimensional, y grid es bidimensional. Flexbox es para layouts sencillos, y grid es para layouts complejos.

Flexboxlink image 35

Como hemos visto, tenemos contenedores que tienen display: block;, y contenedores que tienen display: inline;. Los primeros se muestran en diferentes líneas, y los segundos se muestran en la misma línea. Por lo que si tenemos varios divs se verán uno debajo del otro, y si tenemos varios spans se verán en la misma línea.

Pero si queremos que los divs se vean en la misma línea y además de manera flexible, podemos crear un contenedor padre que los contenga y hacer que el contenedor padre tenga display: flex;.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </div>
      
section {
          display: flex;
      }
      

De esta manera los divs se verán en la misma línea y además de manera flexible, es decir, si no caben en la misma línea, se pondrán en la siguiente línea.

Flex-directionlink image 36

Flexbox es uni-dimensional, por lo que solo se puede configurar una dirección. Por defecto, la propiedad flex-direction está configurada a row. Esto significa que los elementos se muestran en la misma línea. Pero podemos cambiarlo a column, para que los elementos se muestren en diferentes líneas.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
          flex-direction: column;
      }
      

De esta manera los divs se verán en diferentes líneas.

Esto es muy útil para hacer layouts responsive, porque podemos cambiar la dirección de los elementos dependiendo del tamaño de la pantalla.

Podemos además inidicar el sentido de la dirección, con flex-direction: row-reverse; o flex-direction: column-reverse;. Por ejemplo, si tenemos varios divs, y queremos que se muestren en la misma línea, pero en sentido contrario, podemos hacerlo.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
          flex-direction: row-reverse;
      }
      

De esta manera los divs se verán en la misma línea, pero en sentido contrario.

Esto es muy útil cuando queremos ordenar los elementos de manera inversa, por ejemplo, si tenemos un ul con una lista, y queremos que la lista se muestre en sentido contrario, de esta manera no hace falta programar nada y se puede hacer con CSS.

flex-direction

Directionlink image 37

Otra manera de indicar el sentido de la dirección es con la propiedad direction. Por defecto, la propiedad direction está configurada a ltr. Esto significa que el sentido de la dirección es de izquierda a derecha. Pero podemos cambiarlo a rtl, para que el sentido de la dirección sea de derecha a izquierda.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
          direction: rtl;
      }
      

direction

Flex-wraplink image 38

Cuando los elementos no caben en la misma línea, se ponen en la siguiente línea. Pero podemos cambiar este comportamiento con la propiedad flex-wrap. Por defecto, la propiedad flex-wrap está configurada a nowrap. Esto significa que los elementos no se pueden poner en la siguiente línea. Pero podemos cambiarlo a wrap, para que los elementos se puedan poner en la siguiente línea.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
          flex-wrap: wrap;
      }
      

De esta manera los divs se podrán poner en la siguiente línea.

flex-wrap

Flex-flowlink image 39

Una manera de configurar la dirección y el wrap de los elementos es con la propiedad flex-flow. Por defecto, la propiedad flex-flow está configurada a row nowrap. Esto significa que los elementos se muestran en la misma línea, y no se pueden poner en la siguiente línea. Pero podemos cambiarlo a row wrap, para que los elementos se muestren en la misma línea, y se puedan poner en la siguiente línea.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
          flex-flow: row wrap;
      }
      

De esta manera los divs se verán en la misma línea, y se podrán poner en la siguiente línea.

flex-flow

Flex-grow, Flex-shrink y Flex-basislink image 40

Podemos configurar el tamaño de los elementos con las propiedades flex-grow, flex-shrink y flex-basis.

  • flex-grow: Indica si el elemento puede crecer o no. Por defecto, la propiedad flex-grow está configurada a 0, lo que significa que el elemento no puede crecer. Pero podemos cambiarlo a 1, para que el elemento pueda crecer.
  • flex-shrink: Indica si el elemento puede encoger o no. Por defecto, la propiedad flex-shrink está configurada a 1, lo que significa que el elemento puede encoger. Pero podemos cambiarlo a 0, para que el elemento no pueda encoger.
  • flex-basis: Indica el tamaño del elemento. Por defecto, la propiedad flex-basis está configurada a auto, lo que significa que el elemento tiene un tamaño automático. Pero podemos cambiarlo a 100px, para que el elemento tenga un tamaño de 100px.

Por ejemplo, si tenemos varios divs, y queremos que el primer div tenga un tamaño de 100px, y los demás se repartan el espacio restante, podemos hacerlo.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
      }
      
      section div:first-child {
          flex-grow: 0;   /* Como por feecto está a 0, no hace falta ponerlo */
          flex-shrink: 0; /* Como por feecto está a 1, no hace falta ponerlo */
          flex-basis: 100px;
      }
      
      section div {
          flex-grow: 1;
          flex-shrink: 1;     /* Como por feecto está a 1, no hace falta ponerlo */
          flex-basis: auto;   /* Como por feecto está a auto, no hace falta ponerlo */
      }
      

De esta manera el primer div tendrá un tamaño de 100px, y los demás se repartirán el espacio restante.

Se pueden modificar los tres valores de una vez con la propiedad flex. Por ejemplo, si tenemos varios divs, y queremos que el primer div tenga un tamaño de 100px, y los demás se repartan el espacio restante, podemos hacerlo.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
      }
      
      section div:first-child {
          flex: 0 0 100px;
      }
      
      section div {
          flex: 1 1 auto;
      }
      

De esta manera el primer div tendrá un tamaño de 100px, y los demás se repartirán el espacio restante.

O también se puede modificar de una vez con flex: initial;, que es lo mismo que flex: 0 1 auto;. O con flex: auto;, que es lo mismo que flex: 1 1 auto;. O con flex: none;, que es lo mismo que flex: 0 0 auto;. O con flex: 1;, que es lo mismo que flex: 1 1 0%;.

Otra forma de modificar flex es poniendo números, que indicarán el espacio relativo del contenedor. Por ejemplo, si tenemos varios divs, y queremos que el primero tenga el doble de eespacio del segundo, y el segundo tenga el doble de espacio del tercero, podemos hacerlo.

<section>
          <div>Texto</div>
          <div>Texto</div>
          <div>Texto</div>
      </section>
      
section {
          display: flex;
      }
      
      section div:first-child {
          flex: 4;
      }
      
      section div:nth-child(2) {
          flex: 4;
      }
      
      section div:nth-child(3) {
          flex: 1;
      }
      

De esta manera el primer div tendrá el doble de espacio del segundo, y el segundo tendrá el doble de espacio del tercero.

Orderlink image 41

Podemos ordenar los elementos dentro de un contenedor con la propiedad order. Por defecto, la propiedad order está configurada a 0. Pero podemos cambiarlo a 1, para que el elemento se ponga después de los elementos que tengan order: 0;. O podemos cambiarlo a -1, para que el elemento se ponga antes de los elementos que tengan order: 0;.

Es como z-index, pero para el orden de los elementos. Cuanto mayor sea el order, más tarde se pondrá el elemento. Por ejemplo, si tenemos varios divs, y queremos que el primer div se ponga después del segundo, podemos hacerlo.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: flex;
      }
      
      section div:first-child {
          order: 1;
      }
      
      section div {
          order: 0;
      }
      

El resultado será

Texto 2

Texto 3

Texto 1

order

Justify-contentlink image 42

Como Flexbox es uni-dimensional, podemos configurar el justificado de los elementos del contenedor en el eje del Flebox del contenedor. Es decir, si el eje del Flexbox del contenedor es horizontal, podemos configurar el justificado de los elementos del contenedor en el eje horizontal. Y si el eje del Flexbox del contenedor es vertical, podemos configurar el justificado de los elementos del contenedor en el eje vertical.

Los posibles valores son:

  • flex-start: Los elementos se justifican al principio del eje del Flexbox del contenedor.
  • flex-end: Los elementos se justifican al final del eje del Flexbox del contenedor.
  • center: Los elementos se justifican en el centro del eje del Flexbox del contenedor.
  • space-between: Los elementos se justifican con el mismo espacio entre ellos. A los laterales del primer y último elemento no se deja espacio.
  • space-around: Los elementos se justifican con el mismo espacio alrededor de ellos.
  • space-evenly: Los elementos se justifican con el mismo espacio entre ellos y alrededor de ellos. Es decir, es similar a space-between, pero a los laterales del primer y último elemento se deja espacio. El espacio en los laterales es el mismo que el espacio entre los elementos

justify-content

Gaplink image 43

Supon que tenemos varios elementos dentro de un contenedor y hemos puesto justify-content: center;. Esto hará que los elementos estén centrados en el contenedor, pero pegados entre ellos. Si queremos que haya un espacio entre los elementos, podemos poner gap: 10px;. De esta manera habrá un espacio de 10px entre los elementos.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: flex;
          justify-content: center;
          gap: 10px;
      }
      
image css 1

Align-itemslink image 44

Hasta ahora hemos visto como distribuir los elementos en el eje principal del Flexbox. Pero, ¿qué pasa con el eje secundario? Para ello tenemos la propiedad align-items. Esta propiedad nos permite alinear los elementos en el eje secundario del Flexbox.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: flex;
          align-items: center;
      }
      

align-items

Align-contentlink image 45

Con align-content podemos alinear el contenido del contenedor en el eje secundario. Esta propiedad es similar a align-items, pero en vez de alinear los elementos, alinea el contenido del contenedor.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: flex;
          align-content: center;
          flex-wrap: wrap;
          height: 200px;
      }
      

align-content

Align-content vs Align-itemslink image 46

Como puede haber confusión entre align-content y align-items, vamos a ver un ejemplo para ver la diferencia entre ambas propiedades.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
          <div>Texto 4</div>
          <div>Texto 5</div>
          <div>Texto 6</div>
          <div>Texto 7</div>
          <div>Texto 8</div>
          <div>Texto 9</div>
      </section>
      
section {
          display: flex;
          align-items: center;
          align-content: center;
          flex-wrap: wrap;
          height: 200px;
      }
      

Con align-items alineamos los elementos en el eje secundario, mientras que con align-content alineamos el contenido del contenedor en el eje secundario. Es decir, con align-items alineamos los elementos entre ellos, mientras que con align-content alineamos el contenido del contenedor. En el ejemplo anterior podemos ver que con align-items los elementos se alinean entre ellos, mientras que con align-content el contenido del contenedor se alinea en el eje secundario.

Align-selflink image 47

En ocasiones necesitamos alinear un elemento en el eje secundario de forma diferente al resto de elementos. Para ello tenemos la propiedad align-self. Esta propiedad nos permite alinear un elemento en el eje secundario de forma diferente al resto de elementos.

Hasta ahora alineábamos los elementos en el padre, pero con align-self podemos alinear un elemento en el eje secundario de forma diferente al resto de elementos.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: flex;
          align-items: center;
      }
      
      section div:nth-child(2) {
          align-self: flex-end;
      }
      

align-self

Práctica de Flexboxlink image 48

Un buen recurso para practicar Flexbox es Flexbox Froggy.

Gridlink image 49

Si necesitamos crear un layout más complejo, podemos utilizar Grid. Grid es un sistema de rejilla bidimensional que nos permite crear layouts más complejos que con Flexbox.

grid

Grid containerlink image 50

Vamos a ver un ejemplo de cómo maquetar con Grid. Para ello vamos a utilizar la siguiente estructura HTML.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
          <div>Texto 4</div>
          <div>Texto 5</div>
          <div>Texto 6</div>
          <div>Texto 7</div>
          <div>Texto 8</div>
          <div>Texto 9</div>
      </section>
      

Para crear un Grid necesitamos crear un contenedor con la propiedad display: grid, recordemos que por defecto los contenedores tienen por defecto display:block. Este contenedor se conoce como Grid container.

section {
          display: grid;
      }
      

Este código nos creará un Grid con una sola columna y tantas filas como elementos tengamos.

Si queremos cambiar el número de columnas, podemos utilizar la propiedad grid-template-columns. Esta propiedad nos permite definir el número de columnas que tendrá nuestro Grid. Para definir el número de columnas podemos utilizar unidades de medida como px, em, rem, fr, etc.

Se van a crear tantas columnas como unidades de medida definamos. En el siguiente ejemplo vamos a crear 3 columnas de 100px cada una.

section {
          display: grid;
          grid-template-columns: 100px 100px 100px;
      }
      

Con este ejemplo hemos creado un Grid con 3 columnas de 100px cada una.

Podemos definir el ancho de una de las columnas con auto y el resto con una medida, de esta manera la columna con auto se adaptará al contenido, mientras que el resto de columnas tendrán el ancho que le hayamos definido.

Al poner auto será el navegador el que decida el ancho de la columna en función del espacio que haya en el contenedor y del espacio que ocupe el contenido de la columna.

section {
          display: grid;
          grid-template-columns: auto 100px 100px;
      }
      

La primera columna se adaptará al contenido, mientras que las otras dos tendrán un ancho de 100px.

Si definimos dos columnas con auto, el navegador repartirá el espacio entre las dos columnas, pero no tiene por qué ser el mismo espacio para cada columna, ya que como hemos dicho el espacio dependerá del espacio del contenedor y del espacio del contenido.

section {
          display: grid;
          grid-template-columns: auto auto 100px;
      }
      

En este ejemplo las dos primeras columnas se adaptarán al contenido, mientras que la tercera tendrá un ancho de 100px.

Fractionlink image 51

Hay una unidad de medida que solo existe en Grid y es fr. Esta unidad de medida nos permite definir el ancho de las columnas en función del espacio disponible en el contenedor.

section {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr;
      }
      

En este ejemplo las tres columnas tendrán el mismo ancho, ya que el espacio disponible en el contenedor se repartirá entre las tres columnas.

section {
          display: grid;
          grid-template-columns: 1fr 2fr 1fr;
      }
      

En este ejemplo la segunda columna tendrá el doble de ancho que las otras dos, ya que el espacio disponible en el contenedor se repartirá entre las tres columnas, pero la segunda columna tendrá el doble de espacio que las otras dos.

Podemos hacer lo mismo con las filas, para ello utilizamos la propiedad grid-template-rows.

section {
          display: grid;
          grid-template-columns: 1fr 2fr 1fr;
          grid-template-rows: 1fr 2fr 1fr;
      }
      

Cuadrícula vacíalink image 52

Hemos dicho que podemos dividir el Grid en columnas y filas, para ello ponemos tantas unidades de medida como columnas o filas queramos. Pero qué pasa si ponemos más unidades de medida de las que necesitamos.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
          <div>Texto 4</div>
          <div>Texto 5</div>
          <div>Texto 6</div>
          <div>Texto 7</div>
          <div>Texto 8</div>
          <div>Texto 9</div>
      </section>
      
section {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr 1fr;
          grid-template-rows: 1fr 1fr 1fr 1fr;
      }
      

En este ejemplo se creará un Grid con 4 columnas y 4 filas, pero solo tenemos 9 elementos, mientras que nosotros hemos creado una cuadrícula de 16 elementos. ¿Qué pasa con los 7 elementos que nos sobran? El navegador los crea vacíos.

Grid-auto-rowslink image 53

Si a la hora de crear el Grid solo definimos el valor de grid-template-columns, el navegador creará las filas necesarias para las columnas que hemos definido, pero las creará con el tamaño por defecto, es decir, con el tamaño del contenido.

Si queremos definir el tamaño de las filas podemos usar la propiedad grid-auto-rows. Esta propiedad nos permite definir el tamaño de las filas que se crean por defecto.

section {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr 1fr;
          grid-auto-rows: 100px;
      }
      

En este ejemplo se creará un Grid con 4 columnas y tantas filas como elementos tengamos, pero el tamaño de las filas será de 100px.

Supongamos que también hemos definido grid-template-rows, pero hemos definido el tamaño de las primeras filas y no de todas las filas necesarias, con grid-auto-rows podemos definir el tamaño de las filas que faltan.

section {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr 1fr;
          grid-template-rows: 100px 100px;
          grid-auto-rows: 50px;
      }
      

En este ejemplo se creará un Grid con 4 columnas y tantas filas como elementos tengamos, pero el tamaño de las dos primeras filas será de 100px, mientras que el tamaño del resto de filas será de 50px.

Esto es muy útil cuando no sabemos cuántos elementos vamos a tener, ya que podemos definir el tamaño de las primeras filas y el tamaño de las filas que se creen por defecto.

Repeatlink image 54

Imaginemos que queremos crear un Grid con 100 columnas y todas del mismo tamaño. Tendríamos que escribir 100 veces la unidad de medida que queremos utilizar. Para evitar esto podemos utilizar la propiedad repeat.

section {
          display: grid;
          grid-template-columns: repeat(100, 1fr);
      }
      

Con repeat podemos definir el número de columnas que queremos y la unidad de medida que queremos utilizar.

Podemos usar repeat con subpartes de la cuadrícula. Por ejemplo, imaginemos que queremos crear otra vez 100 columnas, pero queremos que la primera y la última columna tengan un ancho de 100px y el resto de columnas tengan un ancho de 1fr.

section {
          display: grid;
          grid-template-columns: 100px repeat(98, 1fr) 100px;
      }
      

Ahora supongamos que tenemos un patrón de columnas que se repite cada 3 columnas. Podemos utilizar repeat para definir este patrón.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px 1fr);
      }
      

De esta manera creamos una cuadrícula de 6 columnas, donde el patrón se repite cada 2 columnas.

minmaxlink image 55

A lo mejor no sabemos el tamaño exacto de una fila o una columna, sino que lo que queremos es que ocupe un tamaño entre un mínimo y un máximo. Para ello podemos utilizar la propiedad minmax.

section {
          display: grid;
          grid-template-columns: minmax(100px, 1fr) 1fr 1fr 1fr;
      }
      

En este ejemplo queremos que cada columna tenga el 25% del ancho del contenedor, pero que la primera columna tenga un ancho mínimo de 100px. Es decir, si el espacio que ocupa la primera columnas es menor de 100px, la columna tendrá un ancho de 100px, pero si el espacio que ocupa la primera columna es mayor de 100px, la columna tendrá un ancho del 25% del contenedor.

Esto es muy útil por ejemplo cuando tenemos un índice en el lateral de la página y queremos que ocupe un ancho mínimo, pero que si el espacio disponible es mayor, ocupe el espacio que le corresponde.

<div>
          <aside>Índice</aside>
          <main>Contenido</main>
      </div>
      
div {
          display: grid;
          grid-template-columns: minmax(100px, 1fr) 5fr;
      }
      

De esta manera el índice tendrá un ancho mínimo de 100px, pero si el espacio disponible es mayor, el índice ocupará el espacio que le corresponde.

Grid-column-gap y Grid-row-gaplink image 56

Si queremos añadir un espacio entre las columnas o entre las filas, podemos utilizar las propiedades grid-column-gap y grid-row-gap.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-column-gap: 20px;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-row-gap: 20px;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las filas.

Podemos definir el espacio entre las columnas y las filas con la propiedad grid-gap.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px 10px;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas y un espacio de 10px entre las filas.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas y las filas.

Auto-fill y Auto-fitlink image 57

Con auto-fill y auto-fit podemos crear un Grid con un número de columnas o filas que se adapte al espacio disponible en el contenedor, así podemos hacer el Grid responsive.

section {
          display: grid;
          grid-template-columns: repeat(auto-fill, 100px);
      }
      

En este ejemplo se crearán tantas columnas como quepan en el contenedor, pero cada columna tendrá un ancho de 100px.

section {
          display: grid;
          grid-template-columns: repeat(auto-fit, 100px);
      }
      

En este ejemplo se crearán tantas columnas como quepan en el contenedor, pero cada columna tendrá un ancho de 100px y si sobra espacio en el contenedor, el espacio se repartirá entre las columnas.

Ahora lo podemos hacer más completo

section {
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
      }
      

En este ejemplo se crearán tantas columnas como quepan en el contenedor, pero cada columna tendrá un ancho mínimo de 100px y si sobra espacio en el contenedor, el espacio se repartirá entre las columnas. A medida que hagamos el navegador más pequeño, las columnas se irán adaptando al espacio disponible, hasta que llegue un momento en el que no para que quepan deberían tener un ancho menor de 100px, por lo que se eliminará una columna y se redistribuirá el espacio entre las columnas restantes.

section {
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
          grid-gap: 20px;
      }
      

En este ejemplo se crearán tantas columnas como quepan en el contenedor, pero cada columna tendrá un ancho mínimo de 100px y si sobra espacio en el contenedor, el espacio se repartirá entre las columnas y habrá un espacio de 20px entre las columnas.

Auto-fill vs Auto-fitlink image 58

La diferencia entre auto-fill y auto-fit es que auto-fill crea tantas columnas o filas como quepan en el contenedor, mientras que auto-fit crea tantas columnas o filas como quepan en el contenedor, pero si sobra espacio en el contenedor, el espacio se repartirá entre las columnas o filas.

Es decir, auto-fill crea tantas columnas o filas como quepan en el contenedor, pero si sobra espacio en el contenedor, el espacio no se repartirá entre las columnas o filas, mientras que auto-fit crea tantas columnas o filas como quepan en el contenedor, pero si sobra espacio en el contenedor, el espacio se repartirá entre las columnas o filas.

Grid-column-start y Grid-column-end (bento grid)link image 59

Hasta ahora hemos visto cómo crear un Grid con columnas y filas, pero ¿qué pasa si queremos que un elemento ocupe más de una columna o fila? Para ello tenemos las propiedades grid-column-start y grid-column-end.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
          <div>Texto 4</div>
          <div>Texto 5</div>
          <div>Texto 6</div>
          <div>Texto 7</div>
          <div>Texto 8</div>
          <div>Texto 9</div>
      </section>
      
section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-column-start: 1;
          grid-column-end: 3;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El segundo elemento ocupa desde la primera columna hasta la tercera columna.

También podemos decirle el inicio y el final de la columna con la propiedad grid-column.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-column: 1 / 3;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El segundo elemento ocupa desde la primera columna hasta la tercera columna.

Si no queremos decirle dónde acabar, sino cuántas columnas queremos que ocupe, podemos utilizar la propiedad span.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-column-start: 1;
          grid-column-end: span 2;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El segundo elemento ocupa desde la primera columna hasta la segunda columna, es decir, ocupa dos columnas.

Si queremos posicionarlos al final, pero no sabemos cuántas columnas hay, podemos utilizar números negativos.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-column-start: 1;
          grid-column-end: -1;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El segundo elemento ocupa desde la primera columna hasta la última columna, es decir, ocupa las tres columnas.

Grid-row-start y Grid-row-end (bento grid)link image 60

Podemos hacer lo mismo con las filas, para ello tenemos las propiedades grid-row-start y grid-row-end.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
          <div>Texto 4</div>
          <div>Texto 5</div>
          <div>Texto 6</div>
          <div>Texto 7</div>
          <div>Texto 8</div>
          <div>Texto 9</div>
      </section>
      
section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-row-start: 1;
          grid-row-end: 3;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El segundo elemento ocupa desde la primera fila hasta la tercera fila.

Tamibén podemos decirle el inicio y el final de la fila con la propiedad grid-row.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-row: 1 / 3;
      }
      

Al igual que antes, si no queremos decirle dónde acabar, sino cuántas filas queremos que ocupe, podemos utilizar la propiedad span.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-row-start: 1;
          grid-row-end: span 2;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El segundo elemento ocupa desde la primera fila hasta la segunda fila, es decir, ocupa dos filas.

Si queremos posicionarlos al final, pero no sabemos cuántas filas hay, podemos utilizar números negativos.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:nth-child(2) {
          grid-row-start: 1;
          grid-row-end: -1;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El segundo elemento ocupa desde la primera fila hasta la última fila, es decir, ocupa las tres filas.

Superposición de elementoslink image 61

Podemos posicionar los elementos de forma que se superpongan unos a otros.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
          <div>Texto 4</div>
          <div>Texto 5</div>
          <div>Texto 6</div>
          <div>Texto 7</div>
          <div>Texto 8</div>
          <div>Texto 9</div>
      </section>
      
section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:first-child {
          grid-column-start: 1;
          grid-column-end: 2;
          grid-row-start: 1;
          grid-row-end: 2;
      }
      
      section div:nth-child(2) {
          grid-column-start: 1;
          grid-column-end: 2;
          grid-row-start: 1;
          grid-row-end: 2;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El primer elemento ocupa desde la primera columna hasta la segunda columna y desde la primera fila hasta la segunda fila. El segundo elemento ocupa desde la primera columna hasta la segunda columna y desde la primera fila hasta la segunda fila.

Para controlar cuál de los elementos se superpone al otro, podemos utilizar la propiedad z-index.

section {
          display: grid;
          grid-template-columns: repeat(3, 100px);
          grid-gap: 20px;
      }
      
      section div:first-child {
          grid-column-start: 1;
          grid-column-end: 2;
          grid-row-start: 1;
          grid-row-end: 2;
          z-index: 1;
      }
      
      section div:nth-child(2) {
          grid-column-start: 1;
          grid-column-end: 2;
          grid-row-start: 1;
          grid-row-end: 2;
          z-index: 2;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas de 100px cada una y un espacio de 20px entre las columnas. El primer elemento ocupa desde la primera columna hasta la segunda columna y desde la primera fila hasta la segunda fila. El segundo elemento ocupa desde la primera columna hasta la segunda columna y desde la primera fila hasta la segunda fila. Como el segundo elemento tiene un z-index mayor que el primer elemento, el segundo elemento se superpone al primero.

Layouts con Gridlink image 62

Ahora que conocemos las propiedades básicas de Grid, vamos a ver cómo podemos crear layouts con Grid.

<header>Header</header>
      <aside>Aside</aside>
      <main>Main</main>
      <footer>Footer</footer>
      
body {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr;
          grid-template-rows: 35px 1fr 100px;
          min-height: 100vh;
      }
      
      header {
          grid-column: 1 / -1;
      }
      
      main {
          grid-column: span 2;
      }
      
      footer {
          grid-column: 1 / -1;
      }
      

En este ejemplo hemos creado un Grid con 3 columnas y 3 filas. La primera fila tiene un alto de 35px, la segunda fila ocupa el resto del espacio disponible y la tercera fila tiene un alto de 100px. El header ocupa desde la primera columna hasta la última columna, el main ocupa desde la primera columna hasta la segunda columna y el footer ocupa desde la primera columna hasta la última columna.

Hemos puesto min-height: 100vh para que el Grid ocupe el 100% del alto de la pantalla, ya que si no ponemos esto, el Grid solo ocupará el alto del contenido.

Sin embargo a la hora de ver el CSS cuesta entenderlo, por lo que podemos utilizar la propiedad grid-area.

Grid-arealink image 63

Podemos ponerle un nombre a cada una de las áreas del Grid y luego utilizar ese nombre para posicionar los elementos.

<header>Header</header>
      <aside>Aside</aside>
      <main>Main</main>
      <footer>Footer</footer>
      
body {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr;
          grid-template-rows: 35px 1fr 100px;
          min-height: 100vh;
          grid-template-areas: 
              "header header header"
              "sidebar content content"
              "footer footer footer";
      }
      
      header {
          grid-area: header;
      }
      
      main {
          grid-area: content;
      }
      
      footer {
          grid-area: footer;
      }
      
      aside {
          grid-area: sidebar;
      }
      

Como hemos puesto nombre a cada una de las áreas del Grid, podemos utilizar ese nombre para posicionar los elementos. De esta manera es más fácil entender el CSS.

Si ahora quisiéramos hacerlo responsive, solo tendríamos que cambiar el Grid y el resto del CSS se mantendría igual.

body {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr;
          grid-template-rows: 35px 1fr 100px;
          min-height: 100vh;
          grid-template-areas: 
              "header header header"
              "sidebar content content"
              "footer footer footer";
      }
      
      @media (width < 400px) {
          body {
              grid-template-columns: 1fr;
              grid-template-rows: 35px 1fr 100px;
              grid-template-areas: 
                  "header header sidebar"
                  "content content content"
                  "footer footer footer";
          }
      
      header {
          grid-area: header;
      }
      
      main {
          grid-area: content;
      }
      
      footer {
          grid-area: footer;
      }
      
      aside {
          grid-area: sidebar;
      }
      

Ahora hemos hecho que cuando lo vemos en un dispositivo grande el sidebar esté a la izquierda y el contenido a la derecha, pero cuando lo vemos en un dispositivo pequeño, el sidebar está arriba y el contenido abajo.

Supongamos que queremos que en una zona no haya nada, podemos poner un punto.

body {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr;
          grid-template-rows: 35px 1fr 100px;
          min-height: 100vh;
          grid-template-areas: 
              "header header header"
              "sidebar . content"
              "footer footer footer";
      }
      
      @media (width < 400px) {
          body {
              grid-template-columns: 1fr;
              grid-template-rows: 35px 1fr 100px;
              grid-template-areas: 
                  "header header sidebar"
                  "content content content"
                  "footer footer footer";
          }
      
      header {
          grid-area: header;
      }
      
      main {
          grid-area: content;
      }
      
      footer {
          grid-area: footer;
      }
      
      aside {
          grid-area: sidebar;
      }
      

Ahora en pantallas grandes hay un hueco entre el sidebar y el contenido.

Justify-items, Align-items, Justify-content y Align-contentlink image 64

Podemos alinear el contenido y los elementos de un Grid con las propiedades justify-items, align-items, justify-content y align-content.

grid justify

Justify-itemslink image 65

Podemos alinear los elementos en el eje X del Grid con la propiedad justify-items.

Los valores que podemos utilizar son:

  • start: alinea los elementos al principio del eje principal.
  • end: alinea los elementos al final del eje principal.
  • center: alinea los elementos en el centro del eje principal.
  • stretch: estira los elementos para que ocupen todo el espacio disponible en el eje principal.
<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: grid;
          justify-items: center;
      }
      

Justify-selflink image 66

Con justify-items alineamos todos los elementos en el eje principal del Grid, pero con justify-self podemos alinear un elemento en el eje principal del Grid de forma diferente al resto de elementos.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: grid;
          justify-items: center;
      }
      
      section div:nth-child(2) {
          justify-self: end;
      }
      
image css 2

Align-itemslink image 67

Es muy parecido a justify-items, pero en vez de alinear los elementos en el eje X, los alinea en el eje Y.

Los valores que podemos utilizar son:

  • start: alinea los elementos al principio del eje secundario.
  • end: alinea los elementos al final del eje secundario.
  • center: alinea los elementos en el centro del eje secundario.
  • stretch: estira los elementos para que ocupen todo el espacio disponible en el eje secundario.
<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: grid;
          align-items: center;
      }
      

Align-selflink image 68

Con align-items alineamos todos los elementos en el eje secundario del Grid, pero con align-self podemos alinear un elemento en el eje secundario del Grid de forma diferente al resto de elementos.

<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: grid;
          align-items: center;
      }
      
      section div:nth-child(2) {
          align-self: end;
      }
      
image css 3

Place-contentlink image 69

Si queremos usar justify-content y align-content a la vez, podemos usar place-content.

Los valores que podemos utilizar son:

  • start: alinea los elementos al principio del eje principal y secundario.
  • end: alinea los elementos al final del eje principal y secundario.
  • center: alinea los elementos en el centro del eje principal y secundario.
  • stretch: estira los elementos para que ocupen todo el espacio disponible en el eje principal y secundario.
<section>
          <div>Texto 1</div>
          <div>Texto 2</div>
          <div>Texto 3</div>
      </section>
      
section {
          display: grid;
          place-content: center;
      }
      

Práctica de Gridlink image 70

Un buen recurso para practicar Grid es Grid Garden.

Centrar un divlink image 71

Hasta ahora hemos visto 3 formas de centrar un div:

  • Con position: absolute.
  • Con display: flex.
  • Con display: grid.

Animacioneslink image 72

Dentro de las animaciones hay dos tipos las transiciones y las animaciones

Transicioneslink image 73

En las transiciones cambiamos un elemento de un estado inicial a un estado objetivo

Supongamos que tenemos el siguiente círculo

<div class="pulser"></div>
      

Y su CSS

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
      }
      

Los elementos de html pueden tener estados, por ejemplo el estado hover, que es cuando el usuario pasa el cursor por encima del elemento

.pulser:hover {
          scale: 2;
          background: purple;
          box-shadow: 0 0 10px purple;
      }
      

Al hacer scale hacemos que aumente el tamaño, pero ocupando el mismo espacio, sin embargo, si hubiésemos cambiado el width y el height el botón se habría movido de sitio.

Transitionlink image 74

Lo que pasa es que si ahora pasamos el ratón por encima del círculo cambia el estado de golpe, así que aquí es donde entra la transición, que es como le indicamos al CSS cómo se tiene que modificar el estado. Por ejemplo si queremos que la transición dure 1 segundo

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: 1s;
      }
      

Es importante poner la transición en .pulser y no en .pulser:hover porque si no, no se aplicaría la transición al volver al estado inicial. Es decir, cuando pasemos el ratón por encima del círculo se verá la transición, pero cuando quitemos el ratón del círculo no habrá una transición de vuelta, sino que pasará de golpe al estado inicial

Qué se quiere transicionar transition-propertylink image 75

Con lo anterior se haría una transición de color, de tamaño y de fondo, pero si no queremos que se produzca una transición de todo podemos indicárselo mediante transition-property

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: 1s;
          transition-property: background-color, scale;
      }
      

De esta manera solo se hará la transición de background-color y scale

Transiciones suaveslink image 76

La transición por defecto se hace de manera lineal, pero si queremos cambiarla podemos hacerlo mediante transition-timing-function

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: 1s;
          transition-property: background-color, scale;
          transition-timing-function: ease-in-out;
      }
      

De esta manera la transición será más suave al principio y al final. Los posibles valores son los siguientes:

  • linear
  • ease
  • ease-in
  • ease-out
  • ease-in-out
  • cubic-bezier(n,n,n,n)

Transiciones por pasoslink image 77

Si queremos que la animación se haga en varios pasos podemos usar steps(n), donde n es el número de pasos que queremos que tenga la animación

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: 1s;
          transition-property: background-color, scale;
          transition-timing-function: steps(5);
      }
      

De esta manera se realizará la transición en 5 pasos durante 1 segundo

Control total de la transición con cubic-bezierlink image 78

Para poder controlar perfectamente la transición podemos usar cubic-bezier(n,n,n,n), donde n es un número entre 0 y 1 que indica la posición del punto en el eje X e Y

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: 1s;
          transition-property: background-color, scale;
          transition-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1);
      }
      

Con delay podemos indicar el tiempo que tiene que pasar hasta que se inicie la transición

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: 1s;
          transition-property: background-color, scale;
          transition-timing-function: cubic-bezier(0.1, 0.7, 1.0, 0.1);
          transition-delay: 1s;
      }
      

Con el delay se pueden hacer animaciones de cargas, por ejemplo

<section>
          Haz hover para mostrar los elementos
          <div class="pulser"></div>
          <div class="pulser"></div>
          <div class="pulser"></div>
      </section>
      
section {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 100vh;
      }
      
      .pulser {
          width: 30px;
          height: 30px;
          border-radius: 50%;
          position: relative;
          position: relative;
          opacity: 0;
          transition: 2s;
          transition-timing-function: ease;
      }
      
      section {
          display: flex;
          gap: 16px;
          justify-content: center;
          aling-items: center;
      }
      
      section:hover .pulser {
          opacity: 1;
      }
      
      .pulser:first-child {
          transition-delay: 0s;
      }
      
      .pulser:nth-child(2) {
          transition-delay: 300ms;
      }
      
      .pulser:last-child {
          transition-delay: 600ms;
      }
      

En easings.co podemos ver y configurar las transiciones

Todo en una línealink image 79

En .pulser hemos puesto transition y transitio-timing-function, pero también podemos ponerlo todo en una línea

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: background 300ms ease-in-out 2s;
      }
      

Con esto, lo que le hemos dicho es anime el background durante 300ms, con una transición suave al principio y al final y que espere 2 segundos antes de empezar la transición

Si queremos hacer especificar varios elementos podemos hacerlo de la siguiente manera

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: background 300ms ease-in-out 2s, scale 1s ease-in-out 1s;
      }
      

¿Qué transicionar?link image 80

A la hora de meter transiciones, se puede buscar qué se puede transicionar en Animatable CSS properties, pero para no estar perdiéndo el tiempo buscando, lo mejor es transicionar propiedades con cabeza, por ejemplo algo que se puede transicionar es un color, un tamaño, etc.

Lo ideal es transicionar propiedades con estados intermedios, por ejemplo una fuente no tiene un estado intermedio y no tiene sentido hacerle una transición de una fuente a otra

Distintas transiciones al inicio y al finallink image 81

Antes hemos dicho que hay que poner las transiciones en el elemento y no en el hover, porque de esta manera la transición solo se verá cuando se pone el ratón encima del elemento y no cuando quites el ratón. Pues si se quieren tener distintas animaciones al inicio y al final podemos aprovecharnos de esto. En el elemento pondremos la transición final y en el hover la inicial

.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
          position: relative;
          transition: background 300ms ease-in-out
      }
      
      .pulser:hover {
          scale: 2;
          background: purple;
          box-shadow: 0 0 10px purple;
          transition: 1s;
          transition-duration: 1s;
      }
      

De esta manera cuando pasemos el ratón por encima del elemento se hará una transición de 300 ms y cuando quitemos el ratón la transición será de 1 segundo

Accesibilidadlink image 82

Hay gente que se puede llegar a marear con las transiciones, por lo que podemos añadir una media query para quitarlas

@media (prefers-reduced-motion: reduce) {
          .pulser {
              transition: none;
          }
      }
      

Animacioneslink image 83

Las transiciones son las animaciones cuando interactuamos con los elementos, pero en las animaciones no neceitamos interactuar con el elemento, pueden ejecutarse solas. Por ejemplo, el típico botón que cada cierto tiempo cambia se mueve para que sepas que tienes que pilsarlo

Keyframeslink image 84

Volvemos al ejemplo de la bola azul y quitamos todas las transiciones

<div class="pulser"></div>
      
.pulser {
          width: 30px;
          height: 30px;
          background-color: #09f;
          border-radius: 50%;
      }
      

Tenemos que indicarle al CSS que queremos hacer una animación, para ello usamos @keyframes y le damos un nombre a la animación

@keyframes move {
      }
      

Ahora le tenemos que decir desde dónde empieza este frame, para ello usamos from y dónde termina, para ello usamos to

@keyframes move {
          from {
          }
          to {
          }
      }
      

Ahora tenemos que indicarle qué propiedades queremos que cambien, por ejemplo la posición

@keyframes move {
          from {
              transform: translateX(0);
          }
          to {
              transform: translateX(100px);
          }
      }
      

De esta manera cuando entremos en la página la bola azul se moverá 100px hacia la derecha

Afterlink image 85

En un elemento se puede poner un after que es un elemento que se pone después del elemento principal

<div class="pulser"></div>
      
.pulser {
          width: 30px;
          height: 30px;
          background-color: blue;
          border-radius: 50%;
      }
      
      .pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      }
      

Esto lo que hace es poner un círculo azul detrás del círculo azul, por lo que ahora tenemos dos círculos azules

Ahora definimos los keyframes

@keyframes move {
          0% {
              opacity: 0;
          }
          50% {
              scale: 1.5;
              opacity: 40%;
          }
          100% {
              opacity: 60%;
          }
      }
      

Y como ya hemos definido los keyframes, ahora solo tenemos que indicarle al CSS que queremos que se ejecute la animación

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation-name: pulse;
          animation-duration: 2s;
          animation-timing-function: ease-in-out;
      }
      

Ahora cuando cargue la página se vería como si el círculo azul tuviese un latido

Pero solo se produce una vez, para que se produzca más veces necesitamos añadir animation-iteration-count

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation-name: pulse;
          animation-duration: 2s;
          animation-timing-function: ease-in-out;
          animation-iteration-count: infinite;
      }
      

Ahora se producirá infinitas veces

Movimientolink image 86

Podemos hacer que un elemento se mueva

<div class="pulser"></div>
      
.pulser {
          width: 30px;
          height: 30px;
          background-color: blue;
          border-radius: 50%;
          position: relative;
      }
      
      .pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation-name: mover;
          animation-duration: 2s;
          animation-iteration-count: infinite;
          animation-timing-function: linear;
      }
      
      @keyframes move {
          from {
              trasnform: translateX(0);
          }
          to {
              transform: translateX(100px);
          }
      }
      

Ahora la bola azul se moverá 100px hacia la derecha

Direcciónlink image 87

Para que la bola azul se mueva hacia la izquierda solo hay que hacer animation-direction: reverse

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation-name: mover;
          animation-duration: 2s;
          animation-iteration-count: infinite;
          animation-timing-function: linear;
          animation-direction: reverse;
      }
      

Si lo que queremos es que la bola vaya de un lado al otro hay que poner animation-direction: alternate

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation-name: mover;
          animation-duration: 2s;
          animation-iteration-count: infinite;
          animation-timing-function: linear;
          animation-direction: alternate;
      }
      

Pausar animacioneslink image 88

Imagina que tienes tarjetas que tienen animaciones, a lo mejor quieres que cuando pases el ratón por encima de la tarjeta se pare la animación, para ello podemos usar animation-play-state: paused

.card:hover {
          animation-play-state: paused;
      }
      

CSS nestinglink image 89

Hemos declarado en el CSS las propiedades del pulser y las propiedades cuando se hace hover, pero se puede hacer todo junto

.pulser {
          width: 30px;
          height: 30px;
          background-color: blue;
          border-radius: 50%;
          position: relative;
      
          &::after {
              content: '';
              position: absolute;
              width: 100%;
              height: 100%;
              top: 0;
              left: 0;
              background-color: blue;
              border-radius: 50%;
              z-index: -1;
      
              animation-name: mover;
              animation-duration: 2s;
              animation-iteration-count: infinite;
              animation-timing-function: linear;
              animation-direction: alternate;
          }
      
          &:hover::after {
              animation-play-state: paused;
          }
      }
      

Cómo terminar las animacioneslink image 90

Si tenemos una animación que solo se ejecuta una vez, por ejemplo, que la bola azul se desplace hacia la derecha, cuando termine la animación irá de golpe a su posición inicial. Para evitar esto se puede usar animation-fill-mode: forwards

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation-name: mover;
          animation-duration: 2s;
          animation-timing-function: linear;
          animation-direction: alternate;
          animation-fill-mode: forwards;
      }
      

De esta manera, cuando termine la animación, la bola azul se quedará en la posición final

Si en vez de forwards ponemos backwards la animación empezará desde el estado final

Si ponemos both la animación empezará desde el estado final y terminará en el estado final

Todo en una línealink image 91

Tenemos un montón de propiedades (animation-name animation-duration, animation-timing-function, animation-direction, animation-fill-mode), pero se pueden poner todas en una línea. Todo lo anterior se podría poner así

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation: mover 2s linear alternate forwards;
      }
      

Podemos crear varias animaciones

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation: 
              mover 2s linear alternate forwards,
              agrandar 1s linear 2s both;
      }
      

Pero como no existe la animación agrandar la creamos con keyframes

@keyframes agrandar {
          0% {
              transform: scale: 1;
          }
          25% {
              transform: scale: 1.5;
          }
          50% {
              transform: scale: 2;
          }
          75% {
              transform: scale: 1.6;
          }
          100% {
              transform: scale: 2;
          }
      }
      

Se va a reproducir una detrás de la otra, porque a agrandar se le ha puesto un delay de 2 segundos, que es lo que dura la primera animación, pero si queremos que sea al mismo tiempo, hay que quitar el delay

.pulser::after {
          content: '';
          position: absolute;
          width: 100%;
          height: 100%;
          top: 0;
          left: 0;
          background-color: blue;
          border-radius: 50%;
          z-index: -1;
      
          animation: 
              mover 2s linear alternate forwards,
              agrandar 1s linear both;
      }
      

Animaciones con scrolllink image 92

Ejemplo de barra de progresolink image 93

Por ejemplo, si queremos hacer una barra que vaya aumentando de tamaño a medida que vamos bajando por la página

<section>
          <div id="barra"></div>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </p>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </p>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </p>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </p>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </p>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </p>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit
          </p>
      </section>
      
section {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 100vh;
      }
      
      #barra {
          position: fixed;
          top: 0;
          width: 0%;
          background-color: red;
          height: 1em;
      
          animation: barra-grow auto linear;
          animation-timeline: scroll(root block);
      }
      
      @keyframes barra-grow {
          from {
              width: 0%;
          }
          from {
              width: 100%;
          }
      }
      

Como en animation hemos puesto un tiempo de auto para saber cuánto tiempo tiene que durar la animación, el navegador mirará animation-timeline, donde le indicamos que tiene que fijarse en el scroll. Dentro de la función scroll le decimos en qué elemento se tiene que fijar, en nuestro caso hemos puesto rootp porque queremos el scroll de la página, pero se podría poner cualquier otro elemento de la página. Además le tenemos qu decir si queremos que se fije en el scroll vertical o en el horizontal, en nuestro caso hemos puesto block porque queremos que se fije en el scroll vertical (block es el valor por defecto, por lo que si quieres no hace falta ponerlo)

Ejemplo de header que cambia de colorlink image 94

Si queremos que cuando hagamos scroll el header cambie de color

<header>
          <nav>
              <ul>
                  <li>Home</li>
                  <li>About</li>
                  <li>Contact</li>
              </ul>
          </nav>
      </header>
      
header {
          position: sticky;
          top: 0;
          width: 100%;
          background-color: white;
          box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
          z-index: 2;
      
          animation: header-color linear both;
          animation-timeline: scroll(root block);
      }
      
      @keyframes header-color {
          from {
              background-color: white;
          }
          to {
              background-color: gray;
              backdrop-filter: blur(5px);
              color: white;
          }
      }
      

Pero haciéndolo así la animación del header termina solo cuando se llega al final de la página, pero a nosotros nos interesa que termine cuando se ha hecho un poco de scroll, para ello quitamos el both del animation y ponemos animation-range: 0 200px para que la animación termine cuando se ha hecho un scroll de 200px, es decir, se le está diciendo que la animación va desde los 0 px hasta los 200 px

header {
          position: sticky;
          top: 0;
          width: 100%;
          background-color: white;
          box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
          z-index: 2;
      
          animation: header-color linear;
          animation-timeline: scroll(root);
          animation-range: 0 200px;
      }
      
Ejemplo de galería de imágeneslink image 95

Imaginemos que tenemos un montón de imágenes y queremos que cuando vayamos haciendo scroll vayan apareciendo

<section>
          <img src="img1.jpg" alt="imagen 1">
          <img src="img2.jpg" alt="imagen 2">
          <img src="img3.jpg" alt="imagen 3">
          <img src="img4.jpg" alt="imagen 4">
          <img src="img5.jpg" alt="imagen 5">
          <img src="img6.jpg" alt="imagen 6">
          <img src="img7.jpg" alt="imagen 7">
          <img src="img8.jpg" alt="imagen 8">
          <img src="img9.jpg" alt="imagen 9">
          <img src="img10.jpg" alt="imagen 10">
      </section>
      
section {
          display: grid;
          grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
          gap: 16px;
      }
      
      img {
          width: 100%;
          height: auto;
          opacity: 0;
          animation: aparecer linear both;
          animation-timeline: view()
          animation-range: entry 20% cover 30%;
      }
      
      @keyframes aparecer {
          from {
              opacity: 0;
          }
          to {
              opacity: 1;
          }
      }
      

con animation-timeline: view() le estamos diciendo que haga la animación cuando la imagen se vea en la pantalla y con animation-range: entry 20% cover 30% le estamos diciendo que la animación empiece cuando la imagen ocupe el 20% de la pantalla y que termine cuando ocupe el 30% de la pantalla

Al poner both en animation le estamos diciendo que la animación se haga tanto al aparecer como al desaparecer, es decir, que cuando la imagen aparece se ve la animación, pero cuando desaparece también se ve la animación pero al revés, es decir, que la imagen va teniendo una opacidad de 1 a 0 poco a poco

Seguir leyendo

DoLa – Decoding by Contrasting Layers Improves Factuality in Large Language Models

DoLa – Decoding by Contrasting Layers Improves Factuality in Large Language Models

¿Alguna vez has hablado con un LLM y te ha respondido algo que suena como si hubiera estado bebiendo café de máquina durante toda la noche? 😂 ¡Eso es lo que llamamos una alucinación en el mundo de los LLMs! Pero no te preocupes, porque no es que tu modelo de lenguaje esté loco (aunque a veces puede parecerlo 🤪). La verdad es que los LLMs pueden ser un poco... creativos cuando se trata de generar texto. Pero gracias a DoLa, un método que utiliza capas de contraste para mejorar la factibilidad de los LLMs, podemos evitar que nuestros modelos de lenguaje se conviertan en escritores de ciencia ficción 😂. En este post, te explicaré cómo funciona DoLa y te mostraré un ejemplo de código para que puedas entender mejor cómo hacer que tus LLMs sean más fiables y menos propensos a inventar historias. ¡Vamos a salvar a nuestros LLMs de la locura y hacer que sean más útiles! 🚀

Últimos posts -->

¿Has visto estos proyectos?

Subtify

Subtify Subtify

Generador de subtítulos para videos en el idioma que desees. Además a cada persona le pone su subtítulo de un color

Ver todos los proyectos -->

¿Quieres aplicar la IA en tu proyecto? Contactame!

¿Quieres mejorar con estos tips?

Últimos tips -->

Usa esto en local

Los espacios de Hugging Face nos permite ejecutar modelos con demos muy sencillas, pero ¿qué pasa si la demo se rompe? O si el usuario la elimina? Por ello he creado contenedores docker con algunos espacios interesantes, para poder usarlos de manera local, pase lo que pase. De hecho, es posible que si pinchas en alún botón de ver proyecto te lleve a un espacio que no funciona.

Ver todos los contenedores -->

¿Quieres aplicar la IA en tu proyecto? Contactame!

¿Quieres entrenar tu modelo con estos datasets?

short-jokes-dataset

Dataset de chistes en inglés

opus100

Dataset con traducciones de inglés a español

netflix_titles

Dataset con películas y series de Netflix

Ver más datasets -->