109 заметок с тегом

css

«Магический шар»

Свой путь в вебе я начинал с вёрстки — в конце 90-х сделал страничку для своего факультета в домене своей альма-матер. Потом несколько лет довольно много верстал. В то время это было довольно сложное занятие — браузеры мало что умели и воевали между собой — реализовывали одни и те же вещи совершенно иначе, кроме того на размер страницы существовали очень серьёзные ограничения.

В 90-х, в веб-студии, где я работал, страница с графикой, стилями и всем текстом не должна была занимать больше 80 килобайт. В таких условиях приходилось выжимать из браузеров всё что только можно — использовать экзотические и даже недокументированные возможности.

Из того набора атрибутов и тегов, что тогда были доступны, мне довелось использовать всё, кроме одного-единственного атрибута ISMAP у картинки, ну просто не возникло ситуации, в которой он мог мне бы пригодиться.

Использование его в те годы могло бы выглядеть как-то так:

<A HREF=/cgi-bin/action.pl><IMG SRC=/i/pict.gif WIDTH=200 HEIGHT=100 ISMAP></A>

Чтобы вы прочувствовали дух времени, специально пишу большими буквами (так было принято) и без кавычек (экономили и на этом тоже).

При нажатии на картинку с этим атрибутом и ссылкой к урлу добавляются в качестве параметров координаты курсора на картинке. Видимо это нужно было для какого-то интерактива — по координатам на серверной стороне можно было понять на какую именно часть картинки нажимали, но мне, как я уже сказал, всё это ни разу не пригодилось.

«Магический шар» из прекрасного фильма «Трасса 60»; с отрисовкой деталей я не стал заморачиваться

Я уже несколько лет как не верстаю, но почему-то этот атрибут ISMAP мне всё никак не давал покоя. Как будто брошенная на последней странице книга — всё тянуло найти ему какое-то применение.

И вот два года назад меня осенило использовать его в вёрстке «магического шара» из фильма «Трасса 60». Если не смотрели, там у главного героя был шар, который давал ответы на заданные вопросы, если его потрясти.

Мой шар «отвечает» в том случае, если на нём щёлкнуть мышкой. В качестве случайных значений используются координаты, передаваемые при помощи атрибута ISMAP, плюс картинка вращается при помощи CSS, поэтому даже под неподвижным курсором всегда разные координаты.

Принцип получился довольно простой — все координаты, в которые пользователь может щёлкнуть мышкой, заданы как идентификаторы скрытых слоёв, лежащих поверх рисунка шара. Как только пользователь выбирает какую-либо координату, срабатывает стиль с селектором :target, который открывает слой.

HTML с таким подходом становится довольно жирным — у меня получился 1,2 мегабайта, но по нынешним временам это не объём.

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

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

text-decoration-line

Wavy (30.66КиБ)

Есть такая договорённость в вебе — псевдоссылки (которые похожи на ссылки, но не уводят со страницы) подчёркивать не сплошной чертой, а прерывистой или точечной. Обычно такую черту делают бордюром снизу тега, но если настоящие ссылки сделаны через text-decoration: underline, то черта оказывается на разной высоте: у ссылок она выше, чем у псевдоссылок.

Сейчас браузеры начинают поддерживать свойство text-decoration-line, но с переменным успехом — Хром — поддержка выключена по-умолчанию, Файерфокс поддерживает в полном объёме, Сафари как утверждает «КенАйЮз» — не поддерживает, ИЕ — тоже.

Оказалось, в данном случае — доверяй, но проверяй. «Сафари» (по крайней мере восьмая версия) всё-таки частично поддерживает это свойство, просто не все значения — отрисовываются wavy (на скриншоте), double и solid (остальные значения превращаются в solid).

Короткий способ определить есть ли поддержка dataURI

Придумал короткий способ определить поддержку data URI в браузере:

<script src="data:text/javascript,self.dataURI=1"></script>

Потом просто проверяете у window свойство dataURI, если оно есть, то есть и поддержка. Способ не работает в IE8 и IE9 — тот и другой не умеют загружать Джаваскрипт этим образом. Собственно, меня это не волнует — мне как раз и нужно определить, что Джаваскрипт так работает, но если вам нужно не это, то должен работать вот такой способ:

<link rel="stylesheet" href="data:text/css,html{font-size:99px}">

То есть устанавливаем у тега HTML какое-нибудь свойство, которое потом в BODY перекроем, а позже, чтобы убедиться, что поддержка дата-ури есть, смоторим что вышло (тут я при помощи jQuery это делаю):

/99/.test($('html').css('font')); // true, если есть поддержка dataURI

Use SVG

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

Одним из главных помощников в такой вёрстке является, без сомнения, формаг СВГ — формат векторной графики, который на данный момент поддерживают все распространённые браузеры (включая ИЕ, с девятой версии). Особенно приятно, что его можно включать прямо внутрь ХТМЛя, это очень удобно — если СВГ используется для кучи мелких значков на странице, то не будет лишних соединений с сервером — ведь всё грузится вместе с основным кодом.

Но встаёт другая проблема — проблема повторного использования. Если одни и те же значки присутствуют на странице в изобилии, страница будет распухать, что печально.

К счастью, есть выход. СВГ — гибкая штука, в этом формате есть возможность использования частей изображения повторно. Первым шагом нужно определить тег-контейнер с необходимыми нам изображениями, по одному в теге symbol. У каждого из них будет собственный идентификатор, по которому мы ниже будем на них ссылаться:

<svg style="display:none">
    <symbol id="folder" viewBox="0 0 49.833 67.167">
        <!-- код не рабочий, только для примера -->
        <path d="M15.938,67.…"/>
        <path d="M3.59,30.531c…"/>
    </symbol>
    <symbol id="file" viewBox="0 0 49.833 67.167">
        <path d="M12.233c0.…"/>
        <path d="M3.28C2.76…"/>
    </symbol>
</svg>

Тут у нас два изображения — folder и file, на которые мы можем сослаться следующим образом:

<svg width="28" height="37">
    <use xlink:href="#folder"/>
</svg>

<svg width="28" height="37">
    <use xlink:href="#file"/>
</svg>

Таких вставок может быть сколько угодно и все они будут использовать одни и те же изображения, описанные в теге-контейнере. Остаётся даже возможность лёгкой настройки под себя, например, можно задать парочку классов и раскрасить часть изображения в разные цвета:

svg.green {
    fill: green;
}

svg.red {
    fill: red;
}

Классы можно повесить на ссылающиеся теги СВГ, жаль только этот способ полон ограничений. Кроме как в ФФ более избирательные селекторы использовать не удаётся — всё, что ниже тега use для таблицы стилей как будто не существует. Если и есть какой-то способ это починить, я его не нашёл.

Chrome (but not Safari) CSS hack

Обратил внимание, что половина интернета сбилась с ног в попытках найти стильевой хак для «Хрома», который не срабатывал бы в «Сафари». Неясно почему его ещё никто не придумал, у меня на это ушла пара минут:

@supports (top: 0__qem) {
    .chrome-only {
        border: 1px solid #000; /* стиль только для Chrome (не Safari) */
    }
}

Работает начиная с 28-го «Хрома» и не работает на «Сафари» (включая последнюю версию 7.0.5). Принцип простой, как чихание — «Сафари», даже самый свежий, не поддерживает конструкцию «@supports», правда её поддерживает Файерфокс и зомби «Оперы».

Эта стандартная конструкция предназначена для проверки — поддерживает ли браузер указанное свойство. Недостаточно подставить туда свойство с префиксом webkit — сейчас многие браузеры читают такие свойства как свои, над что-то иное.

Чтобы отсечь лишнее, я использую нестандартную единицу измерения Вебкита — «__qem», я о ней писал несколько лет назад. Вместе получается, что стиль в «Сафари» не срабатывает, потому что тот не поддерживает «@supports», а в остальных браузерах — потому что они не поддерживают «__qem».

Естественно, обёртки над Вебкитом (новая «Опера», браузер «Яндекса» и прочее) стиль увидят — но на то они и обёртки.

CSS variables

Константы в ЦСС (которые почему-то называются «переменными») — прекрасная штука, особенно в сочетании с вычисляемыми выражениями (calc). Я рад, что браузеры постепенно внедряют эксперементальную поддержку, с нынешними темпами обновшения есть надежда начать это использовать уже очень скоро (calc я уже использую, его ограниченно поддерживает даже IE9).

Идея замечательная — если у вас есть какая-то общая для многих элементов характеристика, можно её вынести в переменную и менять из одного места. Этого настолько нехватает, что появилась целая куча предпроцессоров, которые расцвели вокруг этой проблемы, как ряска на стоячей воде. Справедливости ради, это не единственная проблема, которой они кормятся, но самая важная, на мой взгляд.

В 31-м Файерфоксе (он пока ещё в бете) синтаксис констант сменился и теперь будет включен по-умолчанию. Выглядит это так:

:root {
  --bgcolor: #000; 
}

body {
  background-color: var(--bgcolor);
}

Как видите, префикс «var» сменился на два минуса в полном соответствии с изменениями в стандарте. Чем не устроил предыдущий синтаксис мне не интересно, но этот префикс набирать определённо быстрее — всего-то надо нажать одну клавишу два раза.

IE9 и таблицы

IE9 и таблица (18.31КиБ)

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

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

Дело оказалось в пробелах между ячейками — верстальщик отформатировал шаблон, чтобы он лучше читался, и все браузеры всё показали правильно, один девятый Эксплорер сошёл с ума. Лечится проблема запросто — либо убираем форматирование в шаблоне, либо убираем его прямо в браузере.

Я выбрал второй путь. Пусть лучше шаблон выглядит читаемо, а костыль для девятого Эксплорера всегда можно будет убрать лёгким движением руки. Выглядит он вот так, кстати (используется jQuery, само собой):

$("table tr").contents().filter(function() {
    return this.nodeType == 3;
}).remove();

Свёртка в вебе

Я как-то пропустил момент, когда фильтры SVG стало можно накладывать на обычный тег IMG, а не на изображения внутри SVG же. Любопытные эффекты можно делать, например, можно наложить свёртку для выделения краёв и это будет работать:

<style>
    .edge {
        -webkit-filter: url(#edge);
        filter: url(#edge);
    }
</style>

<svg style="width: 0; height: 0">
<filter id="edge">
<feConvolveMatrix kernelMatrix="-1 -1 -1 -1  9  -1 -1  -1  -1" />
</filter>
</svg>

<image src="sample.jpg" class="edge">

Магические числа в матрице — специальное ядро.

Впрочем, и раньше можно было внедрить в ХТМЛ СВГ-картинку и наложить сверху фильтр, ничего особенного, но мороки чуть больше. При желании этот фильтр можно унести прямо в ЦСС при помощи data URI, но тогда он продублируется два раза — для префиксной и безпрефиксной формы (несмотря на уверения «Кэнайюз», «Хром» и «Сафари» отказались работать без префикса).

С таким возможностями, немудрено, что онлайновых «фотошопов» развелось, как грязи. Немного помучавшись с консолью, можно найти способ как поменять матрицу и это тоже будет работать! Например, вот так меняется число по центру (где у меня в примере девятка записана):

var arr = document.getElementById('edge').childNodes;

for (var i = 0; i < arr.length; i++) {
    if (arr[i].kernelMatrix) {
        arr[i].kernelMatrix.baseVal.getItem(4).value = newvalue;
        break;
    }
}

Осталось только соединить этот код с «крутилкой» и готов онлайн-фильтр «выделение краёв».

CSS parent selector

Тема родительского селектора в ЦСС всплывает ужа давно, если не ошибаюсь, в Вебките даже как-то был эксперементальный синтаксис для его поддержки.

Что такое родительский селектор? О, это очень простая и мощная штука, к примеру, если клиент выбрал что-то в каком-то окне, нужно всё окно спрятать. При помощи ЦСС это можно было бы сделать так:

.window < :checked { /* экспериментальный синтаксис родительского селектора из Вебкита */
    display: none;
}

Сразу скажу, задумка мощная, а реализация плохая. Какую проблему тут видно сразу? Непонятно что значает этот знак. Непосредственного родителя мы здесь выбираем или любого? Если непосредственного, как выбрать любого и наоборот?

Все синтаксисы родительского селектора (включая, например, :parent) грешат чем-то подобным — они не гибкие или неоднозначные.

Мне бы хотелось видеть абсолютную гибкость в отношении родительского селектора и мне кажется, синтаксис тут напрашивается сам собой:

.window > (:checked ~ :checked) {
    display: none;
}

Всё сразу становится логично, на мой взгляд: применить стиль к тегу с классом window, у которого два непосредственных потомка-соседа находятся в состоянии «checked».

IE 10 CSS hack

Придумал CSS-хак для Эксплорера 10-й версии, срабатывающий только в режиме совместимости, похоже, что все существующие хаки в нём не работают.

@media , {
    .:valid, body {
        background: red; /* будет красным в Internet Explorer 10 (режим совместимости) */
    }
}

Проверил при помощи сайта «Браузер шотс» ложные срабатывания, как будто всё в порядке, их нет. Не проверял на IE11, не знаю будет ли там работать. Если у кого-то под рукой есть, напишите в комментариях, пожалуйста, интересно же. Ну и под другими браузерами всё равно будет нелишним проверить, напишите срабатывает или нет.

Так же придумал новый хак для обычного режима IE 10:

@media all\0 {
    _:valid, body {
        background: red; /* будет красным в IE 10 */
    }
}

И ещё один:

_:valid\0, body {
    background: green; /* будет зелёным в IE10 */
}

Так же не тестировал на IE11 (мне негде).

Ранее Ctrl + ↓