¿Es posible poner reglas CSS @media en línea?

293

Necesito cargar dinámicamente imágenes de banner en una aplicación HTML5 y quisiera un par de versiones diferentes para adaptarse a los anchos de pantalla. No puedo determinar correctamente el ancho de pantalla del teléfono, por lo que la única forma en que puedo pensar en hacerlo es agregar imágenes de fondo de un div y usar @media para determinar el ancho de pantalla y mostrar la imagen correcta.

Por ejemplo:

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

¿Es esto posible o alguien tiene alguna otra sugerencia?

Bailarín
fuente
3
¿Decepcionado con las respuestas? Ver este comentario . Puede ayudar.
rinogo

Respuestas:

285

No, @medialas consultas de reglas y medios no pueden existir en atributos de estilo en línea, ya que solo pueden contener property: valuedeclaraciones. Como dice la especificación :

El valor del atributo de estilo debe coincidir con la sintaxis del contenido de un bloque de declaración CSS

La única forma de aplicar estilos a un elemento solo en ciertos medios es con una regla separada en su hoja de estilos, lo que significa que deberá encontrar un selector para ello.

Un spanselector ficticio se vería así, pero si está apuntando a un elemento muy específico, necesitará un selector más específico:

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

@media (max-width: 300px) {
    span { background-image: url(particular_ad_small.png); }
}
BoltClock
fuente
70
También puede simplemente poner una <style>etiqueta en su HTML también. Este es un enfoque necesario para el caso en el que background-imagese extrae dinámicamente de una base de datos. Obviamente en la hoja de estilo externa no es el lugar adecuado para eso.
Jake Wilson
1
@Jakobud: Sí, no importa dónde se encuentre la hoja de estilo, pero el punto es que solo puedes hacer esto en CSS, no en un atributo de estilo en línea.
BoltClock
3
Tenga en cuenta para los futuros exploradores que los <script>clientes de correo electrónico a menudo eliminan la etiqueta cuando se reenvía un correo electrónico, por lo que las personas tienden a usar estilos en línea para los correos electrónicos. Y esto significa que no hay consultas de los medios. Actualmente estoy buscando las mejores prácticas para esta situación, pero solo un aviso amistoso.
TCannadySF
3
Establezca max-width en ems, no en px. De esa manera, seguirá funcionando con sensatez cuando haga zoom.
Silas S. Brown
2
@Silas S. Brown: Ese no es mi problema. Solo estoy reflejando lo que se usa en la pregunta.
BoltClock
137

Problema

No, las consultas de medios no se pueden usar de esta manera

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

Solución

Pero si desea proporcionar un comportamiento específico que se pueda usar sobre la marcha Y que responda, puede usar el stylemarcado y no el atributo.

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>

Vea el código trabajando en vivo en CodePen

En mi blog, por ejemplo, inserto un <style>marcado <head>justo después de la <link>declaración de CSS y contiene el contenido de un área de texto proporcionada junto al área de texto de contenido real para crear una clase adicional sobre la marcha cuando escribí un artículo.

Nota: el scopedatributo es parte de la especificación HTML5. Si no lo usa, el validador lo culpará, pero los navegadores actualmente no son compatibles con el propósito real: limitar el contenido <style>solo al elemento primario inmediato y a los elementos secundarios de ese elemento. El alcance no es obligatorio si el <style>elemento está <head>marcado.


ACTUALIZACIÓN: Aconsejo usar siempre las reglas en el móvil de la primera manera, por lo que el código anterior debería ser:

<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
fuente
10
Esta es una mejor respuesta que la respuesta aceptada porque le permite cambiar dinámicamente background-imagecuando se carga la página.
Jake Wilson
77
Si bien el alcance parece excelente en principio, Chrome eliminó su soporte preliminar algunas versiones atrás y ahora solo Firefox tiene algún tipo de soporte.
Anthony McLin
1
El alcance solo se usa para no permitir .on-the-fly-behaviorque se use en cualquier lugar, pero si la palabra es "ignorar" por algún navegador no es un problema. <style> puede usarse en <body> en todos los navegadores, es trabajo. Es solo un requisito de validación de w3c.
Bruno Lesieur
44
Aunque scopedes una solución brillante, no es oficialmente compatible con ningún navegador. Espero que cambie pronto.
Ken Sharp
1
Este es otro problema, ya que el objetivo principal de un correo electrónico se va a leer por un cliente de correo electrónico y muchos cliente de correo electrónico no son compatibles con la incrustación <style>, o media queriestodos o característica de HTML / CSS. Entonces, en realidad el problema es más grande que eso. Solo sé que puede crear el correo electrónico que se muestra de la misma manera en todos los correos electrónicos del cliente (incluido Gmail) con solo la función HTML4 y CSS2 (con algún truco de Outlook), pero no hay consultas de medios en este caso.
Bruno Lesieur
15

Los estilos en línea no pueden contener nada más que declaraciones ( property: valuepares).

Puede usar styleelementos con los mediaatributos apropiados en la headsección de su documento.

Marat Tanalin
fuente
13

Sí, puede escribir una consulta de medios en inline-css si está usando una etiqueta de imagen. Para diferentes tamaños de dispositivo, puede obtener diferentes imágenes.

<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
fuente
Esto no se aplica a la imagen de fondo CSS: url ()
Jonas Eberle
10

Si está utilizando Bootstrap Responsive Utilities o una alternativa similar que permite ocultar / mostrar divs dependiendo de los puntos de ruptura, es posible que pueda usar varios elementos y mostrar el más apropiado. es decir

 <span class="hidden-xs" style="background: url(particular_ad.png)"></span>
 <span class="visible-xs" style="background: url(particular_ad_small.png)"></span>
Pavel
fuente
3
Hermosa solución: ocultar div, mostrar div en función de la consulta de medios: el único inconveniente que veo es que todavía cargará ambas imágenes, por lo que las enviaría al cliente.
Michael C. Gates
44
El contenido duplicado no es bueno para el mantenimiento o el SEO.
Bruno Lesieur
1
¡Lamentablemente este es un falso amigo! También pensé en esta solución, pero queremos una imagen más pequeña para servir en dispositivos pequeños y guardar bytes para descargar. Esta técnica hace exactamente lo contrario
A. D'Alfonso
8

Las consultas de medios en atributos de estilo no son posibles en este momento. Pero si tiene que configurar esto dinámicamente a través de Javascript. También puede insertar esa regla a través de JS.

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

Esto es como si el estilo estuviera allí en la hoja de estilos. Así que tenga en cuenta la especificidad.

Tipo-estilo
fuente
alguna idea de cuándo será posible?
SuperUberDuper
1
No creo que lo sea. Pero no estoy al tanto de todas las cosas que están haciendo los grupos de trabajo.
Tipo-estilo
8

Hola, acabo de escribirlo.

Ahora puedes usar más <div style="color: red; @media (max-width: 200px) { color: green }">o menos.

Disfrutar.

Даниил Пронин
fuente
He votado esto, ya que parecía funcionar en ese entonces, pero no lo es. #sad
honk31
@ honk31 es el mundo solo para un gobernante
Даниил Пронин
7

Traté de probar esto y no parecía funcionar, pero tengo curiosidad de por qué Apple lo está usando. Estaba en https://linkmaker.itunes.apple.com/us/ y noté que en el código generado que proporciona si selecciona el botón de opción 'Botón grande', están utilizando una consulta de medios en línea.

<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>

nota: saltos de línea agregados para facilitar la lectura, el código generado original se minimiza

davidcondrey
fuente
3
Me gustaría saber por qué / cómo Apple está usando eso también
Douglas.Sesar
1
El código citado ya no existe en el enlace dado (al menos para mí; tal vez obtengo contenido diferente debido a que estoy fuera de los EE. UU.). Además, esto realmente parece más una pregunta separada que una respuesta.
Mark Amery
1
Envié un informe de error y creo que desde entonces lo han eliminado. itunesaffiliate.phgsupport.com/hc/en-us/requests/14201
davidcondrey
4

Puedes usar 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
fuente
2
Tenga en cuenta que esto solo se admite en los navegadores basados ​​en Webkit en este momento.
Qqwy
Esto no funciona en función del tamaño (como se describe en la pregunta) sino del factor de zoom, por lo que puede obtener la imagen para pantallas pequeñas en una pantalla de 27 "2560x1440. Eso podría ser lo que quieres, o tal vez no.
Jan Bühler
4

sí, puedes hacerlo con javascript mediante window.matchMedia

  1. escritorio para texto en color rojo

  2. tableta para texto en color verde

  3. móvil para texto en color azul

//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î
fuente
3

Las consultas de medios en línea son posibles mediante el uso de algo como Breakpoint for Sass

Esta publicación de blog hace un buen trabajo explicando cómo las consultas de medios en línea son más manejables que los bloques separados: No hay punto de interrupción

Relacionado con las consultas de medios en línea está la idea de "consultas de elementos", algunas lecturas interesantes son:

  1. Reflexiones sobre consultas de medios para elementos
  2. Las consultas de medios son un truco
  3. Las consultas de medios no son la respuesta: Polyfill de consulta de elementos
  4. si otra cosa bloquea
Rafael Lüder
fuente
1

si agrega la regla al archivo print.css, no tiene que usar @media.

Lo desconecté en el smarty foreach que uso para dar a algunos elementos un color de fondo.

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

Paul Wolbers
fuente