Дано: Макет облака тегов
Задача: Сверстать его. Помимо визуального отображения обеспечить доступность виджета для скринридеров. Скрыть от поисковых роботов.
Очевидное решение
Изначально виджет был свёрстан примерно так:
<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="Заметки с тегом «jquery»"><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="Заметки с тегом «css»"><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="Заметки с тегом «html5»"><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
.
Так же не понятно пока как к этим изменениям отнесутся поисковики. Буду ждать обновление индекса.
Коментарии к заметке
Можно же запятую ставить с помощью :before и убирать у :first-child, тем самым избавившись от класса. Почему выбрали иной способ?
Всё верно, Андрей. Так тоже можно сделать. Каких-то объективных аргументов за или против сейчас привести не могу. Возможно, 3 года назад я ещё как-то подсознательно заботился об IE6. А раз в шаблоне уже был предусмотрен дополнительный класс у последнего пункта списка, то решил не менять тут ничего.
Минус у
:before
в том, что нужно обязательно убирать пробелы между пунктами списка, а зазор делать через padding. В варианте с:after
зазоры формируются естественным образом с помощью пробелов.Страницы вида «Заметки с тегом …» рано или поздно выпадут из индекса поисковиков. Сниппеты сменятся. Вообще, убрать текст ссылок – это такая крутая мера, может оно того и не стоило!? Ведь запросу pattern у вас релевантна всего одна-две страницы, по сути, https://www.google.ru/#hl=en&output=search&q=pattern+site:noteskeeper.ru Вот поисковик и притягивает помимо них, что может. Проблемы не существует :)
Но вообще, да, метод интересный. Я помню, раньше ограничивались noindex, затем стали убирать лишнее в document.write, теперь так
Я облако тегов привёл в примере из-за его простоты и наглядности. Основной целью для меня был блок ссылок на архивы по месяцам. По мимо того, что он так же повторяется на каждой странице, названия месяцев повторяются из года в год. Там в
title
указал название с годом и количеством заметок для каждого месяца. Принцип остаётся тот же.Сама по себе поисковая оптимизация применительно к блогу меня мало заботит. Можно расценивать его как тренировочную площадку. Если методика покажет себя с лучшей стороны, то её можно будет применять по назначению в проектах. Как-то так.
Кстати, с
:before
может быть проблема такого рода: запятая будет переноситься на другую строку при определённых условиях. В случае с:after
я могу добавить контейнеру white-space: nowrap и разделитель точно будет «приклеен» к названию.Ставить запятую через :before как-то несемантично, запятая должна ставится у слова, возле которого она визуально расположена, отсюда и соответствующие проблемы с переносами. Кстати, а почему нельзя воспользоваться :last-child?
Псевдоселектор
:last-child
не работает в IE7 и IE8.Ещё
:last-child
очень дорогой селектор, лучше обходиться более быстрым решением с:first-child
Спустя две недели после начала эксперимента могу констатировать тот факт, что из выдачи Google по запросу «pattern» уже почти нет мусорных страниц. В Яндексе, однако, они по прежнему остались.
По поводу скрытия ссылок от поисковиков. А разве тег «а» и «href» внутри него, не показывает роботу, что это ссылка?
Да, показывает. Но у ссылки ещё должен быть текст, поясняющий что будет показано при переходе по этой ссылки. Если его нет, то для поисковика такая ссылка будет бессмысленна в плане ранжирования контента.
Ремарка: В 2018 году я бы рекомендовал проверить какие-то менее радикальные методы сокрытия контента от поисковых роботов.
Насчет ремарки и поисков скрытия ссылок. Скрыть ссылки с помощью JS (document.write) уже не получится.
Остается iframe. Но нормальных гайдов по этой теме нет в рунете. Могли бы вы написать такой гайд?