Яндекс.Метрика

    Песочница

    Еще чуть-чуть о круглых аватарках на CSS3 и маленькой тайне Оперы

    imageХочу поделиться крошечным «тайным знанием» вдогонку к недавнему хабратопику о скруглении картинок средствами CSS3.

    Все знают, что в Опере border-radius не работает для тега img. Даже обертка с overflow:hidden не спасает — углы предательски торчат из нее наружу. Чего только не придумано для борьбы с этим багом. Например, перекрыть эти выступающие углы border-ом псевдоэлемента :before обертки. Наш хабраколлега еще больше приблизился к идеалу, показав, что обертка не нужна (заодно еще раз раскрыв мощь CSS3). Но у таких решений есть существенное ограничение: картинки должны быть на однотонном фоне, иначе «покрышка» сразу выдаст себя.

    Но есть у Оперы одна малоизвестная особенность, которая поможет нам решить эту проблему. Предлагаю вашему вниманию пример (сразу с кодом — его очень мало — и результатом): jsfiddle.net/XVtMh/147/.
    Секрет — в последней строчке CSS:
    .avatars img {
      float: left;
      margin: 10px;
      background-color: #fff;
      background-position: 50% 50%;
      border-radius: 24px;
      width: 48px;
      height: 48px;
      box-shadow:
        0 0 0 5px #fff,
        0 0 0 6px #999,
        0px 1px 1px 7px #bbb;
      content: ''; /* Здесь! */
    }

    Как видно, с помощью CSS картинка превращается в аналог блочного элемента с фиксированными размерами, border-ом и даже тенью, т.е. вполне может обойтись без обертки. И, как мы видим, обходится. Если бы еще снять с нее «проклятье» замещаемого элемента, которое обезображивает уголки… К счастью, именно в Опере такое средство есть!

    Разгадка — в свойстве content, которое Опера очень давно поддерживает для любого (!) элемента (нарушая спецификацию CSS 2.1, но в соответствии с полузабытым черновиком одного из модулей CSS3). Задав это свойство (пусть с пустым значением!) нашим <img>, мы словно превращаем их в обычные блочные элементы-контейнеры (в данном случае пустые). Если теперь добавить этим контейнерам ту же самую картинку в качестве фона, мы увидим то же, что и в остальных современных браузерах — аккуратно скругленные картинки на любом фоне. А браузеры, подчиняющиеся CSS 2.1, так ничего и не заметят — они понимают content только для псевдоэлементов.

    И, что важно, в отличие от замены картинок фоном <div>, семантика от этого решения не страдает. Для любых поисковиков и даже для DOM Оперы картинка остается картинкой, ее src никуда не девается, у нее по-прежнему работает полноценное картиночное контекстное меню…

    Увы, от дублирования путей (в src и background-image) избавиться нам не удалось, что лишает решение изящества. Понадеялся я было на конструкцию типа background-image:url(attr('src')), но не вышло, а спецификация отняла последнюю надежду: функция attr() в CSS доступна только для вывода, использовать ее в выражениях нельзя — и этот запрет Опера уже честно соблюдает. Но можно прибегнуть к помощи Javascript. Его, как и разметки со стилями, понадобится всего ничего: найти нужные картинки, перебросить их src (и размеры, если надо) из атрибутов в style, да навесить специальный класс с «особой оперной магией». У меня на скорую руку на JQuery получилось вот так (небольшой бонус: кто интересовался «выпуклыми» аватарками — в Опере, в порядке «прогрессивного улучшения», можете ими полюбоваться). Причем при фиксированных размерах (как у нас) не надо ждать загрузки каждой картинки, можно сделать это по ondomready (пользователь не заметит «моргания» уголков).

    Еще маленький бонус: как видно из кода, ни обертки, ни padding-а, ни даже border-а у картинки нет. А 5-пиксельная белая рамка с однопиксельной серой границей снаружи — есть. Кто сказал, что резкими тенями границы рисовать нельзя? Причем каких угодно, внешних и внутренних, любого цвета, и — главное — хоть все одновременно!

    Опера — не единственный браузер, понимающий content для <img>. Еще это умеют Хром и Сафари. Хотя в них нет проблемы торчащих углов у картинок, кое-какой толк от трюка есть и там: сравним две крайние и две средние картинки в этом примере. Видно, что у обычной картинки углы перекрывают border и обрезаются лишь его внешней границей, а у «превращенной» — внутренней границей border-а, как положено. И внутренняя тень применяется. Но плата за это высоковата: в отличие от Оперы, эти браузеры «доводят превращение до конца» — контекстное меню с картиночного меняется на обычное, как у какого-нибудь <span>. Так что лучше применять «магию» прицельно для Оперы, напр., как в предыдущем примере.

    Надеюсь, что этот маленький секрет кому-то окажется полезным.