Можно ли встроить правила CSS @media?

293

Мне нужно динамически загружать изображения баннеров в приложение HTML5 и хотелось бы, чтобы несколько разных версий соответствовали ширине экрана. Я не могу правильно определить ширину экрана телефона, поэтому я могу думать только о том, чтобы добавить фоновые изображения div и использовать @media, чтобы определить ширину экрана и отобразить правильное изображение.

Например:

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

Это возможно, или у кого-нибудь есть другие предложения?

танцовщик
источник
3
Разочарованы ответами? Смотрите этот комментарий . Это может помочь.
Риного

Ответы:

285

Нет, @mediaправила и медиазапросы не могут существовать в атрибутах встроенного стиля, поскольку они могут содержать только property: valueобъявления. Как сказано в спецификации :

Значение атрибута style должно соответствовать синтаксису содержимого блока объявления CSS

Единственный способ применить стили к элементу только на определенных носителях - это использовать отдельное правило в вашей таблице стилей, а это значит, что вам потребуется создать селектор для него.

Фиктивный spanселектор будет выглядеть следующим образом, но если вы нацеливаетесь на очень определенный элемент, вам понадобится более конкретный селектор:

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

@media (max-width: 300px) {
    span { background-image: url(particular_ad_small.png); }
}
BoltClock
источник
70
Вы также можете просто вставить <style>тег в свой HTML. Это необходимый подход для случая, когда background-imageдинамически извлекается из базы данных. Очевидно, что во внешней таблице стилей это не подходящее место для этого.
Джейк Уилсон
1
@Jakobud: Да, не имеет значения, где находится таблица стилей, но дело в том, что вы можете делать это только в CSS, а не в атрибуте встроенного стиля.
BoltClock
3
Обратите внимание на будущих исследователей, что этот <script>тег часто удаляется почтовыми клиентами при пересылке электронной почты, поэтому люди склонны использовать встроенные стили для электронных писем. А это значит, что нет медиа-запросов. В настоящее время я ищу лучшие практики для этой ситуации, но просто дружеский хедз-ап.
TCannadySF
3
Пожалуйста, установите максимальную ширину в emс, а не в px. Таким образом, он будет работать разумно при увеличении масштаба.
Сайлас С. Браун
2
@ Силас С. Браун: Это не моя проблема. Я просто размышляю над тем, что используется в вопросе.
BoltClock
137

проблема

Нет, медиазапросы не могут быть использованы таким образом

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

Решение

Но если вы хотите обеспечить конкретное поведение, которое можно использовать на лету И реагировать, вы можете использовать styleразметку, а не атрибут.

й

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

Смотрите код, работающий вживую на CodePen

Например, в моем блоге я добавляю <style>разметку <head>сразу после<link> объявления для CSS, и она содержит содержимое текстовой области, предоставляемой рядом с реальной текстовой областью содержимого, для создания дополнительного класса на лету, когда я писал artitle.

Примечание: scopedатрибут является частью спецификации HTML5. Если вы не используете его, валидатор обвинит вас, но браузеры в настоящее время не поддерживают реальную цель: ограничивают содержимое <style>только непосредственно родительским элементом и дочерними элементами этого элемента. Область действия не обязательна, если <style>элемент находится в <head>разметке.


ОБНОВЛЕНИЕ: Я советую всегда использовать правила для мобильных устройств, поэтому предыдущий код должен быть:

<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>
Бруно Лезье
источник
10
Это лучший ответ, чем принятый, поскольку он позволяет динамически изменять background-imageвремя загрузки страницы.
Джейк Уилсон
7
В то время как scoped в принципе выглядит великолепно, Chrome удалил предварительную поддержку несколько версий назад, и теперь только Firefox имеет какую-либо поддержку.
Энтони Маклин
1
Scoped используется только для того, чтобы не допустить .on-the-fly-behaviorего использования, но если слово «игнорировать» каким-то навигатором не является проблемой. <style> может использоваться в <body> во всех навигаторах, это работает. Это просто требование проверки w3c.
Бруно Лезье
4
Хотя scopedэто блестящее решение, оно официально не поддерживается ни одним браузером. Надеюсь, это скоро изменится.
Кен Шарп
1
Это другой вопрос, потому что главная цель по электронной почте, чтобы читать с помощью клиента электронной почты и многими клиентами электронной почты не поддерживает вложения <style>, или media queriesвсе или функцию HTML / CSS. Так что на самом деле проблема более серьезна. Я только знаю, что вы можете создавать электронную почту, отображаемую таким же образом на всей клиентской электронной почте (включая Gmail) только с функцией HTML4 и CSS2 (с некоторым взломом Outlook), но в этом случае нет медиазапросов.
Бруно Лезье
15

Встроенные стили в настоящее время не могут содержать ничего, кроме объявлений ( property: valueпар).

Вы можете использовать styleэлементы с соответствующими mediaатрибутами в headразделе вашего документа.

Марат Таналин
источник
13

Да, вы можете написать медиа-запрос в inline-css, если вы используете тег изображения. Для разных размеров устройства вы можете получить разные изображения.

<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>
Ариф Хуссейн
источник
Это не относится к CSS background-image: url ()
Jonas Eberle
10

Если вы используете Bootstrap Responsive Utilities или аналогичную альтернативу, которая позволяет скрывать / показывать div в зависимости от точек останова, может оказаться возможным использовать несколько элементов и показать наиболее подходящий. т.е.

 <span class="hidden-xs" style="background: url(particular_ad.png)"></span>
 <span class="visible-xs" style="background: url(particular_ad_small.png)"></span>
Павел
источник
3
Прекрасный обходной путь - скрыть div, показать div на основе медиазапроса - единственный недостаток, который я вижу, это то, что он все равно будет загружать оба изображения, поэтому вы будете отправлять оба на клиент.
Майкл С. Гейтс
4
Дублированный контент не очень хорошая вещь для обслуживания или SEO.
Бруно Лезье
1
К сожалению это ложный друг! Я тоже думал об этом решении, но мы хотим, чтобы уменьшенное изображение служило небольшим устройствам и сохраняло байты для загрузки. Эта техника делает с точностью до наоборот
А.
8

Медиа-запросы в стиле-атрибутах сейчас невозможны. Но если вам нужно установить это динамически с помощью Javascript. Вы можете вставить это правило через JS aswell.

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

Это как если бы стиль был в таблице стилей. Так что будьте в курсе специфики.

Type-Style
источник
есть идеи когда это будет возможно?
SuperUberDuper
1
Я не думаю, что это будет. Но я не знаю всех вещей, которые делают рабочие группы.
Тип Стиль
8

Эй, я только что написал это.

Теперь вы можете использовать <div style="color: red; @media (max-width: 200px) { color: green }">или так.

Наслаждаться.

Даниил Пронин
источник
Я проголосовал за это, так как это казалось тогда, но это не так. #sad
honk31
@ honk31 это мир только для одного правителя
Даниил Пронин
7

Я пытался проверить это, но это не сработало, но мне любопытно, почему Apple его использует. Я был только на https://linkmaker.itunes.apple.com/us/ и заметил, что в сгенерированном коде, который он предоставляет, если вы выбираете радиокнопку «Большая кнопка», они используют встроенный медиа-запрос.

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

примечание: добавлены разрывы строк для удобства чтения, минимизирован исходный сгенерированный код

davidcondrey
источник
3
Я хотел бы знать, почему / как Apple также использует это
Douglas.Sesar
1
Код по кавычкам больше не существует по данной ссылке (по крайней мере, для меня; возможно, я получаю другой контент из-за того, что нахожусь за пределами США). Кроме того, это действительно больше похоже на отдельный вопрос, чем на ответ.
Марк Амери
1
Я отправил отчет об ошибке, и я думаю, что с тех пор его удалили. itunesaffiliate.phgsupport.com/hc/en-us/requests/14201
davidcondrey
4

Вы можете использовать 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
источник
2
Обратите внимание, что это поддерживается только в браузерах на основе Webkit .
Qqwy
Это не работает в зависимости от размера (как указано в вопросе), но в зависимости от коэффициента масштабирования, поэтому вы можете получить изображение для маленьких экранов на экране 27 “2560x1440. Это может быть то, что вы хотите, а может и нет.
Ян Бюлер
4

да, вы можете сделать с JavaScript с помощью window.matchMedia

  1. рабочий стол для текста красного цвета

  2. планшет для текста зеленого цвета

  3. мобильный телефон для текста синего цвета

//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î
источник
3

Встроенные медиа-запросы возможны при использовании чего-то вроде точки останова для Sass

Это сообщение в блоге хорошо объясняет, как встроенные медиа-запросы более управляемы, чем отдельные блоки: Точки останова нет

С «встроенными медиа-запросами» связана идея «элементарных запросов». Вот несколько интересных прочтений:

  1. Мысли о медиа-запросах для элементов
  2. Медиа-запросы - это взлом
  3. Медиа-запросы не являются ответом: Элемент Query Polyfill
  4. если еще блоки
Рафаэль Людер
источник
1

если вы добавляете правило в файл print.css, вам не нужно использовать @media.

Я включил его в умный foreach, который я использую, чтобы придать некоторым элементам цвет фона.

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

Пол Волберс
источник