Pull to refresh

Сохранение исходных пропорций видео

Reading time 9 min
Views 9.2K
Original author: Thierry Koblentz


Вы когда-нибудь хотели изменять размеры видео на лету, масштабировать его как изображение? Используя внутренние пропорции для видео, можно. Эта техника позволяет броузерам устанавливать размеры видео, основываясь на ширине родительского блока. С внутренними пропорциями, новая ширина вызывает новое вычисление высоты, что позволяет изменять размеры видео и дает возможность для масштабирования его, так же, как изображения. Пример 1.


Концепция


Идея состоит в том, чтобы создать блок с соответствующими пропорциями (4:3, 16:9, и т.д.), а затем поместить видео в этот блок, растянув его до размеров блока. Это очень просто.

Значение padding — волшебство, которое создает внутренние пропорции. Потому, что мы устанавливаем отступы в процентах, основываясь на ширине родительского блока.

CSS правила, приведенные ниже, иллюстрируют как стили родителей и детей создают «волшебную обертку» — контейнер, который пропорционально изменяет свои размеры в зависимости от ширины своих родителей. Пример 2.

.wrapper-with-intrinsic-ratio {
    position: relative;
    padding-bottom: 20%;
    height: 0;
}

.element-to-stretch {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: teal;    
}

* This source code was highlighted with Source Code Highlighter.

Давайте рассмотрим объявления в каждом правиле, начиная с .wrapper-with-intrinsic-ratio.

position: relative
Объявив position: relative все дочерние элементы будут позиционироваться относительно этого контейнера.

padding-bottom: 20%
Это объявление дает блоку специфический формат. Использование 20% для padding делает высоту блока равной 20% от его ширины.

Мы специально выбрали padding-bottom, а не padding-top. Это объясняется тем, что IE5 удаляет из потока «пространство» созданное при помощи padding-top. Иными словами, используя padding-top: 20% будет создан макет, который мы хотим, но блок будет вести себя как абсолютно позиционированный элемент, перекрывая следующие элементы в потоке.

height: 0
Определение нулевой высоты создает этому элементу «Layout», что дает возможность делать IE5 и IE6 правильные измерения внутри блока. Чтобы узнать больше, посетите «On having layout» (перевод на хабре)

Теперь давайте рассмотрим каждое объявление в правиле .element-to-stretch.

position: absolute
Это освобождает элемент от границ высоты его родителя. Таким образом он может быть расположен в «области padding».

top: 0
Мы устанавливаем top: 0, чтобы поместить блок в верхнюю часть его родителя.

left: 0
Это объявление располагает блок в левой части его родителя.

width: 100%
Объявление width: 100% растягивает блок на всю ширину его контейнера.

height: 100%
Это объявление растягивает блок на всю высоту его контейнера.

background: teal
Задаем цвет, чтобы увидеть расположение блока.

Реальные действия


В примере 3 используется видео с YouTube (YouTube markup), поэтому нам нужно создать место для панели управления. Высота панели статична: она составляет 25 пикселей, независимо от размеров видео. Мы так же изменяем значение padding, для показа видео в широком формате (16:9).

#containingBlock {
    width: 50%;
}

.videoWrapper {
    position: relative;
    padding-bottom: 56.25%;
    padding-top: 25px;
    height: 0;
}

object,
embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

* This source code was highlighted with Source Code Highlighter.

Давайте взглянем на наши новые селекторы и объявления, начнем с селектора #containingBlock

width: 50%
Это всего лишь обертка видео, чтобы продемонстрировать изменение размеров видео основываясь на ширине блока просмотра. В предыдущем примере родительским блоком был элемент body.

Теперь давайте рассмотрим несколько объявлений в селекторе .videoWrapper.

padding-bottom: 56.25%
Чтобы создать отношение 16:9 мы должны разделить 9на 16 (0.5625 или 56.25%).

padding-top: 25px
Чтобы избежать проблем с нарушением блочной модели (IE5 или IE6 в quirks mode), мы используем padding-top, а не height для создания места под панель управления.

Наконец мы будем использовать object, embed селектор, потому что, некоторые броузеры используют object (например,Safari), другие embed (например, Firefox).

Примечание: В данный момент я использую элементы разметки YouTube, но в конце статьи буду использовать валидную разметку и уберу embed.

Исправления для Internet Explorer


Чтобы сделать это работоспособным в Internet Explorer просто добавим дополнительные обертки. Пример 4.

#containingBlock {
    width: 50%;
}

.videoWrapper {
    position: relative;
    padding-top: 25px;
    padding-bottom: 56.25%;
    height: 0;
}

* html .videoWrapper {
    margin-bottom: 45px;
    margin-bot\tom: 0;
}

.videoWrapper div,
.videoWrapper embed,
.videoWrapper object {
    position:absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
}

* This source code was highlighted with Source Code Highlighter.

Давайте взглянем на наши новые селекторы и объявления, начиная с селектора .videoWrapper.

height: 0
Как видно во втором примере, IE5 и IE6 нуждается в «layout».

Теперь посмотрим на селектор * html .videoWrapper. Так называемый «star hack», Этот селектор работает только для IE6 и ниже, поэтому только эти версии обработают следующие объявления:

margin-bottom: 45px
Как видно во втором примере, верхний padding создает некоторые проблемы в IE5. Здесь мы используем произвольное значение (которое должно работать с различными панелями управления) в качестве компенсации за «пространство» мы теряем возможность использовать padding-top. Это необходимо для предотвращения накладывания видео на следующие элементы.

margin-bottom: 0
В CSS разделение знаками (обратный слеш) названия свойства действует как фильтр, устанавливая некоторое значение для IE6. IE6 «видит» это объявление, в то время как IE5 игнорирует его. Если вы предпочитаете использовать условные комментарии, а не вышеуказанные фильтры, вы можете переместить эти объявления в специфические style заголовка документа.

Селектор .videoWrapper div является дополнительной оберткой, которую нам нужно сделать для Internet Explorer версий 5, 6 и 7.

Примечание: Мы используем .videoWrapper div, .videoWrapper embed и .videoWrapper object {} вместо .videoWrapper * {} для предотвращения стилизации другого контента.

Отчистка


Чтобы сделать решение более гибким, мы удаляем объявление padding-top из предыдущих правил и привяжем иго к классам. Таким образом мы можем легко стилизовать видео с различными пропорциями и/или панелями управления. Пример 5.
#containingBlock {
    width: 50%;
}

.videoWrapper {
    position: relative;
    height: 0;
}

* html .videoWrapper {
    margin-bottom: 45px;
    margin-bot\tom: 0;
}

.videoWrapper div,
.videoWrapper embed,
.videoWrapper object {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
}

.wideScreen {
    padding-bottom: 56.25%;
}

.fourBYthree {
    padding-bottom: 75%;
}

.chrome_25 {
    padding-top: 25px;
}

.chrome_35 {
    padding-top: 35px;
}

* This source code was highlighted with Source Code Highlighter.

Рассмотрим новые классы начиная с .wideScreen.

.wideScreen
Используем этот класс для стилизации div.videoWrapper в соотношении 16:9.

.fourBYthree
Используем этот класс для стилизации div.videoWrapper в соотношении 4:3.

.chrome_25
Этот класс создает пространство для панели управления высотой в 25 пикселей.

.chrome_35
Этот класс создает пространство для панели управления высотой в 35 пикселей.

Вопрос валидации


Когда дело доходит до видео, поддержки web стандартов не легка. Во первых, большинство «поставщиков» не кодирует амперсанды. Чаще всего, они используют twice-cooked метод (в котором используются не стандартные элементы embed).

Для того, чтобы сделать нашу разметку соответствующей стандартам, мы сначала заменим все амперсанды в URL на «& amp;». Затем, мы реализуем метод одного объекта. В отличии от метода вложенных объектов, эта технология предоставляет броузеру единственный объект, как показывает пример кода ниже. Пример 6.

<div id="containingBlock">
 <div class="videoWrapper">
    <div>
     <!--[if IE]>
     <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="480" height="295">
        <param name="movie" value="http://www.youtube.com/v/mDRYnaajUcY&hl=en&fs=1&showinfo=0" />
     <![endif]-->
     <!--[if !IE]>-->
     <object type="application/x-shockwave-flash" data="http://www.youtube.com/v/mDRYnaajUcY&hl=en&fs=1&showinfo=0" width="480" height="295">
     <!--<![endif]-->
        <param name="quality" value="high" />
        <param name="wmode" value="opaque" />
        <p><a href="http://www.adobe.com/go/getflashplayer"><img alt="Get Adobe Flash player" src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"/></a></p>
     </object>
    </div>
 </div>
 ...
</div>

* This source code was highlighted with Source Code Highlighter.

Метод одного объекта облегчает генерацию кода, поскольку «разветвление» сделано в одном месте <object>, а не в двух <object> и </object>.

Бонус


Поскольку мы создаем абсолютно позиционированный элемент в блоке, мы можем скрыть контент «позади» видео.
Примечание: Этот контент находится вне объекта. Это не «альтернативный контент», как таковой.
Пример 7.

<div id="containingBlock">
 <div class="videoWrapper">
    <div>
     <!--[if IE]>
     <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="480" height="295">
        <param name="movie" value="http://www.youtube.com/v/mDRYnaajUcY&hl=en&fs=1&showinfo=0" />
     <![endif]-->
     <!--[if !IE]>-->
     <object type="application/x-shockwave-flash" data="http://www.youtube.com/v/mDRYnaajUcY&hl=en&fs=1&showinfo=0" width="480" height="295">
     <!--<![endif]-->
        <param name="quality" value="high" />
        <param name="wmode" value="opaque" />
        <p><a href="http://www.adobe.com/go/getflashplayer"> <img alt="Get Adobe Flash player" src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"></a></p>
     </object>
    </div>
    

    <p>The following is the description of the video embeded in this document.</p>

    <p>This short clip is about YouTube widescreen formatting. It shows the two main formats (16:9, 4:3) and also explains the best way to create a Flash movie according to the new widescreen format.</p>
 </div>
 ...
</div>


* This source code was highlighted with Source Code Highlighter.

Подход с использованием скрипта SWFObject


Чтобы автоматизировать этот подход, мы можем использовать скрипт SWFObject, чтобы добавить нужную стилизацию классу .videoWrapper, а так же добавить обертку, если это необходимо для IE. Пример 8.
Примечание: в последнем примере, ширина блока-контейнера указана в em.

Чтобы добавить код, мы должны заменить следующие строки в SWFObject v 1.5 (примерно 117 строка)

n.innerHTML = this.getSWFHTML();

* This source code was highlighted with Source Code Highlighter.

На:

n.className += " videoWrapper";
if(typeof document.documentElement.style.zoom != "undefined"){
    var wrapper4ie = document.createElement("div");
    n.appendChild(wrapper4ie);
    wrapper4ie.innerHTML = this.getSWFHTML();
}else{
    n.innerHTML = this.getSWFHTML();                
};

* This source code was highlighted with Source Code Highlighter.

Это все что нужно. Всего лишь, небольшой CSS и вы можете масштабировать видео на лету.
Tags:
Hubs:
+23
Comments 27
Comments Comments 27

Articles