Consultas de medios en SCSS: otra forma conveniente de utilizar la pantalla @media

¡Hola!



Recientemente me enfrenté al problema de las consultas de medios en un proyecto construido en Angular. No recuerdo exactamente qué restricciones me hicieron escribir un mixin para simplificar mi trabajo, pero realmente quiero compartir el resultado y recibir comentarios. Conocí muchos otros ejemplos similares, pero para mi trabajo me resulta más claro y conveniente usar este en particular.



En general, por conveniencia, me hice los siguientes requisitos:



  1. Los tamaños de pantalla deben representarse por separado para que pueda cambiar el comportamiento globalmente en un solo lugar (por ejemplo, en lugar de "320px", simplemente transmita "xs").
  2. Esta combinación con consultas de medios puede ser no solo en una dirección (por ejemplo, no siempre solo en el ancho máximo).
  3. Mixin se puede usar por separado, anulando las clases descritas en el interior, o descritas en el cuerpo del padre, anulando sus propiedades.


Así que definamos los permisos que necesitemos. Por ejemplo:



$sizes: ("xs":320px, "sm":576px, "md":768px, "lg":992px, "xl":1200px);


Para empezar, escribamos un mixin que acepte el prefijo y la resolución de rango deseados, bajo los cuales estamos limitados:



@mixin media($minmax, $media) {
  @each $size, $resolution in $sizes {
    @if $media == $size {
      @media only screen and (#{$minmax}-width: $resolution) {
        @content;
      }
    }
  }
}


En definitiva, pasamos el nombre de la resolución de pantalla que necesitamos, buscando su valor entre los previamente declarados en la variable $ tamaños. Una vez que lo hayamos encontrado, lo sustituimos junto con el mínimo o máximo pasado (variable $ minmax).



Un ejemplo de uso, incluido en otro mixin:



@mixin blocks-width {
  width: 400px;
  @include media("max", "md") {
    width: 100%;
  }
}


De este simple ejemplo obtendremos un mixin que cambia el ancho del bloque en <768px de 400px a 100%. Los siguientes ejemplos deberían dar el mismo resultado.



Un ejemplo de uso dentro de una clase:



.blocks-width {
width: 400px;
  @include media("max", "md") {
    width: 100%;
  }
}


Un ejemplo de uso como consulta de medios independiente:



.blocks-width {
width: 400px;
}

@include media("max", "md") {
.blocks-width {
    width: 100%;
}
}


Pero, ¿qué sucede si necesita una consulta de medios, incluida una con un rango claro (especifique una resolución dentro de la cual funcionará la consulta de medios)? Ampliemos un poco nuestros mixins.



Personalmente, es conveniente para mí describir la resolución de la siguiente manera: si necesitamos el rango md, tomamos los tamaños de pantalla entre sm y md. Si queremos reescribir el mixin para que solo pasemos una resolución, entonces tendremos que buscar el valor anterior de la lista. Como no encontré ningún método para hacer esto rápidamente, tuve que escribir una función:



@function getPreviousSize($currentSize) {
  $keys: map-keys($sizes);
  $index: index($keys, $currentSize)-1;
  $value: map-values($sizes);
  @return nth($value, $index);
}


Para comprobar cómo funciona, utilice depurar:



@debug getPreviousSize('md');


A continuación, nuestro código ligeramente rehecho:



@mixin media($minmax, $media) {
  @each $size, $resolution in $sizes {
    @if $media == $size {
      @if ($minmax != "within") {
        @media only screen and (#{$minmax}-width: $resolution) {
          @content;
        }
      } @else {
        @if (index(map-keys($sizes), $media) > 1) {
          @media only screen and (min-width: getPreviousSize($media)+1) and (max-width: $resolution) {
            @content;
          }
        } @else {
          @media only screen and (max-width: $resolution) {
            @content;
          }
        }
      }
    }
  }
}


La lógica es la misma que para la funcionalidad anterior. Pero, si desea aplicar una consulta de medios solo en el rango, por ejemplo, md, escriba lo siguiente cuando llame al mixin:



@include media("within", "md") {
  .blocks-width {
    width: 100%;
  }
}


Después de eso, veremos el siguiente CSS compilado:



@media only screen and (max-width: 768px) and (min-width: 577px)
.blocks-width {
    width: 100%;
}


Además, si especificamos el tamaño de pantalla más pequeño (lo tenemos xs), por ejemplo:



@include media("within", "xs") {
  .blocks-width {
    width: 100%;
  }
}


Luego obtenemos un rango de 0 a la resolución más pequeña correspondiente:



@media only screen and (max-width: 320px)
.blocks-widthh {
    width: 100%;
}


Naturalmente, puede reescribir estas consultas de medios en la otra dirección, pero personalmente, estoy acostumbrado a diseñar de más a menos.



¡Gracias por su atención!

UPD: el mixin se ha corregido ligeramente para que las resoluciones en rangos limitados no se superpongan :) Gracias por su atenciónE_STRICT



All Articles