Consultas de mídia em SCSS são outra maneira conveniente de usar a tela @media

Olá!



Recentemente, encontrei um problema com consultas de mídia em um projeto desenvolvido no Angular. Não me lembro exatamente quais limitações me fizeram escrever um mixin para simplificar meu trabalho, mas eu realmente quero compartilhar o resultado e obter feedback. Eu encontrei muitos outros exemplos semelhantes, mas para o trabalho é mais claro e mais conveniente para mim usar este em particular.



Em geral, por conveniência, fiz os seguintes requisitos para mim:



  1. Os tamanhos de tela devem ser renderizados separadamente, para que você possa alterar o comportamento globalmente em um lugar (por exemplo, em vez de "320px", simplesmente transmita "xs").
  2. Esse mixin com consultas de mídia pode estar em mais de uma direção (por exemplo, nem sempre apenas largura máxima).
  3. Mixin pode ser usado separadamente, sobrescrevendo as classes descritas dentro, ou descritas no corpo do pai, sobrescrevendo suas propriedades.


Portanto, vamos definir as permissões de que precisamos. Por exemplo:



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


Para começar, vamos escrever um mixin que aceitaria o prefixo e a resolução de intervalo desejados, sob os quais somos limitados:



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


Resumindo, passamos o nome da resolução de tela de que precisamos, procurando seu valor entre os previamente declarados na variável $ size. Depois de encontrá-lo, nós o substituímos junto com o min ou max (variável $ minmax).



Um exemplo de uso, inclusive em outro mixin:



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


A partir deste exemplo simples, obteremos um mixin que altera a largura do bloco em <768px de 400px para 100%. Os exemplos a seguir devem dar o mesmo resultado.



Um exemplo de uso dentro de uma classe:



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


Um exemplo de uso como consulta de mídia autônoma:



.blocks-width {
width: 400px;
}

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


Mas e se você precisar de uma consulta de mídia, incluindo uma com um intervalo claro (especifique uma resolução na qual a consulta de mídia funcionará)? Vamos expandir um pouco nossos mixins.



Pessoalmente, é conveniente para mim descrever a resolução da seguinte maneira - se precisarmos da faixa md, então pegamos os tamanhos de tela entre sm e md. Se quisermos reescrever o mixin de forma que passemos apenas uma resolução, teremos que encontrar o valor anterior na lista. Como não encontrei nenhum método para fazer isso rapidamente, tive que escrever uma função:



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


Para verificar como funciona, use depurar:



@debug getPreviousSize('md');


A seguir, nosso código ligeiramente refeito:



@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;
          }
        }
      }
    }
  }
}


A lógica é a mesma da funcionalidade anterior. Mas, se você quiser aplicar uma consulta de mídia apenas no intervalo, por exemplo, md, escreva o seguinte ao chamar o mixin:



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


Depois disso, veremos o seguinte css compilado:



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


Além disso, se especificarmos o menor tamanho de tela (temos xs), por exemplo:



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


Então, obtemos um intervalo de 0 à menor resolução correspondente:



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


Naturalmente, você pode reescrever essas consultas de mídia na outra direção, mas, pessoalmente, estou acostumado a fazer layouts de mais para menos.



Obrigado pela atenção!

UPD: o mixin foi ligeiramente corrigido para que as resoluções em intervalos limitados não se sobreponham :) Obrigado pela atençãoE_STRICT



All Articles