É possível colocar as regras CSS @media em linha?

293

Preciso carregar dinamicamente imagens de banner em um aplicativo HTML5 e gostaria de duas versões diferentes para se adequar às larguras da tela. Como não consigo determinar corretamente a largura da tela do telefone, a única maneira de pensar nisso é adicionar imagens de plano de fundo de uma div e usar @media para determinar a largura da tela e exibir a imagem correta.

Por exemplo:

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

Isso é possível ou alguém tem outras sugestões?

Dançarino
fonte
3
Decepcionado com as respostas? Veja este comentário . Isso pode ajudar.
Rinogo 4/08

Respostas:

285

Não, @mediaregras e consultas de mídia não podem existir em atributos de estilo embutido, pois podem conter apenas property: valuedeclarações. Como as especificações colocam:

O valor do atributo style deve corresponder à sintaxe do conteúdo de um bloco de declaração CSS

A única maneira de aplicar estilos a um elemento apenas em determinadas mídias é com uma regra separada na sua folha de estilo, o que significa que você precisará criar um seletor para ele.

Um spanseletor fictício se pareceria com isso, mas se você estiver segmentando um elemento muito específico, precisará de um seletor mais específico:

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

@media (max-width: 300px) {
    span { background-image: url(particular_ad_small.png); }
}
BoltClock
fonte
70
Você também pode colocar uma <style>tag no seu HTML também. Essa é uma abordagem necessária para o caso em que background-imageé extraído dinamicamente de um banco de dados. Obviamente, na folha de estilo externa não é o lugar certo para isso.
Jake Wilson
1
@ Jakobud: Sim, não importa onde a folha de estilo está localizada, mas o ponto é que você só pode fazer isso em CSS, não em um atributo de estilo embutido.
BoltClock
3
Observe para futuros exploradores que a <script>tag geralmente é removida pelos clientes de email quando um email é encaminhado; portanto, as pessoas tendem a usar estilos in-line para emails. E isso significa que não há consultas de mídia. Atualmente, estou procurando as melhores práticas para essa situação, mas apenas um aviso amigável.
TCannadySF
3
Defina a largura máxima em ems, não em px. Dessa forma, ainda funcionará com sensatez ao aumentar o zoom.
Silas S. Brown
2
@Silas S. Brown: Esse não é o meu problema. Estou apenas refletindo o que é usado na pergunta.
BoltClock
137

Problema

Não, as consultas de mídia não podem ser usadas dessa maneira

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

Solução

Mas se você deseja fornecer um comportamento específico utilizável em tempo real e responsivo, pode usar a stylemarcação e não o 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>

Veja o código trabalhando ao vivo no CodePen

No meu Blog, por exemplo, injeto uma <style>marcação <head>logo após a <link>declaração para CSS e ela contém o conteúdo de uma área de texto fornecida ao lado da área de texto de conteúdo real para criar classe extra em tempo real quando escrevi um artigo.

Nota: o scopedatributo faz parte da especificação HTML5. Se você não o usar, o validador o culpará, mas os navegadores atualmente não suportam o objetivo real: definir o escopo do conteúdo <style>apenas no elemento pai imediatamente e nos elementos filhos desse elemento. O escopo não é obrigatório se o <style>elemento estiver na <head>marcação.


ATUALIZAÇÃO: Eu aconselho a sempre usar as regras da maneira móvel para que o código anterior seja:

<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
fonte
10
Essa é uma resposta melhor que a resposta aceita, pois permite alterar dinamicamente background-imagequando a página é carregada.
Jake Wilson
7
Embora o escopo pareça ótimo em princípio, o Chrome removeu o suporte preliminar algumas versões anteriores e agora apenas o Firefox tem suporte.
Anthony McLin
1
O escopo é usado apenas para não permitir o .on-the-fly-behavioruso em qualquer lugar, mas se a palavra for «ignorar» por algum navegador, não será um problema. <style> pode ser usado em <body> em todo navegador, é trabalho. É apenas um requisito de validação do w3c.
de Bruno Lesieur
4
Embora scopedseja uma solução brilhante, não é oficialmente suportada por nenhum navegador. Espero que isso mude em breve.
Ken afiada
1
Esta é uma outra questão, porque o objetivo principal de um e-mail deve ser leitura por um cliente de email e muitos clientes e-mail não suportam a incorporação <style>, ou media queriesou todos os recursos HTML / CSS. Então, na verdade, o problema é maior do que isso. Eu sei apenas que você é capaz de criar e-mails exibidos da mesma maneira em todos os E-mails de Clientes (Gmail incluído) com apenas o recurso HTML4 e CSS2 (com algum hack do Outlook), mas não há Consultas de Mídia neste caso.
Bruno Lesieur
15

No momento, os estilos embutidos não podem conter nada além de declarações ( property: valuepares).

Você pode usar styleelementos com mediaatributos apropriados na headseção do seu documento.

Marat Tanalin
fonte
13

Sim, você pode escrever uma consulta de mídia em CSS embutido se estiver usando uma marca de imagem. Para diferentes tamanhos de dispositivo, você pode obter imagens diferentes.

<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
fonte
Isso não se aplica à imagem de plano de fundo do CSS: url ()
Jonas Eberle 4/19
10

Se você estiver usando os Bootstrap Responsive Utilities ou uma alternativa semelhante que permita ocultar / mostrar divs, dependendo dos pontos de interrupção, pode ser possível usar vários elementos e mostrar o mais apropriado. ie

 <span class="hidden-xs" style="background: url(particular_ad.png)"></span>
 <span class="visible-xs" style="background: url(particular_ad_small.png)"></span>
Pavel
fonte
3
Solução alternativa bonita - ocultar div, mostrar div com base na consulta de mídia - a única desvantagem que vejo é que ainda carregará as duas imagens para que você as envie ao cliente.
Michael C. Gates,
4
Conteúdo duplicado não é bom para manutenção ou SEO.
Bruno Lesieur 14/10
1
Infelizmente, este é um falso amigo! Também pensei nessa solução, mas queremos que imagens menores sirvam para dispositivos pequenos e economizem bytes para fazer o download. Esta técnica faz exatamente o oposto
A. D'Alfonso
8

As consultas de mídia em Atributos de estilo não são possíveis no momento. Mas se você tiver que definir isso dinamicamente via Javascript. Você pode inserir essa regra via JS também.

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

É como se o estilo estivesse na folha de estilo. Portanto, esteja ciente da especificidade.

Tipo-Estilo
fonte
alguma idéia de quando será possível?
precisa
1
Eu não acho que será. Mas não estou ciente de todas as coisas que os grupos de trabalho estão fazendo.
Tipo-Style
8

Ei, acabei de escrever.

Agora você pode usar mais <div style="color: red; @media (max-width: 200px) { color: green }">ou menos.

Aproveitar.

Даниил Пронин
fonte
Eu votei isso, já que parecia funcionar naquela época, mas não é. #sad
honk31
@ honk31 ele mundo apenas para um em regra
Даниил Пронин
7

Tentei testar isso e ele não parecia funcionar, mas estou curioso para saber por que a Apple está usando. Eu estava apenas em https://linkmaker.itunes.apple.com/us/ e notei o código gerado que fornece se você selecionar o botão de opção 'Botão grande', eles estão usando uma consulta de mídia embutida.

<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: quebras de linha adicionadas para facilitar a leitura, o código gerado original é reduzido

davidcondrey
fonte
3
Eu gostaria de saber por que / como a Apple está usando esse também
Douglas.Sesar
1
O código citado não existe mais no link fornecido (pelo menos para mim; talvez eu receba conteúdo diferente por estar fora dos EUA). Além disso, isso realmente parece mais uma pergunta separada que uma resposta.
Mark Amery
1
Enviei um relatório de erro e acredito que eles o tenham removido. itunesaffiliate.phgsupport.com/hc/en-us/requests/14201
davidcondrey
4

Você pode usar o conjunto de imagens ()

<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
fonte
2
Observe que isso é suportado apenas em navegadores baseados no Webkit no momento.
Qqwy
Isso não funciona com base no tamanho (conforme descrito na pergunta), mas no fator de zoom, então você pode obter a imagem para telas pequenas em uma tela de 27 "2560x1440. Pode ser o que você deseja - ou talvez não.
Jan Bühler
4

sim, você pode usar javascript na janela window.matchMedia

  1. área de trabalho para texto em vermelho

  2. tablet para texto em cor verde

  3. móvel para texto em cor 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î
fonte
3

Consultas de mídia em linha são possíveis usando algo como Breakpoint for Sass

Esta postagem do blog explica bem como as consultas de mídia embutida são mais gerenciáveis ​​do que blocos separados: Não há ponto de interrupção

Relacionada às consultas de mídia embutida está a ideia de "consultas de elemento", algumas leituras interessantes são:

  1. Pensamentos sobre consultas de mídia para elementos
  2. Consultas de mídia são um hack
  3. Consultas de mídia não são a resposta: Polyfill de consulta de elemento
  4. se mais bloquear
Rafael Lüder
fonte
1

se você adicionar a regra ao arquivo print.css, não precisará usar @media.

Eu o incluí no smarty foreach que eu uso para dar a alguns elementos uma cor de fundo.

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

Paul Wolbers
fonte