65 votes

Imbrication des règles @media en CSS

Le soutien semble varier d'un navigateur à l'autre

Vérifier le lien

Firefox : Noir avec texte blanc.

Opera, Chrome, IE9 : Bleu avec texte noir.

Laquelle est la bonne et comment la rendre cohérente ?

Le code

@media screen and (min-width: 480px) {

    body{
        background-color:#6aa6cc;
        color:#000;    
    }

    @media screen and (min-width: 768px) {

        body{
            background-color:#000;
            color:#fff;    
        }
    }
}

Il est intéressant de noter qu'il semble que l'imbrication des requêtes média dans une requête conditionnelle de type @import semble fonctionner.

par exemple

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Media test</title>
    <link rel="stylesheet" type="text/css" href="importer.css" />
</head>
<body>
    <h1>Why is this not consistent.</h1>
</body>
</html>

importer.css

@import url(media.css) screen and (min-width: 480px);

media.css

body {
    background-color: #6aa6cc;
    color: #000;
}

@media screen and (min-width:768px) {
    body {
        background-color: #000;
        color: #fff;
    }
}

106voto

BoltClock Points 249668

Pour ceux qui cherchent simplement une réponse à la question "Quels sont les navigateurs qui prennent en charge l'imbrication de @media la réponse courte est que tous les navigateurs modernes, y compris Firefox, Safari, Chrome (et ses dérivés), et Microsoft Edge, supportent maintenant l'imbrication des règles de @media les règles de l'at, telles qu'elles sont décrites dans l'article CSS conditionnel 3 . Le code de la question avec les éléments imbriqués @media at-rules devrait maintenant fonctionner correctement partout, à l'exception d'Internet Explorer (qui est n'est plus mis à jour avec de nouvelles fonctionnalités ce qui signifie qu'aucune version d'IE ne prendra jamais en charge cette fonctionnalité).

Cette fonction n'existait pas dans les CSS2.1 En effet, il n'existait à l'époque que des types de médias que l'on pouvait simplement grouper par une virgule, ce qui explique pourquoi le support était très faible à l'époque où cette question a été posée pour la première fois.

Ce qui suit est une analyse de la question originale en gardant à l'esprit ces limites historiques.


Il y a une certaine confusion terminologique qui doit être levée pour que nous puissions comprendre ce qui se passe exactement.

Le code que vous avez se réfère à @media et pas tant les requêtes de média - la requête de média elle-même est le composant qui suit les règles du @media alors que la règle est l'ensemble du bloc de code constitué par les éléments suivants @media la requête média et les règles imbriquées à l'intérieur de son ensemble d'accolades.

Cela peut être source de confusion pour beaucoup lorsqu'il s'agit d'utiliser des requêtes de médias en CSS, ainsi que dans votre cas particulier où une requête de médias est utilisée. @media dans une feuille de style importée fonctionne correctement même si la règle @import est accompagnée d'une autre demande de support. Il est à noter que les requêtes médiatiques peuvent être présentes à la fois dans les @media y @import règles. Il s'agit de la même chose, mais elles sont utilisées pour appliquer de manière restrictive les règles de style de différentes manières.

Le problème qui se pose ici est que l'imbrication de @media Les règles sont non valide en CSS2.1 parce que vous n'avez pas le droit de nicher tous at-rules au sein de @media règles. Cependant, les choses semblent bien différentes en CSS3. En effet, le module Règles conditionnelles affirme très clairement que @media règles peut être imbriqués, en fournissant même un exemple :

Par exemple, avec cet ensemble de règles imbriquées :

@media print { /* rule (1) */
  /* hide navigation controls when printing */
  #navigation { display: none }
  @media (max-width: 12cm) { /* rule (2) */
    /* keep notes in flow when printing to narrow pages */
    .note { float: none }
  }
}

la condition de la règle marquée (1) est vraie pour les médias imprimés, et la condition de la règle marquée (2) est vraie lorsque la largeur de la zone d'affichage (qui, pour les médias imprimés, est le cadre de la page) est inférieure ou égale à 12 cm. Ainsi, la règle "#navigation { display : none }" s'applique chaque fois que cette feuille de style est appliquée à un support imprimé, et la règle ".note { float : none }" n'est appliquée que lorsque la feuille de style est appliquée à un support imprimé et que la largeur de la zone d'affichage est inférieure ou égale à 12 centimètres.

De plus, il semble que Firefox suive cette spécification et traite les règles en conséquence, alors que les autres navigateurs continuent à les traiter à la manière de CSS2.1.

La grammaire de la Syntaxe du module n'a pas encore été mis à jour pour refléter cette évolution ; il interdit toujours l'imbrication des règles at dans les règles at. @media comme dans le cas de CSS2.1. Cette spécification est de toute façon destinée à être réécrite, donc je suppose que cela n'a pas d'importance.

En principe, CSS3 le permet (en attendant la réécriture du module Syntax), mais pas CSS2.1 (parce qu'il ne définit pas les requêtes de médias et n'autorise pas les requêtes imbriquées). @media blocs de règles). Et bien qu'au moins un navigateur ait commencé à prendre en charge la nouvelle spécification, je ne dirais pas que les autres navigateurs sont bogués ; je dirais plutôt qu'ils n'ont tout simplement pas encore rattrapé leur retard car ils se conforment en réalité à une spécification plus ancienne et plus stable.

Enfin, la raison pour laquelle votre @import fonctionne, c'est parce que @import peut fonctionner de manière conditionnelle à l'aide d'une requête média. Cependant, cela n'a aucun rapport avec le @media dans votre feuille de style importée. Il s'agit en fait de deux choses distinctes, qui sont traitées comme telles par tous les navigateurs.

Pour que votre code fonctionne de manière cohérente dans tous les navigateurs, vous pouvez soit utiliser votre code @import ou, puisque vos deux règles utilisent l'instruction min-width il suffit de supprimer l'imbrication de votre @media règles :

@media screen and (min-width: 480px) {
    body {
        background-color: #6aa6cc;
        color: #000;
    }
}

@media screen and (min-width: 768px) {
    body {
        background-color: #000;
        color: #fff;
    }
}

1 votes

Merci pour cela. C'est intéressant. J'ai ajouté l'exemple @import juste pour montrer que cela fonctionne. Je suis toujours étonné de voir que ce genre de choses peut être vanté comme étant supporté par les navigateurs mais avec des comportements très différents.

2 votes

@James South : En effet. J'ai également ajouté quelques explications pour votre @import exemple. Après avoir relu les spécifications, j'ai ressenti le besoin de revenir sur ce point.

0 votes

Sympa mais les commentaires CSS doivent utiliser /* ... */ et non // ; // est utilisé pour les commentaires dans certains exemples de CSS que vous avez fournis.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X