Фронтенд разработчик
0,0
рейтинг
30 сентября 2014 в 05:21

Разработка → Picture — новый элемент, которого нет



В девелоперских сборках браузеров Chrome, Firefox и Opera появилась поддержка нового элемета picture, призванного решить ряд проблем возникающих при разработке адаптивных дизайнов. Давайте рассмотрим его подробнее.

Новый элемент picture, решает следующие задачи, встающие перед разработчиком адаптивных веб-приложений (я воспользуюсь классификацией, предложенной pepelsbey на одной из недавних конференций по фронтенду):
  1. Ретина, т.е. экраны с плотностью точек на дюйм 150 и выше, на которых обычное изображение выглядит размыто
  2. Адаптивность, задача изменения размеров изображения согласно вашим правилам, прописанным в дизайне в зависимости от размера вьюпорта.
  3. Формат, возможность использовать современные форматы, такие как WebP, если они поддерживаются браузером
  4. Кадрирование или Художественные цели. Обрезка маловажных частей изображения, при показе на устройствах с меньшим экраном.

Сложив первые буквы, получаем мнемонику РАФК

Синтаксис


Условно, расширенный синтаксис нового элемента выглядит так
<picture>
  <source 
    srcset="<список URL c дескрипторами>" 
    [sizes="<ваши размеры в зависимости от раскладки>"] 
    [media="<медиавыражение>"] 
    [type="<mime/type>"]
  >
 <source ...>
  ...
  <img src="image.jpg" alt="My image" 
    [srcset="<список URL с дескрипторами>"] 
    [sizes="<ваши размеры в зависимости от раскладки>"]>
</picture>

Элемент picture не рендерит никакой контент, а лишь является справочным контейнером для вложенного в него тега img.

Поэтому для большинства задач хватит сокращенной записи, совсем без использования picture
  <img src="image.jpg" alt="My image" 
    [srcset="<список URL с дескрипторами>"] 
    [sizes="<ваши размеры в зависимости от раскладки>"]>


Давайте рассмотрим как решаются вышеозначенные проблемы с помощью нового элемента. Все файлы примеров можно найти в этом репозитории github.com/fetis/picture

Для тестирования примеров из данной статьи на десктопе вам понадобятся либо Firefox Nighlty (поддержка picture включается настройкой dom.image.picture.enable в about:config), либо Chrome Canary, либо Opera Developer. На мобильном устройстве новый элемент можно протестировать в Chrome Beta

Ретина


У нас есть изображение 400х300 пкс, которое мы хотим также красиво показывать при двукратной и трехкратной плотности пикселей. Для этого готовим еще 2 картинки, размерами 800x600 и 1200х900 и пишем следующий код
      <img
        src="images/400.jpg"  
        srcset="images/800.jpg 2x, images/1200.jpg 3x"
        width="400" height="300"
        >


2x и 3x это дескрипторы плотностей пикселей, они говорят браузеру, что вот эти картинки были подготовлены для вот этой плотности, если хочешь, можешь использовать. Обратите внимание, они не заставляют бразуер использовать эти картинки, а только подсказывают ему. Окончательное решение остается за ним в зависимости от других условий, например, текущего соединения.

Атрибут src в данном случае служит источником картинки для плотности < 2 и фолбеком на случай, если браузер не поддерживает новый элемент.

Адаптивность


Представим раскладку, в которой есть единственная контрольная точка (breakpoint) 700пкс. При размере вьюпорта более 700 пкс мы показываем справа сайдбар и размер нашего изображения должен быть 75% от ширины экрана. В противном случае сайдбар располагается в конце страницы и изображение должно быть растянуто на всю ширину. Это реализуется следующим кодом
      <img
        src="images/400.jpg"  
        srcset=" 400w, images/800.jpg 800w, images/1200.jpg 1200w"
        sizes="(min-width: 700px) 75vw, 100vw"
        >

400w, 800w, 1200wэто дескрипторы ширины, они подсказывают браузеру картинка какой ширины находится по данному URL и на основе этой информации браузер принимает решение какое изображение лучше всего подойдет в текущей ситуации. Как и в случае с ретиной информация носит рекомендательный характер и окончательное решение какое изображение грузить остается за браузером.

Одновременное использование дескрипторов плотности и ширины недопустимо.

В атрибуте sizes перечисляются размеры изображения для всех контрольных точек в нашем дизайне. Контрольные точки задаются в виде обычного медиавыражения, браузер берет первое, которое возвращает Истину и дальше цепочку не рассматривает. Для значения ширины используется новая единица длины vw, которая возвращает значение в процентах от ширины вьюпорта.

Если для картинки нет необходимости использовать контрольные точки, то запись можно сократить до такой sizes="100vw". А для более сложных дизайнов можно использовать CSS-функцию calc(), например
sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"

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

Как видите, мы уже покрыли 80% потребностей адаптивной верстки, а еще ни разу не использовали picture, настало время ему тоже вступить в игру.

Формат


Использование различных форматов для изображений мало отличается от способов используемых для тегов video или audio
      <picture>
        <source srcset="images/400.webp" type="image/webp">
        <img src="images/400.jpg"
          width="400" height="300" 
        >
      </picture>

Мы указываем список источников и mime/type для каждого, а браузер уже выбирает первый, который знает. В качестве фолбека используется изображения из атрибута src.

Кадрирование


Когда мы показываем фото на меньшем экране иногда имеет смысл обрезать лишние детали, оставив только основную часть. С этой задачей нам поможет справиться атрибут media
      <picture>
        <source media="(min-width: 900px)" srcset="images/original.jpg 1200w" sizes="100vw">
        <source media="(min-width: 700px)" srcset="images/800crop.jpg 800w" sizes="100vw">
        <img 
          srcset="images/400crop.jpg 400w"
          sizes="100vw"  
          >
      </picture>

В каждом атрибуте media мы задаем медиавыражение, при котором у нас будет меняться исходное изображение и, в отличие от предыдущих примеров, браузер будет обязан ему следовать. Обратите также внимание как кадрирование здесь сочетается с адаптивностью, чтобы растянуть изображение на всю ширину.

РАФК


А теперь все 4 метода в одном флаконе :) Возможно так будет выглядеть вставка картинок через пару лет (пример из блога Оперы)
<picture>
	<source
		media="(min-width: 1280px)"
		sizes="50vw"
		srcset="opera-fullshot-200.webp 200w,
				opera-fullshot-400.webp 400w,
				opera-fullshot-800.webp 800w,
				opera-fullshot-1200.webp 1200w,
				opera-fullshot-1600.webp 1600w,
				opera-fullshot-2000.webp 2000w"
		type="image/webp">
	<source
		sizes="(min-width: 640px) 60vw, 100vw"
		srcset="opera-closeup-200.webp 200w,
				opera-closeup-400.webp 400w,
				opera-closeup-800.webp 800w,
				opera-closeup-1200.webp 1200w,
				opera-closeup-1600.webp 1600w,
				opera-closeup-2000.webp 2000w"
		type="image/webp">
	<source
		media="(min-width: 1280px)"
		sizes="50vw"
		srcset="opera-fullshot-200.jpg 200w,
				opera-fullshot-400.jpg 400w,
				opera-fullshot-800.jpg 800w,
				opera-fullshot-1200.jpg 1200w,
				opera-fullshot-1600.jpg 1800w,
				opera-fullshot-2000.jpg 2000w">
	<img
		src="opera-closeup-400.jpg" alt="The Oslo Opera House"
		sizes="(min-width: 640px) 60vw, 100vw"
		srcset="opera-closeup-200.jpg 200w,
				 400w,
				opera-closeup-800.jpg 800w,
				opera-closeup-1200.jpg 1200w,
				opera-closeup-1600.jpg 1600w,
				opera-closeup-2000.jpg 2000w">
</picture>


Здесь используются 2 формата JPEG и WebP. При ширине экрана более 1280 пкс показывается полноразмерная картинка в половину вьюпорта. При ширине от 640 до 1279 показывается обрезанное фото на 60% ширины вьюпорта. При ширине экрана меньше 640пкс показывается обрезанная фотография на 100% ширины. Выбор под текущее DPI экрана производится на основе ширины исходных файлов.

Дополнительная информация


Поддержка браузерами caniuse.com/#search=picture
Спецификация www.w3.org/html/wg/drafts/html/master/embedded-content.html#the-picture-element
Рабочая группа и типовые задачи, которые они решали с помощью нового элемента responsiveimages.org
Множество примеров использования dev.opera.com/articles/responsive-images
Сергей @fetis26
карма
31,0
рейтинг 0,0
Фронтенд разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (98)

  • +74
    Тихий ужас.
    • –1
      Почему?
      • +16
        Да потому что опять перекладывают оформление в модель. css в html.
        • +4
          Это не оформление в чистом виде, это информация об источниках картинки — ничего не поделаешь, только так сейчас можно решить эту проблему.
        • 0
          Ну к оформлению здесь можно отнести максимум sizes, и то ничто не мешает прописать вам стопы размеров для картинок в CSS. Это работает, хоть и с глюками.
          • 0
            Да и sizes тоже не относится — это же не размер элемента, а размер картинки, которая является источником. Т.е. это просто метаданные файла, вынесенные в тег.
            • 0
              (min-width: 640px) — это тоже матаданные?
              • 0
                Если я правильно понимаю написанное — это хинт того, какой именно файл грузить — то есть в общем-то да, тоже метаданные.
                • 0
                  Видимо неправильно. sizes указывает какого размера будет картинка. А хинт, какую картинку грузить — в srcset.
          • 0
            Бродили, бродили, и все равно пришли к HTML.
        • +2
          Предполагается, что это картинки, важные с точки зрения контента. Например, иллюстрации на Википедии уже давно используют srcset, ещё со времён, когда атрибут не поддерживался браузерами. Браузеры стараются загрузить картинки как можно раньше, отсюда и синтаксис в HTML, чтобы не дожидаться загрузки стилей. Для оформления ничто не мешает использовать все уже имеющиеся возможности CSS. Но адаптивность для декораций, как правило, не нужна.
      • +12
        Представил как контент-менеджеру работать с этим. Ну и размер html растет, замусоривается.
        • +5
          А это не задача контент-менеджера совсем, а задача CMS. Его задача картинку загрузить, а система сама сгенерит и разные форматы и разные разрешения
          • 0
            Эээ… Это ужасный вариант.
            Для такой вещи, как адаптивный дизайн, нужно готовить все по-человечески и руками. Каким бы ни был суперскрипт обработки изображения, он не сделает работу лучше, чем человек.
            • 0
              Вы готовы сидеть и руками делать эту работу? Или платить другому человеку за эту работу? А скрипт либо будет в CMS исходно, либо плагином за 15-40 баксов.
            • +1
              Не путайте элементы оформления и тысячи картинок каталога продукции. Никто их вручную не обрабатывает.
    • 0
      Поддерживаю
      Почему это лучше чем

      <img src="opera-closeup-400.jpg" class="w0-400" />
      <img src="opera-closeup-1000.jpg" class="w400-1000" />
      <img src="opera-closeup-1400.jpg" class="w1000-more" />
      с соотвествующими правилами в CSS.
      
  • +8
    Очень удивился, что автор статьи не pepelsbey: Сколько нужно верстальщиков, чтобы вставить <picture>?.
    • +2
      Будет и моя статья :)
      • 0
        Спасибо за доклад, кстати. Если бы не он он, не было бы этой статьи.
      • 0
        Пользуясь случаем, спрошу. Почему браузер так странно себя ведет в этом варианте
                <img
                  src="images/400crop.jpg"
                  srcset="images/400.jpg 400w, images/800.jpg 800w, images/1200.jpg 1200w"
                  width="200"
                  >
        


        Он полностью игнорирует атрибут width и загружает максимальное изображение на 1200
        • 0
          Вы поставили меня в тупик — если заменить 200 на 100%, то переключение работает. Напишу Йоаву, который внедрял это в Блинк и Вебкит. Кажется только он до конца понимает как это работает :)
          • 0
            Оно конечно работает, но зависит строго от вьюпорта. Попобуйте demo2.html уменьшить до 820пкс например. Картинка сама 788 пкс, но использует 1200.jpg, потому что вьюпорт 820, а надо по идее 800.jpg брать. При width="50%" эта кореляция более очевидна.

            С нетерпением жду ответа.
  • 0
    Раньше верстальщики и дизайнеры мечтали чтоб вымерли старые версии браузеров или даже некоторые браузеры целиком.
    Скоро будут мечтать чтоб вымерли старые версии устройств с небольшой плотностью пикселов на экранах.
  • +11
    Атрибут «srcset» вполне логичный и нужный, но я совсем не понимаю зачем пихать css в виде «sizes» прям в html код
  • +2
    Сложив первые буквы, получаем мнемонику РАФК
    Лучше ФРАК.
    • +1
      Думал об этой версии, но слишком отвлекает смысл и порядок усложнения нарушается.
    • 0
      В исходной презентации вообще РАКФ.
      • 0
        Черт :) Я не проверил себя. Хотя «рафк» вроде русскому человеку легче прочесть, чем «ракф». Может приживется.
        • 0
          Да нормально.
    • 0
      Здесь выстроено по важности. Ретина и Адаптивность это основное ради чего задумывалось. Иначе смысловой порядок нарушается
  • +2
    Было бы неплохо, если бы браузеры умели распознавать зум и подставлять картинку в большем разрешении.
    На многих сайтах вставляют превьюшки, по которым надо кликнуть для просмотра в большем разрешении, часто с переходом на другую страницу — на телефонах было бы намного удобней, если бы подгружалась бóльшая картинка по мере зума пальцами.
    К сожалению, я так и не понял, как прикладными средствами отлавливать событие zoom.
  • 0
    То есть одна и та же картинка, на мониторе с низким разрешением нормально выглядят, а на ретине мыло сплошное? Может что-то не так с монитором, а не картинкой?

    На мой взгляд, метаинформация о типе, разрешении, плотности точек не должна быть ни в html ни в css. Этой информации самое место в uri, который уже может использоваться как в html, так и в css, да и где угодно, единообразно:

    <img src="wallpaper.jpg?meta:width=800&meta:height=600&meta:dpi=72#or#wallpaper-x2.jpg?meta:width=800&meta:height=600&meta:dpi=150#or#wallpaper.svg?meta:mime=text/svg" />
    


    body {
        background: url( 'wallpaper.jpg?meta:width=800&meta:height=600&meta:dpi=72#or#wallpaper-x2.jpg?meta:width=800&meta:height=600&meta:dpi=150#or#wallpaper.svg?meta:mime=text/svg' );
    }
    


    <script src="index.js?meta:mime=text/javascript#or#index.ts?meta:mime=text/x-typescript"></script>
    


    И так далеее.
    • +1
      Можно и ещё проще — отдавал бы браузер в HTTP-заголовке размер вьюпорта и плотность пикселей. А на сервере уже каким-нибудь несложным плагином это всё разруливать. Понятно, что «чисто статика» так не взлетит (и, наверное, это плохо). Но вот на комментарий ниже RMV1983 написал, почему жесткий хардкод всех вариантов тоже плох.

      Кстати, был бы в http-заголовке размер вьюпорта, ещё ряд проблем с адаптивностью можно было бы решить (например, при первой загрузке сразу выдавать нужные размеры html-блоков на сервере, или нужные css-файлы).
      • +2
        Вы сейчас про HTTP Client Hints говорите.

        Недостаток его в том, что надо реализовывать и на сервере, и на клиенте.
    • 0
      B кто должен формировать этот мета запрос? браузер? и потом сервер его еще понять и отдать нужный контент. Получается что реализацию должна быть двухсторонней в отличие от picture

      А если происходит динамическое изменение вьюпорта? Тогда как быть.
      • 0
        Формирует программист, а понимает браузер, загружая «wallpaper.jpg?meta:width=800&meta:height=600&meta:dpi=72» или «wallpaper-x2.jpg?meta:width=800&meta:height=600&meta:dpi=150» или «wallpaper.svg?meta:mime=text/svg» в зависимости от того, что лучше подходит. Серверу не нужно его понимать — при отдаче статики он просто игнорирует query string. При изменении вьюпорта, если уже есть загруженная картинка в большем разрешении или в векторном формате, то просто ресемплит, иначе показывает что есть, а в фоне подгружает хайрез.
        • 0
          Не, это очень плохая идея. URL указывает на несколько ресурсов вместо одного. Параметры переданные в урл игнорируются и используются почему-то браузером. Человеку такую кашу параметров читать невозможно.
          • 0
            А что плохого в том, что uri указывает на несколько ресурсов? Точнее представляет из себя просто список uri.

            Параметры могут игнорироваться, а могут и нет:
            <img src="generate?meta:dpi=72#or#generate?meta:dpi=150#or#generate?meta:dpi=300" />
            

            В этом случае сервер генерирует картинку с нужной плотностью в зависимости от параметров.

            При наличие подсветки синтаксиса читать не сложнее, чем нагромождение picture, img, src, srcset и пр.
            • 0
              От каких парметров? Вы передаете 2 набора парметров и что должен вернуть сервер, 2 картинки?
              • 0
                Ещё раз, на сервер посылаться в данном случае будут:
                generate?meta:dpi=72
                или
                generate?meta:dpi=150
                или
                generate?meta:dpi=300

        • 0
          В таком варианте оно выглядит как костыль страшный.
          Кроме внесения того, что на конец-то вынесли в css вы предлагаете еще и логику добавить, т.е. «or»
          Зачем это все тогда? Проще яваскриптом разруливать, хотя бы все поймут сразу.
          • –1
            Я бы не назвал bulk-uri костылём. Соединение через #or# — для обратной совместимости.

            Мета информация об изображении ничего не говорит о том, как его следует показывать. meta:width и meta:height — информация о разрешении изображения, необходимая браузеру, чтобы принять решение какой ресурс скачивать и, если в css не сказано иное, сколько места нужно зарезервировать на странице, чтобы не было скачка контента, когда изображение загрузится.

            Яваскриптом в css не очень-то удобно рулить.
            • 0
              >>Яваскриптом в css не очень-то удобно рулить.
              Почему неудобно? Обычная объектная модель, к тому же почти везде jquery.

              >>Я бы не назвал bulk-uri костылём. Соединение через #or# — для обратной совместимости.
              Дело не только в OR, но само OR там явно не органически выглядит, это все-таки логика, это условие уже, а не просто запятая списка.

              Зачем все вообще пихать в один атрибут? запоминать где там двоеточие, где равно, какой-то еще свой синтаксис появляется.
              При этом абсолютная мешанина, тут и идентификатор ресурса и его параметры, да это просто читать неприятно,
              все-таки мы двигаемся к ускорению разработки, повсеместной подсветки синтаксиса и к автоподстановкам, а тут наоборот.
              Еще можно вспомнить про различные парсеры и поисковики

              То, что представлено в статье, конечно тоже та еще радость — но там хотя бы сходу понятно о чем речь идет.

              • 0
                Потому что у каждого браузера свои особенности. Потому что js — имеративный язык, а css — декларативный. Потому, что модифицируемые налету css сложнее отлаживать. И jquery тут никаким боком.

                #or# — вполне себе запятая списка. Никакой особой логики тут нет.

                Затем, чтобы иметь возможность использовать один и тот же механизм везде, где надо указывать ссылку. Не только в html, но и в css и прочих местах. Двоеточие отделяет пространство имён от собственно имён. meta — зарезервированное пространство имён.
                Идентификатор ресурса почти всегда содержит параметры. Тут они более стандартизированы.
                Тут ничего не мешает быстро разрабатывать, подсвечивать синтаксис, автоподставлять и анализировать поисковиками.

                Нет, эта запись сходу, без разъяснений не понятна
                    <source
                        sizes="(min-width: 640px) 60vw, 100vw"
                        srcset="opera-closeup-200.webp 200w,
                                opera-closeup-400.webp 400w,
                                opera-closeup-800.webp 800w,
                                opera-closeup-1200.webp 1200w,
                                opera-closeup-1600.webp 1600w,
                                opera-closeup-2000.webp 2000w"
                        type="image/webp">
                
                • 0
                  >>Потому что у каждого браузера свои особенности. Потому что js — имеративный язык, а css — декларативный.
                  >>Потому, что модифицируемые налету css сложнее отлаживать. И jquery тут никаким боком.
                  Похоже в данном контексте мы разговариваем немного о разных вещах, в прочем теперь я понял что вы имели ввиду под «Яваскриптом в css не очень-то удобно рулить.»

                  Я не говорю что понятно, я говорю о том, что понятно о чем идет речь. Это несколько разные вещи.
                  В этом случае, например, по факту используется привычный синтаксис html, в вашем же нет, вы там свой придумали.
                  Т.е. вот по-моему: Этот вариант как бы не очень, но ваш точно также не очень, не решает он проблем, а только добавляет.
                  • 0
                    Содержимое sizes и srcset — ниразу не «привычный html»

                    Какие проблемы не решает? «Разрешение» и «Формат» — вполне решает. «Адаптивность» и «Кадрирование» — не место им в html.
                    • 0
                      Им место как раз в HTML. Вот захотите вы добавить ещё одну фотку с этими свойствами. Будете писать дополнительный CSS? А если фоток много?
                      • 0
                        Я напишу один css для любых фоток. И уж точно я не буду руками делать для каждой картинки несколько дубликатов в разном разрешении с разным кадрированием. Максимум — каждой фотке присвою пару классов, указывающих, какая её часть является наиболее значимой.
                        • 0
                          Так фотки же разные, надо будет делать своё кадрирование для каждой.
                          • 0
                            Это огромный объём работы, которым никто не будет заниматься. Максимум — пользователь укажет где на фотографии важные детали, чтобы неважными пожертвовала автоматика, если места не будет хватать.
                            • 0
                              Так речь о том, что не будешь писать в CSS параметры каждой фотки. Поэтому запись в HTML.
                              • 0
                                В данном случае не просто запись в html, а ещё в фотошопе нужно откадрировать каждую фотографию. Всё же проставить css класс «всё-важное-сверху» куда проще.
                                • 0
                                  Не обязательно в фотошопе, можно и на глаз с поправками. Я svg на глаз спокойно рисовал.
                                  • 0
                                    Неважно же в чём.
                    • 0
                      >> sizes и srcset — ниразу не «привычный html»
                      Это атрибуты html тега, это привычно парсерам и людям.

                      >>«Разрешение» и «Формат» — вполне решает
                      Вы внутри формата html придумали свой формат, еще одну сущность. Принцип Оккама опять же. Необходимости нет, раз есть возможность сделать как в варианте, описанном в статье.

                      >> «Адаптивность» и «Кадрирование» — не место им в html.
                      Что вы имеете ввиду? Во первых, нужно понимать принципы разделения контента и стилей его отображения.
                      тег img это контент, бекграунд это стиль отображения, хоть там тоже речь об изображении, между ними громадная разница.
                      Вас же не удивляет, надеюсь, что в теге img есть атрибут src?
                      • –1
                        А атрибуты src и href — не привычны?

                        Ещё раз подчеркну, предложенный мной вариант не имеет никакого отношения ни к HTML ни к CSS, а является расширением стандарта URI, который перпендикулярен как HTML так и CSS, хотя они и ссылаются на него при определении некоторых свойств. И именно поэтому расширение URI даёт системный эффект, а добавление костылей в html:img, html:picture, html:video, html:audio, html:link, html:script, html:iframe, html:object, css:background-image, css:font-family, css:cursor и прочие места, где бывает необходимо грузить разные ресурсы в зависимости от браузера/вьюпорта/доступной памяти/скорости процессора — нет.

                        Обрезание и ресайз замечательно реализуются специально предназначенным для этого инструментом — css.
                        • 0
                          >>Ещё раз подчеркну, предложенный мной вариант не имеет никакого отношения ни к HTML ни к CSS,
                          >>а является расширением стандарта URI

                          Ок, хорошо, можно посмотреть с этой стороны. Стандарт URI четко описан в RFC, если уж предлагаете именно его расширять, делайте не частное прикладное решение, которое вызывает больше проблем, чем их решений, а конкретное и четкое предложение в формате RFC.
                          Сразу увидите, почему всякие #OR# там будут очень странно смотреться.

                          • 0
                            Я знаком с этим стандартом и, что важнее, с практикой его применения. Всякие "#or#" смотрятся необычно, но всяко не хуже всяких "#!"

                            Какие именно проблемы вы видите в этом решении? Оно полностью обратно совместимо и довольно расширяемо.
                            • +1
                              Тут важна не узкая практика применения стандарта, а практика создания стандартов.
                              Стандарт URI вещь очень широкого применения, намного более широкого чем проблема различных dpi.
                              Поэтому я и говорю, что для дальнейшего обсуждения, раз вы предлагаете расширить URI RFC, необходимо увидеть как вы его хотите расширить. Не просто некоторый комментарий описывающий некий частный случай, а предложение в формате RFC.
                              • +1
                                Вы прекрасно понимаете, что я не буду тратить кучу времени на написание стандарта, которому никто не будет следовать. Это не важно как именно расширять URI. Приведённый мной пример лишь иллюстрирует как простое и обратно совместимое расширение URI заменяет десяток расширений HTML, XML, CSS, SVG и других языков.
    • +3
      Выглядит как костыль.

      Как такие URI кешировать? Ведь кроме браузеров, есть еще куча уровней кеша.
      Сколько граблей будет с динамическим изменением всего этого на клиенте?
      Почему разделитель hash-части вдруг становится разделителем какой-либо мета-инфромации?

      Почему вообще уникальный идентификатор ресурса должен включать в себя какую-то метаинформацию, фактически указывая на несколько различных ресурсов?
      • 0
        А что в html не выглядит как костыль? :-)

        А где вы тут видите проблемы с кэшированием?
        Никаких граблей не будет.
        Для обеспечения обратной совместимости.

        А почему не должен? Все уже давно используют указание мета-информации через параметры:

        <im src="background.jpg?v=2" />
        


        Я лишь предлагаю стандартизировать основные параметры, чтобы ими мог пользоваться браузер.
        • +1
          Как и что будут кешировать кеширующие прокси? Это надо их массово научить парсить хитроумный URI?

          <im src="background.jpg?v=1" />
          

          <im src="background.jpg?v=2" />
          

          Не чувствуете разницу: у двух разных ресурсов два разных URL, а не один URL на несколько разных ресурсов, как предлагаете вы.
  • +4
    Похоже, что этот код picture (тот что в конце статьи) подразумевает, что окончательный синтаксис будет писать не человек. node.js перед загрузкой сайта или class picture на сервере. Поскольку слишком много текста получается и никакой автоматизации,. типа «если не указано обратное, для всех картинок на странице есть три версии плотности, отличия в scr — такие то».

    И да, я тоже не понимаю — почему нельзя сразу предусмотреть альтернативный синтаксис на css. Да и зачем picture вообще, если, как мне кажется, можно ограничиться расширением параметров img? С первыми пунктами, на мой взгляд, получилось намного удобнее, чем с последними. Или хотят сделать именно по аналогии с video?

    Вопрос по существу — насколько удобно будет решение в следующей гипотетической ситуации: сайт, адаптированный под плотность 1, 2 и 3. Т.е. для всех изображений — есть 3 картинки. Картинок больше 1000, готовил картинки какой-нибудь скрипт. Но вставляли их вручную (или исходник скрипта был утерян, или другой подрядчик и исходники ему не дали — сайт же есть и не зашифрован). Появились новые устройства и требуется поддержка скажем 4 и 5. Теперь собственно вопрос: а чем поможет этот занимательный picture?

    В его случае потребуется полностью перелопачивать весь код или на уровне проекта — предусматривать возможность его автоматического изменения! Но в последнем случае — гораздо проще всё сделать на сервере, до отдачи клиенту (предварительно узнав по ajax+js — плотность) или наоборот — отказаться от расширенного image, скриптом подставляя нужное изображение. И кто тогда будет пользоваться picture? Кроме как для одиночной основной картинки?

    Если в моих рассуждениях есть ошибка, прошу прояснить. Возможно, что я упустил какой то важный логический шаг. Поскольку кроме как для одиночного использования, применения picture пока что не вижу.
    • +1
      Мне кажется, что проблема выходит за рамки picture и касается внедрения любого нового функционала в существующий контент.

      Вы можете по-быстрому использовать текущий метод загрузки через JS, но даже в этом случае вам придется каким-то образом дать ему знать о новой плотности. Если она прописывалась в виде data-x2, data-x3 (так делает HiSRC), то код вам лопатить в любом случае.

      Или же можете потратить чуть больше времени и сделать правильно. Получите сразу еще и расширяемую поддержку в будущем (допустим кадрирования когда захотите), поддержку форматов, экономию трафика.

      Собственно задача распарсить текущие статьи на предмет тега img и обновить на новый совсем не сложна для бекенда. Выбор за вами.
      • +2
        >…касается внедрения любого нового функционала в существующий контент.
        Скорее «может касаться», поскольку в некоторых случаях, люди исправляют свои ошибки. И получается то, что не стыдно назвать «продуманным». Про picture лично я пока такого сказать не могу. Но насколько я понимаю, это ещё только развивается, да же в ночные сборки ещё не полностью вошло — может и успеют исправить.

        Понятно что выбор есть всегда. Как понятно и то, что если будет функционал, то потом найдут как его использовать. Но пока он ещё только разрабатывается, желательно что бы результат был бы более полезен.

        >…но даже в этом случае вам придется каким-то образом дать ему знать о новой плотности.
        Как насчёт отдельной функции (или свойства класса) за это отвечающей? Или просто массива доступных элементов по умолчанию?
        Скажем, если нет ни одного атрибута data-x?, а класс — fleximg то всем им добавить ещё одну плотность. И все изменения сведутся к новым изображениям и правке кода в одном месте, причём скорее всего — одной строчке! (И не важно: фронтенд это делает или бэкенд)

        К picture претензия с моей стороны в том, что вместо того, что бы решать проблему (причём на уровне css), она добавляет новые. Зачем? Существуют решения со схожей эффективностью. Если уж что-то делать, то нужно делать так, что бы стало лучше. И да, в рамках picture можно много чего исправить, да и использовать ограниченно можно (скажем при разметке в WYSIWYG-редактор — для добавления одной картинки), но на данный момент (исходя из статьи) — это создаст больше неудобств, чем даст преимуществ. Может быть я неправ, время — покажет.

        >Если она прописывалась в виде data-x2, data-x3 …
        Вот в этом случае, я с вами согласен — ничем не лучше. Проблема в том, что picture «рекомендует», «пополяризирует» именно такой и только такой подход.

        >Собственно задача распарсить текущие статьи на предмет тега img и обновить на новый совсем не сложна для бекенда. Выбор за вами.
        И зачем тут picture? Сейчас это и для фронтенда не особая проблема (если не ставить целью экономию трафика при максимизации качества и скорости отклика одновременно).

        Речь идёт о том, что нет (в статье или в принципе?) чётко сформулированной проблемы, которую бы решала picture. Нет сравнения с эффективностью существующих решений. И в то же время её синтаксис кажется черезчур усложнённым, не продуманным до конца.
        • 0
          Давайте оставим тему замены существующих тегов на picture в стороне. Это задача без деталей текущей реализации не имеет смысла.

          >К picture претензия с моей стороны в том, что вместо того, что бы решать проблему (причём на уровне css)
          Я не очень понимаю как вы решите проблему DPI или формата на уровне CSS.

          >Проблема в том, что picture «рекомендует», «пополяризирует» именно такой и только такой подход.
          Спецификация picture это часть будущего HTML5.1. Это не то, что какие-то дядьки из Оперы запилили и всем навязывают теперь. Изначально она была отдельным документом, но когда все стороны пришли к соглашениям как это должно выглядеть и работать ее включили в HTML и теперь браузеры начали потихоньку это реализовывать.

          > Речь идёт о том, что нет (в статье или в принципе?) чётко сформулированной проблемы, которую бы решала picture
          Ну здрасьте. РАФК это и есть 4 четко сформулированные проблемы, которые решает picture. Если вам мало, можете почитать расширенное описание на usecases.responsiveimages.org/, там и текущие техники рассмотрены.
          • 0
            >Давайте оставим тему замены существующих тегов на picture в стороне.
            Давайте. Но делать это похоже всё-равно придётся, для совместимости со старыми браузерами.

            >Я не очень понимаю как вы решите проблему DPI или формата на уровне CSS.
            Чуть ниже постарался, как смог, проиллюстрировать свою идею. (см. комментарий )

            >Спецификация picture это часть будущего HTML5.1.
            Именно это и печалит.

            >…когда все стороны пришли к соглашениям как это должно выглядеть и работать…
            Вероятно что-то недоглядели. Такая реакция, судя по комментариям, не у меня одного. Может, одумаются пока не поздно, да и поменяют спецификацию, пока ещё не внедрили?

            >Ну здрасьте. РАФК это и есть 4 четко сформулированные проблемы…
            Ну, в вашей статье кейс описан нечётко. Не учтена, к примеру, масштабируемость решения. При том, что для одиночной картинки picture подходит, она явно нуждается в доработке для сотни картинок.
            За ссылку спасибо — почитаю.
            Самая же главная претензия, что нет сравнения: почему это лучше тех решений, что используются для этих целей сейчас? (по ссылке, при беглом взгляде, этого тоже не увидел)

            • 0
              Совместимость прекрасно обеспечивается через атрибут src.

              Сравнивать с текущими методами не входило в мою задумку. На вскидку могу сравнить с методом загрузки через JS в случае высоких DPI

              Picture:
              1) Не использует JS
              2) Сразу грузит нужную картинку
              • 0
                Дополню про picture
                3) вызывает проблемы совместимости
                4) -//- головную боль при изменении более 10 картинок
                5) не семантичен
                Вы пишите только плюсы, забывая про недостатки.

                Я НЕ утверждаю, что правильный вариант только тот что я предложил. Нет. Проблему можно решить разными способами. Лично мне вариант с picture нравится меньше всего.

                >Совместимость прекрасно обеспечивается через атрибут src.
                Вы проверяли? Точно на всех браузерах? И на links2 (с поддержкой картинок)?

                Я понимаю, что хочется, что бы video, audio, picture были семантически похожи, но беда в частоте их использования. Картинок на любом сайте на порядок больше. И если заняться целью их ВСЕ адаптировать… picture будет только мешать. ИМХО

                И напишите пожалуйста: почему, скажем, обрезку изображений вы относите к семантике, когда это именно изменение внешнего вида, содержимое то (в идеале) меняться не должно…
                • 0
                  3) Какие?
                  4) Какую?
                  5) ЛОЛШТО? как картинка, которая показывает картинку может быть не семантична?

                  > Вы проверяли? Точно на всех браузерах? И на links2 (с поддержкой картинок)?
                  А что здесь проверять? Любой браузер игнорирует неизвестные теги и атрибуты

                  > почему, скажем, обрезку изображений вы относите к семантике, когда это именно изменение внешнего вида, содержимое то (в идеале) меняться не должно…
                  это не изменение оформления и не семантика. это контент. для больших экранов больше контента, для маленьких меньше.
                  • 0
                    3) Ну например в существующих WYSIWYG-редакторах
                    4) Хм… вроде бы уже писал. Есть более 10 (или давайте более 100, если мало — более 1000) картинок. Нужно к каждой из них добавить вариант с точностью x6. Вы предлагаете вручную каждой из них дописывать source, причём не давая альтернатив. Если использовать picture.
                    5) Просто. Картинки бывают разными. Сама картинка (одна) — вполне семантична. Но вот беда, вы же предлагаете. что одна картика — то не одна картинка, это куча картинок, которые притворяются одной. И где тут семантичность?

                    >Любой браузер игнорирует неизвестные теги и атрибуты…
                    Кхм. Ну да. Верно. Похоже, что тут проблем с браузерами не будет. Зато с редакторами кода — будут.

                    >это не изменение оформления и не семантика. это контент. для больших экранов больше контента, для маленьких меньше.
                    В том то и дело, что это НЕ контент, а оформление. контент — это только первоначальная картинка А её варианты — уже оформление. Вы же не будете утверждать. что картинки по смыслу должны быть абсолютно разными для разных экранов? Они должны быть похожими, но адаптированными. А раз похожими — значит они производные от первоначальной и сиё должно быть автоматизированно. При этом, если человек захочет, то он должен иместь возможность сделать и так, и так. Вариант с picture лишает этого.
        • 0
          Могу даже свой концепт-вариант предложить. Не идеальный конечно и упрощённый, но думаю, что мою мысль насчёт css-решения продемонстрирует.

          концепт-вариант flex-css alpha
          <img class="fleximg" src="{{$pic-dir}}/pic.png" />
          <div class="pic_div"><div>
          


          .fleximg {
            box-shadow: 0 0 10px rgba(0,0,0,0.5);
          }
          .fleximg retina_x2 {
            media-src-type:inherit;
            media-src-flex-add:'x2';
            /*теперь ссылка ведёт на "{{$pic-dir}}/pic.x2.png"*/
          }
          .fleximg retina_x3 {
            media-src-type:svg;
            media-src-flex-add:'x3';
            /*теперь ссылка ведёт на "{{$pic-dir}}/pic.x3.svg"*/
          }
          .fleximg retina_x4 {
            /*ссылка по-умолчанию, ведёт на "{{$pic-dir}}/pic.png"*/
          }
          .pic_dir {
            background-image: url(img/bg.jpg);
          }
          .pic_dir retina_x2{
            media-src-type:svg;
            media-src-flex-add:'x2';
            /*теперь ссылка ведёт на "img/bg.x2.svg"*/
          }
          .pic_dir retina_x3{
            media-min-width-cut: 900px; /*Изображение будет порезано*/
            background-image: url(img/bg-full.bmp);
          }
          

          retina_x? — определяется браузером. Возможно, правильнее это делать через медиа-запросы а не так как в этом примере.
          См. пример-2

          концепт-вариант flex-css alpha-2 media
          <img class="fleximg" src="{{$pic-dir}}/pic.png" />
          <div class="pic_div"><div>
          


          @media all{
          	.fleximg {
          	  box-shadow: 0 0 10px rgba(0,0,0,0.5);
          	}
          	.pic_dir {
          	  background-image: url(img/bg.jpg);
          	}
          }
          @media screen and (min-retina:2){
          	.fleximg {
          	  media-src-type:inherit;
          	  media-src-flex-add:'x2';
          	  /*теперь ссылка ведёт на "{{$pic-dir}}/pic.x2.png"*/
          	}
          	.pic_dir {
          	  media-src-type:svg;
          	  media-src-flex-add:'x2';
          	  /*теперь ссылка ведёт на "img/bg.x2.svg"*/
          	}
          }
          @media screen and (min-retina:3){
          	.fleximg {
          	  media-src-type:svg;
          	  media-src-flex-add:'x3';
          	  /*теперь ссылка ведёт на "{{$pic-dir}}/pic.x3.svg"*/
          	}
          	.pic_dir {
          	  media-min-width-cut: 900px; /*Изображение будет порезано*/
          	  background-image: url(img/bg-full.bmp);
          	}
          }
          @media screen and (min-retina:4){
          	.fleximg {
          	  /*ссылка по-умолчанию, ведёт на "{{$pic-dir}}/pic.png"*/
          	}
          	.pic_dir {
          	  /*ссылка по-умолчанию, ведёт на "img/bg.jpg"*/
          	}
          }
          
          

          • 0
            CSS инструмент для создания внешнего вида, а вы через него формируете результирующий URL. «Уже сейчас видно, что все это будет глючить и тормозить» (с)

            Опять же, убираем файл CSS и вся адаптивность валиться к чертям и в тег style это не положишь. Схема именования жестко закреплена, это очень плохо на мой взгляд.
            • 0
              Адаптивность в большинстве случаев и так валится, если не удаётся загрузить css. Да и что мешает это записать в style — не совсем понятно.

              Вроде бы позиционировалась концепция семантического HTML5. Так вот, picture — ни разу не семантичен. Предлагаемый мною вариант, конечно не идеален, но — семантичен.

              >CSS инструмент для создания внешнего вида…
              Именно. Так и дайте ему отвечать за внешний вид. Ведь picture делает именно это. Насколько я понимаю, picture не должен менять содержимое, а только внешний вид — это прямая задача css. как вы и пишите.
              • 0
                Кажется вы застряли в 98. Тег img для оформления уже давно давно не используется.
                • 0
                  Я вот захожу (к примеру) на opera.com/ru/computer и вижу, что там img используется как элемены дизайна, т.е. как оформление. Я имею ввиду скруглённые картинки. Они не несут информацию сами по себе, иллстрируя текст. Да, их можно назвать частью контента. а можно — оформлением. И правы будут оба.

                  Но вы ведь не об этом. Оформление сейчас достигается за счёт css так что ваш довод
                  >Опять же, убираем файл CSS и вся адаптивность валиться к чертям…
                  Справедлив именно для современных сайтов. И для любого css, а вот к img отношения не имеет.
                  Или (если брать мой концепт) — имеет в той же мере, что и всё остальное оформление.
                  А современный сайт без оформления… там не нужен контент. И не важно — адаптивный или нет.

                  Так что, если css отваливается — поздно пить баржоми.
                  • 0
                    Это чистый контент. Тут даже обсуждать нечего.
                    • 0
                      Это не совсем чистый контент, т.к. никакой информации он не несёт. Это скорее — дизайн статьи, оформление контента и т.п. Но всё это неважно.

                      Важно то, что на той странице изображений достаточно много. что бы начать себя чувствовать дискомфортно, когда потребуется у всех них добавить альтернативную плотность. А ведь это только одна страница. На сайте же изображений удет гораздо больше. Отсюда и числа 100 или 1000. Если это делать через css — да даже код страницы менять бы не пришлось, максимум — класс добавить, да и то не факт.

                      А с picture — придётся. а когда появится новая плотность — придётся ещё раз. А потом ещё. И выгоды в этом ни на грош.
              • 0
                В атрибут style ваши медиавыражения нельзя засунуть. Никак.
                • 0
                  Я показал два концепта. Два. media лишь в одном.
                  Да, вариант с media мне кажется предпочтительней.
                  И да, в этом случае контент таки будет — будет картинка по умолчанию. Да, не адаптивный.
                  Но если отвалился весь css, а адаптивность оформления обеспечивалась за счёт него (бутстар, 960 и т.п.), то неадаптивность картинки роли не сыграет.
                  • 0
                    Адаптивность разная бывает. Цветная картинка, которая подменяется ч/б для печати это тоже адаптивность.
                    • 0
                      И именно это часто делают через css media print
                      Разве не так? А picture загоняет всё в код страницы. И где тут вы видите семантичность?
                      • 0
                        как вы будете подменять урл фотографии через CSS?
                        • 0
                          Хотя бы также как и фон.
                          Можно так как предложил я. На мой взгляд, самое удобное — это дать возможность автоматически дополнять URL. Неважно каким способом. Я предложил генерировать postfix или prefix — вам не понравилось, но это — реальное улучшение. Я не настаиваю на этом способе, но хочу показать удобство идеи автоматизирования ссылок (или её аналогов).
            • 0
              >Схема именования жестко закреплена, это очень плохо на мой взгляд.
              А это в моём варианте обсуждаемо и подлежит изменению. Можно продумать несколько вариантов. тот вариаент что я написал — даёт возможность быстро вставить 1000 картинок. А если 1001-ой он не подходит — поставить ей другой класс.

              >…а вы через него формируете результирующий URL
              Он так и так должен формироваться разный. Просто я предлагаю более гибкий вариант. Пусть и не проработанный.

              Вы можете для наглядности сравнить объём кода и понять, что… Упс, не можете. Извините. Ведь Picture по позволит менять background. т.е. у picture заведомо ограничена область применения.
              • 0
                Менять фон в CSS вы можете уже сейчас, безо всяких picture.
                • 0
                  >Менять фон в CSS вы можете уже сейчас, безо всяких picture.
                  Почему бы тогда не экстраполировать этот опыт на picture?
                  • 0
                    Так именно это и было сделано! Я не понимаю что вам не нравится.
                    • 0
                      Возможно то, что этого сделано не было?
                      К примеру, нет возможности менять и обрезать изображение в зависимости от плотности у большой группы картинок.
                      picture вообще, похоже, является вещью в себе.
  • –4
    Только что нашел статью от 22 сентября, в которой приводится аргументация против использования <picture>
    • +2
      Вы очевидно саму стать не читали. Там как раз речь про то, что не нужно использовать picture там, где достаточно атрибутов srcset и sizes
  • +6
    Я лучше останусь с img.
  • +2
    Вот я не понимаю почему не сделают подстановку переменных на этапе конструкции DOM? Все костыли какие-то с тонной JS и новые конструкции в HTML, прицеленные на узкий кейз. ОК, а если я не картинку хочу а фон с разными DPI и кропом? Чего стоит на этапе парсинга сразу разворачивать какие-нибудь ${DPI-X} и ${DPI-Y}, ${SCREEN-WIDTH} и прочее и подставлять в URL или в HTTP хедеры. И эту, и еще миллион проблем с тем же видео решили бы сразу.
  • 0
    А есть какие-то явные критерии или рекомендации, что браузер должен считать двукратной и трехкратной плотностью пикселей?
    • 0
      Это отношение между количеством физических пикселей экрана и CSS-пикселей. По сути, тут не браузер решает, а производитель устройства.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.