Est-il possible de mettre les règles CSS @media en ligne?

293

J'ai besoin de charger dynamiquement des images de bannière dans une application HTML5 et j'aimerais que deux versions différentes correspondent à la largeur de l'écran. Je ne peux pas déterminer correctement la largeur d'écran du téléphone, donc la seule façon d'y penser est d'ajouter des images d'arrière-plan d'un div et d'utiliser @media pour déterminer la largeur d'écran et afficher l'image correcte.

Par exemple:

 <span style="background-image:particular_ad.png; @media (max-width:300px){background-image:particular_ad_small.png;}"></span>

Est-ce possible ou quelqu'un a-t-il d'autres suggestions?

Danseur
la source
3
Déçu des réponses? Voir ce commentaire . Cela peut aider.
rinogo

Réponses:

285

Non, les @mediarègles et les requêtes multimédias ne peuvent pas exister dans les attributs de style en ligne car elles ne peuvent contenir que des property: valuedéclarations. Comme le dit la spécification :

La valeur de l'attribut style doit correspondre à la syntaxe du contenu d'un bloc de déclaration CSS

La seule façon d'appliquer des styles à un élément uniquement sur certains supports est d'utiliser une règle distincte dans votre feuille de style, ce qui signifie que vous devrez créer un sélecteur pour celui-ci.

Un spansélecteur factice ressemblerait à ceci, mais si vous ciblez un élément très spécifique, vous aurez besoin d'un sélecteur plus spécifique:

span { background-image: url(particular_ad.png); }

@media (max-width: 300px) {
    span { background-image: url(particular_ad_small.png); }
}
BoltClock
la source
70
Vous pouvez également simplement insérer une <style>balise dans votre code HTML. Il s'agit d'une approche nécessaire dans le cas où le background-imageest extrait dynamiquement d'une base de données. De toute évidence, la feuille de style externe n'est pas le bon endroit pour cela.
Jake Wilson
1
@Jakobud: Oui, peu importe où se trouve la feuille de style, mais le fait est que vous ne pouvez le faire qu'en CSS, pas un attribut de style en ligne.
BoltClock
3
Notez aux futurs explorateurs que la <script>balise est souvent supprimée par les clients de messagerie lorsqu'un e-mail est transféré, de sorte que les gens ont tendance à utiliser des styles en ligne pour les e-mails. Et cela signifie aucune interrogation des médias. Je recherche actuellement les meilleures pratiques pour cette situation, mais juste un heads-up amical.
TCannadySF
3
Veuillez définir la largeur maximale en ems, pas en px. De cette façon, cela fonctionnera toujours sensiblement lorsque vous zoomerez.
Silas S. Brown
2
@Silas S. Brown: Ce n'est pas mon problème. Je ne fais que refléter ce qui est utilisé dans la question.
BoltClock
137

Problème

Non, les requêtes multimédias ne peuvent pas être utilisées de cette manière

<span style="@media (...) { ... }"></span>

Solution

Mais si vous voulez fournir un comportement spécifique utilisable à la volée ET réactif, vous pouvez utiliser le stylebalisage et non l'attribut.

ei

<style scoped>
.on-the-fly-behavior {
    background-image: url('particular_ad.png'); 
}
@media (max-width: 300px) {
    .on-the-fly-behavior {
        background-image: url('particular_ad_small.png');
    }
}
</style>
<span class="on-the-fly-behavior"></span>

Voir le code en direct sur CodePen

Dans mon blog par exemple, j'injecte un <style>balisage <head>juste après la <link>déclaration pour CSS et il contient le contenu d'une zone de texte fournie à côté de la zone de texte de contenu réel pour créer une classe supplémentaire à la volée lorsque j'ai écrit un article.

Remarque: l' scopedattribut fait partie de la spécification HTML5. Si vous ne l'utilisez pas, le validateur vous en voudra mais les navigateurs ne prennent actuellement pas en charge le véritable objectif: délimiter le contenu de <style>uniquement sur l'élément immédiatement parent et les éléments enfants de cet élément. La portée n'est pas obligatoire si l' <style>élément est en <head>balisage.


MISE À JOUR: Je conseille de toujours utiliser les règles dans le premier mobile, donc le code précédent devrait être:

<style scoped>
/* 0 to 299 */
.on-the-fly-behavior {
    background-image: url('particular_ad_small.png'); 
}
/* 300 to X */
@media (min-width: 300px) { /* or 301 if you want really the same as previously.  */
    .on-the-fly-behavior {   
        background-image: url('particular_ad.png');
    }
}
</style>
<span class="on-the-fly-behavior"></span>
Bruno Lesieur
la source
10
C'est une meilleure réponse que la réponse acceptée car elle vous permet de changer dynamiquement le background-imagemoment où la page se charge.
Jake Wilson
7
Bien que la portée semble excellente en principe, Chrome a supprimé son support préliminaire de quelques versions en arrière et maintenant seul Firefox a un support quel qu'il soit.
Anthony McLin
1
Scoped est juste utilisé pour ne .on-the-fly-behaviorpas être utilisé n'importe où, mais si le mot est «ignoré» par un navigateur, ce n'est pas un problème. <style> peut être utilisé dans <body> dans tous les navigateurs, cela fonctionne. C'est juste une exigence de validation w3c.
Bruno Lesieur
4
Bien qu'il s'agisse d' scopedune solution brillante, elle n'est officiellement prise en charge par aucun navigateur. Espérons que cela changera bientôt.
Ken Sharp
1
Ceci est une autre question, car l'objectif principal d'un e-mail est d'être lu par un e-mail client et de nombreux e-mails clients ne prennent pas en charge l'incorporation <style>, media queriesou la totalité des fonctionnalités HTML / CSS. Donc, en réalité, le problème est plus grave que cela. Je sais seulement que vous pouvez créer des e-mails affichés de la même manière sur tous les e-mails clients (Gmail inclus) avec uniquement les fonctionnalités HTML4 et CSS2 (avec un certain piratage Outlook), mais il n'y a pas de requêtes multimédias dans ce cas.
Bruno Lesieur
15

Les styles en ligne ne peuvent actuellement contenir que des déclarations ( property: valuepaires).

Vous pouvez utiliser des styleéléments avec les mediaattributs appropriés dans la headsection de votre document.

Marat Tanalin
la source
13

Oui, vous pouvez écrire une requête média en inline-css si vous utilisez un tag d'image. Pour différentes tailles d'appareils, vous pouvez obtenir différentes images.

<picture>
    <source media="(min-width: 650px)" srcset="img_pink_flowers.jpg">
    <source media="(min-width: 465px)" srcset="img_white_flower.jpg">
    <img src="img_orange_flowers.jpg" alt="Flowers" style="width:auto;">
</picture>
Arif Hussain
la source
Cela ne s'applique pas à l'image d'arrière-plan CSS: url ()
Jonas Eberle
10

Si vous utilisez Bootstrap Responsive Utilities ou une alternative similaire qui permet de masquer / afficher les div en fonction des points d'arrêt, il peut être possible d'utiliser plusieurs éléments et d'afficher le plus approprié. c'est à dire

 <span class="hidden-xs" style="background: url(particular_ad.png)"></span>
 <span class="visible-xs" style="background: url(particular_ad_small.png)"></span>
Pavel
la source
3
Belle solution de contournement - masquer div, afficher div en fonction de la requête multimédia - le seul inconvénient que je vois est qu'il chargera toujours les deux images de sorte que vous enverriez les deux au client.
Michael
4
Le contenu en double n'est pas une bonne chose pour la maintenance ou le référencement.
Bruno Lesieur
1
Malheureusement, c'est un faux ami! J'ai aussi pensé à cette solution, mais nous voulons qu'une image plus petite soit diffusée sur de petits appareils et économise des octets à télécharger. Cette technique fait exactement le contraire
A. D'Alfonso
8

Les requêtes multimédias dans les attributs de style ne sont pas possibles pour le moment. Mais si vous devez définir cela dynamiquement via Javascript. Vous pouvez également insérer cette règle via JS.

document.styleSheets[0].insertRule("@media only screen and (max-width : 300px) { span { background-image:particular_ad_small.png; } }","");

C'est comme si le style était là dans la feuille de style. Soyez donc conscient de la spécificité.

Type-Style
la source
des idées quand ce sera possible?
SuperUberDuper
1
Je ne pense pas que ce sera le cas. Mais je ne suis pas au courant de tout ce que font les groupes de travail.
Type-Style
8

Hé je viens de l'écrire.

Maintenant, vous pouvez utiliser <div style="color: red; @media (max-width: 200px) { color: green }">ou ainsi.

Prendre plaisir.

Даниил Пронин
la source
J'ai voté pour cela, car cela semblait fonctionner à l'époque, mais ce n'est pas le cas. #sad
honk31
@ honk31 it world only for one at-rule
Даниил Пронин
7

J'ai essayé de tester cela et cela ne semble pas fonctionner mais je suis curieux de savoir pourquoi Apple l'utilise. J'étais juste sur https://linkmaker.itunes.apple.com/us/ et j'ai remarqué dans le code généré qu'il fournit si vous sélectionnez le bouton radio "Grand bouton", ils utilisent une requête multimédia en ligne.

<a href="#" 
    target="itunes_store" 
    style="
        display:inline-block;
        overflow:hidden;
        background:url(#.png) no-repeat;
        width:135px;
        height:40px;
        @media only screen{
            background-image:url(#);
        }
"></a>

remarque: ajout de sauts de ligne pour plus de lisibilité, le code généré d'origine est réduit

davidcondrey
la source
3
Je voudrais savoir pourquoi / comment Apple utilise cela aussi
Douglas.Sesar
1
Le code cité n'existe plus sur le lien donné (du moins pour moi; peut-être que j'obtiens un contenu différent parce que je suis en dehors des États-Unis). En plus, cela ressemble plus à une question séparée qu'à une réponse.
Mark Amery
1
J'ai soumis un rapport de bogue et je pense qu'ils l'ont supprimé depuis. itunesaffiliate.phgsupport.com/hc/en-us/requests/14201
davidcondrey
4

Vous pouvez utiliser image-set ()

<div style="
  background-image: url(icon1x.png);
  background-image: -webkit-image-set(  
    url(icon1x.png) 1x,  
    url(icon2x.png) 2x);  
  background-image: image-set(  
    url(icon1x.png) 1x,  
    url(icon2x.png) 2x);">
the7oker
la source
2
Notez que ceci n'est actuellement pris en charge que dans les navigateurs Webkit .
Qqwy
Cela ne fonctionne pas en fonction de la taille (comme indiqué dans la question) mais du facteur de zoom, vous pouvez donc obtenir l'image pour les petits écrans sur un écran 27 "2560x1440. C'est peut-être ce que vous voulez - ou peut-être pas.
Jan Bühler
4

oui, vous pouvez le faire avec javascript par le window.matchMedia

  1. bureau pour le texte de couleur rouge

  2. tablette pour texte de couleur verte

  3. mobile pour le texte de couleur bleue

//isat_style_media_query_for_desktop_mobile_tablets
var tablets = window.matchMedia("(max-width:  768px)");//for tablet devices
var mobiles = window.matchMedia("(max-width: 480px)");//for mobile devices
var desktops = window.matchMedia("(min-width: 992px)");//for desktop devices



isat_find_device_tablets(tablets);//apply style for tablets
isat_find_device_mobile(mobiles);//apply style for mobiles
isat_find_device_desktops(desktops);//apply style for desktops
// isat_find_device_desktops(desktops,tablets,mobiles);// Call listener function at run time
tablets.addListener(isat_find_device_tablets);//listen untill detect tablet screen size
desktops.addListener(isat_find_device_desktops);//listen untill detect desktop screen size
mobiles.addListener(isat_find_device_mobile);//listen untill detect mobile devices
// desktops.addListener(isat_find_device_desktops);

 // Attach listener function on state changes

function isat_find_device_mobile(mob)
{
  
// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="blue";

// isat mobile style here

}

function isat_find_device_desktops(des)
{

// isat mobile style here

var daynight=document.getElementById("daynight");
daynight.style.color="red";
 
//  isat mobile style here
}

function isat_find_device_tablets(tab)
{

// isat mobile style here
var daynight=document.getElementById("daynight");
daynight.style.color="green";

//  isat mobile style here
}


//isat_style_media_query_for_desktop_mobile_tablets
    <div id="daynight">tricky style for mobile,desktop and tablet</div>

ßãlãjî
la source
3

Les requêtes de médias en ligne sont possibles en utilisant quelque chose comme Breakpoint for Sass

Ce billet de blog explique bien comment les requêtes multimédias en ligne sont plus faciles à gérer que les blocs séparés: il n'y a pas de point d'arrêt

L'idée des «requêtes d'éléments» est liée aux requêtes de médias en ligne, voici quelques lectures intéressantes:

  1. Réflexions sur les requêtes média pour les éléments
  2. Les requêtes média sont un hack
  3. Les requêtes multimédias ne sont pas la réponse: Element Query Polyfill
  4. si autre bloque
Rafael Lüder
la source
1

si vous ajoutez la règle au fichier print.css, vous n'avez pas besoin d'utiliser @media.

Je l'ai exclu dans le smarty foreach que j'utilise pour donner à certains éléments une couleur d'arrière-plan.

<script type='text/javascript'>
  document.styleSheets[3].insertRule(" #caldiv_<?smarty $item.calendar_id ?> { border-color:<?smarty $item.color ?> }", 1);
</script>

Paul Wolbers
la source