Czy można wstawiać reguły CSS @media?

293

Potrzebuję dynamicznie ładować obrazy banerów do aplikacji HTML5 i chciałbym, aby kilka różnych wersji pasowało do szerokości ekranu. Nie mogę poprawnie określić szerokości ekranu telefonu, więc jedynym sposobem, aby to zrobić, jest dodanie obrazów tła div i użycie @media do określenia szerokości ekranu i wyświetlenia prawidłowego obrazu.

Na przykład:

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

Czy to możliwe, czy ktoś ma jakieś inne sugestie?

Tancerz
źródło
3
Rozczarowany odpowiedziami? Zobacz ten komentarz . To może pomóc.
rinogo,

Odpowiedzi:

284

Nie, @mediareguły i zapytania multimedialne nie mogą istnieć w atrybutach stylu wbudowanego, ponieważ mogą zawierać tylko property: valuedeklaracje. Zgodnie ze specyfikacją :

Wartość atrybutu stylu musi być zgodna ze składnią treści bloku deklaracji CSS

Jedynym sposobem zastosowania stylów do elementu tylko w niektórych mediach jest oddzielna reguła w arkuszu stylów, co oznacza, że ​​musisz wymyślić selektor dla tego elementu.

Atrapa spanselektora wyglądałaby tak, ale jeśli celujesz w bardzo konkretny element, potrzebujesz bardziej szczegółowego selektora:

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

@media (max-width: 300px) {
    span { background-image: url(particular_ad_small.png); }
}
BoltClock
źródło
70
Możesz także po prostu wstawić <style>tag w swoim HTML. Jest to konieczne podejście w przypadku, gdy dane background-imagesą dynamicznie pobierane z bazy danych. Oczywiście w zewnętrznym arkuszu stylów nie jest do tego odpowiednie miejsce.
Jake Wilson
1
@Jobobud: Tak, nie ma znaczenia, gdzie znajduje się arkusz stylów, ale chodzi o to, że możesz to zrobić tylko w CSS, a nie w atrybucie stylu.
BoltClock
3
Zwróć uwagę przyszłym odkrywcom, że <script>znacznik jest często usuwany przez klientów poczty e-mail, gdy wiadomość e-mail jest przesyłana dalej, więc ludzie często używają stylów wbudowanych w wiadomościach e-mail. A to oznacza brak zapytań o media. Obecnie szukam najlepszych praktyk w tej sytuacji, ale tylko przyjaznego heads-upa.
TCannadySF
3
Proszę ustawić maksymalną szerokość emws, a nie w px. W ten sposób nadal będzie działać rozsądnie podczas powiększania.
Silas S. Brown
2
@Silas S. Brown: To nie jest mój problem. Po prostu zastanawiam się, co zostało użyte w pytaniu.
BoltClock
137

Problem

Nie, zapytań o media nie można używać w ten sposób

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

Rozwiązanie

Ale jeśli chcesz zapewnić określone zachowanie możliwe do użycia w locie ORAZ responsywne, możesz użyć styleznaczników, a nie atrybutu.

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>

Zobacz kod działający na żywo w CodePen

Na przykład na moim blogu wstawiam <style>znacznik <head>tuż po <link>deklaracji dla CSS i zawiera on zawartość obszaru tekstowego dostarczonego obok rzeczywistego obszaru tekstowego, aby stworzyć dodatkową klasę w locie, gdy pisałem artykuł.

Uwaga: ten scopedatrybut jest częścią specyfikacji HTML5. Jeśli go nie użyjesz, walidator będzie cię winił, ale przeglądarki obecnie nie obsługują prawdziwego celu: zakres zawartości <style>tylko elementu bezpośrednio nadrzędnego i elementów potomnych tego elementu. Zakres nie jest obowiązkowy, jeśli <style>element jest <head>oznaczony.


AKTUALIZACJA: Radzę, aby zawsze używać reguł w telefonie komórkowym, więc poprzedni kod powinien być:

<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
źródło
10
Jest to lepsza odpowiedź niż odpowiedź zaakceptowana, ponieważ pozwala dynamicznie zmieniać czas background-imageładowania strony.
Jake Wilson
7
Chociaż zakres wydaje się w zasadzie świetny, Chrome usunął swoje wstępne wsparcie kilka wersji wstecz, a teraz tylko Firefox ma jakiekolwiek wsparcie.
Anthony McLin,
1
Scope jest po prostu używany, aby nie pozwalać .on-the-fly-behaviorna użycie go gdziekolwiek, ale jeśli słowo to jest ignorowane przez jakiegoś nawigatora, nie stanowi problemu. <style> może być użyte w <body> we wszystkich nawigatorach, to działa. To tylko wymóg sprawdzania poprawności w3c.
Bruno Lesieur
4
Chociaż scopedjest to genialne rozwiązanie, nie jest oficjalnie obsługiwane przez żadną przeglądarkę. Mam nadzieję, że wkrótce się to zmieni.
Ken Sharp
1
Jest to inna kwestia, ponieważ głównym celem jest e-mail do czytania przez klienta poczty i wiele klient poczty elektronicznej nie obsługuje osadzanie <style>lub media querieslub wszystkich funkcji HTML / CSS. Więc tak naprawdę problem jest większy. Wiem tylko, że możesz tworzyć wiadomości e-mail wyświetlane w ten sam sposób na wszystkich wiadomościach e-mail klientów (w tym Gmail) tylko z funkcją HTML4 i CSS2 (z pewnym włamaniem do programu Outlook), ale w tym przypadku nie ma zapytań o media.
Bruno Lesieur,
15

Style wbudowane nie mogą obecnie zawierać niczego poza deklaracjami ( property: valueparami).

W sekcji dokumentu możesz używać styleelementów o odpowiednich mediaatrybutach head.

Marat Tanalin
źródło
13

Tak, możesz napisać zapytanie o media w inline-css, jeśli używasz tagu graficznego. Dla różnych rozmiarów urządzeń można uzyskać różne obrazy.

<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
źródło
Nie dotyczy to obrazu tła CSS: url ()
Jonas Eberle,
10

Jeśli używasz narzędzi responsywnych Bootstrap lub podobnej alternatywy, która pozwala ukryć / pokazać div w zależności od punktów przerwania, możliwe jest użycie kilku elementów i pokazanie najbardziej odpowiednich. to znaczy

 <span class="hidden-xs" style="background: url(particular_ad.png)"></span>
 <span class="visible-xs" style="background: url(particular_ad_small.png)"></span>
Pavel
źródło
3
Piękne obejście - ukryj div, pokaż div na podstawie zapytania medialnego - jedyną wadą, jaką widzę, jest to, że nadal ładuje oba obrazy, więc możesz wysłać oba do klienta.
Michael C. Gates
4
Duplikaty treści nie są dobre dla utrzymania lub SEO.
Bruno Lesieur
1
Niestety jest to fałszywy przyjaciel! Myślałem też o tym rozwiązaniu, ale chcemy, aby mniejszy obraz był wyświetlany małym urządzeniom i oszczędzał bajty do pobrania. Ta technika działa dokładnie odwrotnie
A. D'Alfonso
8

Zapytania o media w atrybutach stylu nie są teraz możliwe. Ale jeśli musisz to ustawić dynamicznie za pomocą Javascript. Możesz również wstawić tę regułę za pośrednictwem JS.

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

To tak, jakby styl był w arkuszu stylów. Bądź więc świadomy specyficzności.

Styl typu
źródło
jakieś pomysły, kiedy będzie to możliwe?
SuperUberDuper
1
Nie sądzę, że tak będzie. Ale nie jestem świadomy wszystkich rzeczy, które robią grupy robocze.
Type-Style
8

Hej, właśnie to napisałem.

Teraz możesz użyć <div style="color: red; @media (max-width: 200px) { color: green }">mniej więcej tego.

Cieszyć się.

Даниил Пронин
źródło
głosowałem za tym, ponieważ wydawało się, że wtedy działało, ale tak nie jest. #sad
honk31
@ honk31 to świat tylko dla jednej reguły
Даниил Пронин
7

Próbowałem to przetestować i nie działało, ale jestem ciekawy, dlaczego Apple go używa. Byłem właśnie na https://linkmaker.itunes.apple.com/us/ i zauważyłem w wygenerowanym kodzie, który udostępnia, jeśli wybierzesz przycisk opcji „Duży przycisk”, używają wbudowanego zapytania medialnego.

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

Uwaga: dodano podział wierszy dla czytelności, oryginalny wygenerowany kod jest minimalizowany

Davidcondrey
źródło
3
Chciałbym wiedzieć, dlaczego / jak Apple również tego używa
Douglas.Sesar
1
Cytowany kod już nie istnieje pod danym linkiem (przynajmniej dla mnie; być może otrzymuję inną treść z powodu przebywania poza USA). Poza tym to naprawdę wydaje się bardziej osobnym pytaniem niż odpowiedzią.
Mark Amery
1
Przesłałem raport o błędzie i myślę, że od tego czasu go usunęli. itunesaffiliate.phgsupport.com/hc/en-us/requests/14201
davidcondrey
4

Możesz użyć 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
źródło
2
Pamiętaj, że obecnie jest to obsługiwane tylko w przeglądarkach opartych na Webkit .
Qqwy,
Nie działa to w zależności od rozmiaru (jak opisano w pytaniu), ale od współczynnika powiększenia, więc możesz uzyskać obraz dla małych ekranów na ekranie 27 ”2560 x 1440. To może być to, czego chcesz - a może nie.
Jan Bühler,
4

tak, możesz zrobić z javascript przez window.matchMedia

  1. pulpit dla tekstu w kolorze czerwonym

  2. tablet dla tekstu w kolorze zielonym

  3. mobile na tekst w kolorze niebieskim

//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î
źródło
3

Wewnętrzne zapytania o media są możliwe przy użyciu czegoś takiego jak Breakpoint for Sass

Ten post na blogu dobrze wyjaśnia, w jaki sposób wbudowane zapytania o media są łatwiejsze do zarządzania niż oddzielne bloki: Nie ma punktu przerwania

Związana z wbudowanymi zapytaniami o media jest idea „zapytań o elementy”, kilka interesujących lektur to:

  1. Myśli na temat zapytań o media dla elementów
  2. Zapytania o media to hack
  3. Zapytania o media nie są odpowiedzią: Element Query Polyfill
  4. jeśli jeszcze blokuje
Rafael Lüder
źródło
1

jeśli dodasz regułę do pliku print.css, nie musisz używać @media.

Odkryłem to w smarty foreach, którego używam, aby nadać niektórym elementom kolor tła.

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

Paul Wolbers
źródło