Se seu código CSS foi criado com uma abordagem mobile-first, ele provavelmente contém todas as regras que compõem a visualização “desktop” dentro do @media
declarações. Isso é ótimo, mas os navegadores que não oferecem suporte a media queries (IE 8 e inferiores) simplesmente as ignoram e acabam obtendo a visualização móvel – o que não é bom.
Uma alternativa é criar duas folhas de estilo separadas: uma regular, para ser exibida nos navegadores modernos, e outra sem media queries, exibida nos navegadores mais antigos que não as suportam. Mas isso é passível de manutenção? É razoável manter uma folha de estilo separada para um pequeno subconjunto de visitantes?
Acontece que, como Jake Archibald descreveu, o Sass pode ser usado para automatizar grande parte do processo. De fato, gerenciadores de pontos de interrupção, como o include-media ou Sass MQ fornecem um mecanismo para lidar com isso com bastante facilidade e sem esforço extra de manutenção.
Neste artigo, descreverei como usar o include-media para gerar uma folha de estilo alternativa sem consultas de mídia e também como integrar esse processo ao fluxo de trabalho de ferramentas de compilação populares.
Uma primeira abordagem
Então, como vamos gerar essa folha de estilo alternativa? Queremos nos livrar de todos os @media
mas não é tão simples como desembrulhar cada uma delas e usar seu conteúdo.
Por exemplo, vamos imaginar uma grade de artigos. Em uma visualização móvel, cada artigo deve ocupar toda a largura da tela, mas à medida que a largura da janela de visualização aumenta, mais artigos devem ser encaixados em uma linha. Para fazer isso, diminuímos gradualmente a largura do artigo em relação ao seu contêiner com algumas media queries – quando chegarmos a 1400px
poderemos colocar 8 artigos por linha.
/* Original rules (1) */ .article { width: 100%; @media (min-width: 768px) { width: 50%; } @media (min-width: 1024px) { width: 25%; } @media (min-width: 1400px) { width: 12.5%; } } /* All media queries flattened (2) */ .article { width: 100%; width: 50%; width: 25%; width: 12.5%; }
Sem nenhum tratamento especial, o IE 8 simplesmente ignoraria todas as consultas de mídia e, portanto, renderizaria artigos de largura total, mesmo em uma tela grande (1). No entanto, se achatarmos cegamente todas as consultas de mídia e usarmos seu conteúdo, o navegador acabará usando sempre a última regra (width: 12.5%
, neste caso), mesmo que ela tenha sido originalmente planejada apenas para telas excepcionalmente grandes (2).
Isso não é ideal, pois passamos de ignorar todas as consultas de mídia para o outro extremo de incluir todas elas, o que, em um site típico, provavelmente significa passar de uma visualização móvel para uma realmente grande. Uma abordagem mais razoável é escolher uma largura específica e selecionar apenas as consultas de mídia que contribuem para essa visualização.
Passando para o terreno do include-media, vamos começar com a mesma lista de pontos de interrupção.
$breakpoints: ( 'small': 320px, 'medium': 768px, 'large': 1024px, 'super-large': 1400px );
É justo presumir que nossos usuários do IE 8 não estarão em um telefone ou tablet, portanto, parece razoável fornecer a eles o site como ele aparece no grande vista, então 1024px
. Vamos dar uma olhada em algumas media queries de um dos módulos do nosso site, parte do _module1.scss
.
.module1 { // This rule interests us, as it affects 'large' @include media('>=phone') { color: tomato; } // This one doesn't, as it's between 'medium' and 'large' (excluding) @include media('>medium', '<large') { color: chocolate; } // Not this one either, it affects only 'super-large' @include media('>=super-large') { color: wheat; } }
Com o include-media, o senhor pode simplesmente informar à biblioteca que deseja gerar uma versão das folhas de estilo sem suporte a consultas de mídia e especificar qual ponto de interrupção deseja emular. Para fazer isso, basta definir duas variáveis ($im-media-support
e $im-no-media-breakpoint
respectivamente).
Um cenário típico é ter duas cópias do arquivo SCSS principal: a normal permanece como está (main.scss
), e a alternativa com as variáveis definidas (main-old.scss
).
// main.scss @import 'include-media'; @import 'module1';
// main-old.scss $im-media-support: false; $im-no-media-breakpoint: 'large'; @import 'include-media'; @import 'module1'; // Resulting CSS .module1 { color: tomato; }
O senhor pode até mesmo especificar quais expressões de mídia devem ser aceitas ao nivelar as consultas de mídia. Por exemplo, se o senhor tiver uma consulta de mídia voltada para dispositivos de retina, provavelmente não desejará incluir seu conteúdo na folha de estilo alternativa, mesmo que ela corresponda ao ponto de interrupção emulado.
$im-no-media-expressions: ( 'screen', 'print' ); // This is retina only, we don't want this! @include media('>=medium', 'retina2x') { color: olive; }
A integração desse fluxo de trabalho em suas ferramentas de compilação é bastante simples e torna todo o processo perfeito. Estou incluindo exemplos de tarefas para o Grunt e o Gulp (desculpem os usuários de brócolis, mas nunca como minhas verduras).
// Gruntfile.js module.exports = function(grunt) { grunt.initConfig({ sass: { dist: { files: { 'css/main.css': 'sass/main.scss', "https://davidwalsh.name/css/main-old.css": 'sass/main-old.scss' } } } }); grunt.loadNpmTasks('grunt-contrib-sass'); grunt.registerTask('default', ['sass']); };
// Gulpfile.js var gulp = require('gulp'); var sass = require('gulp-sass'); gulp.task('sass', function() { return gulp.src(['sass/main.scss', 'sass/main-old.scss']) .pipe(sass()) .pipe(gulp.dest('./css')); }); gulp.task('default', ['sass']);
Com isso, a ferramenta de compilação gerará as duas folhas de estilo automaticamente, enviando-as para css/main.css
e css/main-old.css
.
Servindo as folhas de estilo
Por fim, só precisamos apresentar a folha de estilo apropriada dependendo do navegador, usando os bons e velhos comentários condicionais.
<!--[if lte IE 8]> <link rel="stylesheet" href="https://davidwalsh.name/css/main-old.css"> <![endif]--> <!--[if gt IE 8]><!--> <link rel="stylesheet" href="css/main.css"> <!--<![endif]-->
E é isso. Sites responsivos para dispositivos móveis e amigáveis ao IE!
O senhor pode obter o include-media em http://include-media.com

Sobre Eduardo Bouças
Eduardo é um desenvolvedor web português que vive em Londres e trabalha como Lead Developer para a Time Inc. UK. UK. Ele é apaixonado pela Web, por design limpo, código elegante e soluções robustas.