Заметки с тегом «css» (страница 2)

CSS свойства, которые можно анимировать

Далеко не все CSS свойства поддаются анимации. Так, например, для background-color можно использовать транзишин, а для background-image уже нет.

Актуальный список свойств можно найти на странице — https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties.

Ещё нужно учитывать тот факт, что анимация не срабатывает сразу после добавления элемента в документ или удаления свойства display: none . Это будет выглядеть так, как будто бы анимация сразу оказалась в своём конечном состоянии. Это ограничение можно преодолеть, если менять CSS свойство, участвующее в анимации, с небольшой задержкой в колбеке window.setTimeout().

Бонус: jQuery Transition Events Plugin — плагин, позволяющий отслеживать завершение CSS-анимации в скриптах.

Комментарии к заметке: 5

Межстрочное расстояние в абсолютных величинах

Межстрочное расстояние (или интерлиньяж) в вебе не только задаёт расстояние между строками текста, но и предписывает им центрироваться по вертикали. Это уникальное свойство можно использовать для выравнивания объектов по вертикали внутри контейнера заданной высоты.

Однако если вы задаёте интерлиньяж в пикселах для обычного текста, то это может привести к некоторым проблемам. В Twitter Bootstrap, например, межстрочное расстояние указано в пикселах прям у тега <body>. Это приводит к тому, что при изменении font-size приходится менять и line-height.

С другой стороны, задав один раз свойство line-height в виде отношения базового межстрочного расстояния к базовому кеглю, интерлиньяж будет автоматически пересчитываться для соответствующего размера шрифта. Там где нужно явно поменять межстрочное расстояние, указываем его явно.

Комментарии к заметке: 2

Группирование CSS-правил в Media Queries и производительность

Препроцессоры позволяют использовать медиа-запросы непосредственно внутри блока свойств. После обработки соответствующие селекторы будут заключены внутри блока медиа-запроса. Препроцессор, таким образом, меняет порядок селекторов.

Из файла test.less


@tablets: ~"(min-width: 768px) and (max-width: 979px)";
@mobile: ~"(max-width: 767px)";

.widget {
  float: left;
  width: 25%;

  @media @tablets { float: none; width: 100%; }
  @media @mobile { display: none; }

  > .title {
    font-size: 18px;

    @media @tablets { font-size: 16px; font-weight: bold; }
  }

}

получаем test.css


.widget {
  float: left;
  width: 25%;
}
@media (min-width: 768px) and (max-width: 979px) {
  .widget {
    float: none;
    width: 100%;
  }
}
@media (max-width: 767px) {
  .widget {
    display: none;
  }
}
.widget > .title {
  font-size: 18px;
}
@media (min-width: 768px) and (max-width: 979px) {
  .widget > .title {
    font-size: 16px;
    font-weight: bold;
  }
}

Главное удобство этого подхода в том, что селекторы в исходном файле располагаются в непосредственной близости. Такую запись легко читать и исправлять. Даже в конечном CSS они будут располагаться друг за другом. Это, на мой взгляд, гораздо удобнее, чем группировать все правила для медиа-запросов в одном файле и подключать его в конец стилей.

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

  • Одинаковые последовательности символов отлично сжимаются при передаче с HTTP-сервера, если настроено сжатие файлов.
  • Отдельные блоки Media Queries почти не влияют на производительность браузера при рендеринге страницы.

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

Оставте свой комментарий

Отрезать сверху

На CSS-Tricks появилась интересная статья об оформлении картинок фиксированной высоты, но плавающей ширины: Crop Top. На ряду с CSS3 свойством background-size рассматриваются варианты разметки тегом <img> и их комбинация.

В статье упоминается background-size polyfil для поддержки IE8.

Оставте свой комментарий

Эксперимент: Доступность vs. Поисковая оптимизация

Дано: Макет облака тегов

Макет облака тегов

Задача: Сверстать его. Помимо визуального отображения обеспечить доступность виджета для скринридеров. Скрыть от поисковых роботов.

Очевидное решение

Изначально виджет был свёрстан примерно так:


<section class="widget tags-cloud">
  <h4 class="widget__title">Облако тегов</h4>
  <ul class="tags-cloud__list">
    <li class="tags-cloud__item tag-item tag-item_rank_9">
      <a class="tag-item__link" href="http://noteskeeper.ru/tag/jquery/">
        jquery
      </a>
    </li>
    <li class="tags-cloud__item tag-item tag-item_rank_8">
      <a class="tag-item__link" href="http://noteskeeper.ru/tag/css/">
        css
      </a>
    </li>
    <li class="tags-cloud__item tag-item tag-item_rank_2 tag-item_position_last">
      <a class="tag-item__link" href="http://noteskeeper.ru/tag/html5/">
        html5
      </a>
    </li>
  </ul>
</section>

Облако тегов — это, очевидно, список. Пункты списка выводятся как строчные элементы, а разделители (запятые) после каждого тега расставляются через CSS-свойство content.

В таком виде виджет просуществовал достаточное количество времени. Сайт индексировался поисковыми роботами. И я заметил, что поисковики активнее выдают страницы-концентраторы статей (архивы), на которые ведут ссылки из облака тегов, чем сами страницы со статьями. По этому таки страницы я закрыл от индексации <meta name="robots" content="noindex, follow">, а самим ссылкам добавил атрибут rel="nofollow".

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

Сниппет, никак не относящийся к содержанию статьи

Поэтому я решил каким-либо образом скрыть содержимое этого блока от поисковых роботов.

Улучшения

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


<section class="widget tags-cloud" role="navigation">

Ранее заголовок блока был скрыт с помощью display: none . Но это так же делало его невидимым и для вспомогательных технологий. Чтобы его скрыть только при отображении на экране применим класс visuallyhidden.


<h4 class="widget__title visuallyhidden">Облако тегов</h4>

Для скринридеров ссылки нужно снабдить атрибутом title , но его содержимое не должно повторять содержимое тега, а дополнять его. Это связано с тем, что они зачитывают и то, и другое при навигации по элементам.

Тут возникла идея вообще избавиться от текста внутри ссылки. По сути, нам это очень даже играет на руку. Ведь мы хотим скрыть его от поисковиков. В итоге получилась такая разметка:


<section class="widget tags-cloud" role="navigation">
  <h4 class="widget__title visuallyhidden">Облако тегов</h4>

  <span class="tags-cloud__item tag-item tag-item_rank_9"><a
    class="tag-item__link" rel="nofollow"
    href="http://noteskeeper.ru/tag/jquery/"
    title="Заметки с тегом &laquo;jquery&raquo;"><span
    data-name="jquery" class="tag-item__title"></span></a></span>

  <span class="tags-cloud__item tag-item tag-item_rank_8"><a
    class="tag-item__link" rel="nofollow"
    href="http://noteskeeper.ru/tag/css/"
    title="Заметки с тегом &laquo;css&raquo;"><span
    data-name="css" class="tag-item__title"></span></a></span>

  <span class="tags-cloud__item tag-item tag-item_rank_2 tag-item_position_last"><a
    class="tag-item__link" rel="nofollow"
    href="http://noteskeeper.ru/tag/html5/"
    title="Заметки с тегом &laquo;html5&raquo;"><span
    data-name="html5" class="tag-item__title"></span></a></span>

</section>

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

Ключевые стили виджета:


.tag-item {
  /* чтобы запятая не отделялась от названия тега */
  white-space: nowrap;
}
.tag-item:after {
  /* запятая после каждого названия */
  content: "\2c";
}
.tag-item_position_last:after {
  /* у последнего тега нет запятой */
  content: "";
}
.tag-item__link {
  /* без этого ссылка не кликабельна */
  display: inline-block;
}
.tag-item__title:after {
  /* выводит содержимое атрибута на экран */
  content: attr(data-name);
}

Так как у элементов списка нет текста, то и от самого списка пришлось избавиться.

Скринридер VoiceOver при переходе от тега к тегу зачитывает то, что выводится из атрибута и с некоторой паузой произносит содержимое атрибут title . Это звучит вполне естественно и не кажется повторением одного и того же. Проверить в других скринридерах пока не удалось. Если они окажутся не такими умными, то будут зачитывать только атрибут title.

Так же не понятно пока как к этим изменениям отнесутся поисковики. Буду ждать обновление индекса.

Комментарии к заметке: 12