Utiliser les Media Queries CSS3 dans l'attribut style

Autant vous annoncer la mauvaise nouvelle tout de suite, il n'est pas possible d'utiliser les Media Queries dans l'attribut des balises HTML style. Ainsi le code suivant ne fonctionnera pas...

<div>
    <img 
        src="image/que/je/veux/decaller/seulement/quand/elle/flotte.png" 
        style="@media(min-width: 768px){float:left margin:-4px 16px 8px -24px;}">
    <p>J'aimerai faire flotter à gauche l'image ci-dessus uniquement sur 
    les grands écrans. Comme les valeurs de `margin` sont ajustées uniquement 
    aux propriétés de cette image (-4px 16px 8px -24px), il n'existe pas de
    classe  HTML-driven comme créer un `.float-left` (à l'avance) qui répondrait 
    exactement à mon besoin.</p>
</div>

...c'est comme ça !

Dans ce cas, comment faire pour gérer des propriétés CSS ponctuellement en utilisant les Media Queries ? Cela est très utile pour le remplissage de contenu pour ajuster des images ou encore manager des background-image.

La solution n'est pas l'attribut style des balises HTML mais la balise <style> elle même !

La balise style

La solution simple en HTML5 est donc d'utiliser la balise <style scoped> dans la balise <body> d'un document HTML :

<!DOCTYPE html><!-- On travail en HTML5 -->
...
<body>
    ...
    <div>
        <style scoped>
            @media (min-width: 768px) {
                .on-the-fly-class-example { 
                    float: left; 
                    margin: -4px 16px 8px -24px;
                }
            }
        </style>
        <img class="on-the-fly-class-example" src="image/que/je/veux/decaller/seulement/quand/elle/flotte.png">
        J'aimerai faire flotter à gauche l'image ci-dessus uniquement sur les grands écrans. Comme les valeurs de `margin` sont ajusté uniquement aux propriété de cette image (-4px 16px 8px -24px), il n'existe pas de classe HTML-driven comme `.float-left` (à l'avance) qui répondrait exactement à mon besoin.
    </div>
    ...
</body>

Tester le rendu de ce code

Note : Il est important que la balise <style> soit déclarée avant son utilisation pour éviter que le navigateur ne pose un problème de FOUC.

Pourquoi ajouter l'attribut scoped ?

En HTML5, il n'est pas valide de placer la balise <style> en dehors de la balise <head>. Oui, mais ce n'est pas tout à fait exacte... En réalité, il n'est pas valide de la placer dans <body> uniquement si on ne mentionne pas qu'elle est scoped, ce qui signifie que notre exemple est parfaitement valide.

Oui, mais pourquoi est-il nécessaire cet attribut ? scoped signifie que le style ne s'appliquera que sur la balise parente imédiate (ici <div>) et la totalité de ses balises enfants (ici <img>). Cependant dans les faits, aucun navigateur ne l'implémente encore et il ne limite donc pas du tout sa portée.

Vous pouvez tout à fait vous en passer donc mais cela ne sera pas valide W3C.

Je ne travail pas en HTML5

Cela signifie donc que l'attribut scoped ne peut pas être utilisé et qu'il faut lui préférer <style type="text/css">. Cependant, même avec toute votre bonne volonté en plus, l'attribut style est invalide en dehors de la balise <head>.

Actuellement, même si vous ne passerez pas la validation la quasi totalité des navigateurs qui savent lire les Média Queries sauront exécuter le style dans le body. Mais parceque les standards ne sont pas fait pour les chiens, vous pouvez soit :

  • Migrer votre site en HTML5 pour utiliser ce type de fonctionnalité.
  • Faire comme ce blog : proposer un chanp textarea pour entrer toutes les instructions CSS souhaitées lors de la rédaction d'un article, et injecter son contenu dans une balise <style> située après les balises <link> de la balise <head> lors de son rendu côté serveur.
  • Ne pas l'utiliser :)

Un petit mot sur les performances

N'ayez point peur, du fait que les instructions CSS (même si elles sont dans une feuille CSS à part) bloquent le rendu de votre page le temps qu'elles soient analysées, cela revient donc au même de placer vos instructions dans la page en amont des balises à habiller.

Ça allégera vos feuilles CSS qui n'ont pas besoin de déclarations spécifiques pour des éléments affichés uniquement sur la page courante.