Тонкое подчёркивание ссылок с разрывами на буквах «р», «у» и других
У меня на сайте два изменения. Во-первых, я опять втихую увеличил шрифт (я этим занимаюсь время от времени), во-вторых, я изменил стиль подчёркивания ссылок. После сайтов Тёмы и Ильи Бирмана, подчёркивание у меня казалось тяжёлым и давящим, а у них — естественным и воздушным.
Но просто сделать так же не интересно, и я решил сделать лучше. Спорно получилось ли лучше, тут есть простор для экспериментов.
Подчёркивание ссылок и Тёмы и Ильи сделано одинаково — убрано родное подчёркивание, а взамен установлено свойство border-bottom, задающее бордюр толщиной в один пиксель. Мне в этом подходе не понравилось, что бордюр находится неестественно далеко — за хвостиками букв «у», «р» и прочих.
Сначала позвольте показать что получилось, обратите внимание на разрыв на хвостике «р», когда я добился более плотного прилегания, оказалось, что перечёркивание хвостов меня не устраивает, хорошо что удалось это поправить:
Собственно, мне захотелось сначала исправить этот недостаток — слишком далеко отстоящее подчёркивание. Готовое решение у меня было, я когда-то его делал, но оказалось, что у него недостаток — плохо себя ведёт с переносом в ссылках, на вторую и следущие строчки подчёркивание не распространялось.
Я довольно долго эксперементировал и нашёл, в конце-концов, решение — я сделал цветной однопиксельный задний фон (простой ГИФ в data URI) по одному для каждого цвета ссылок: непосещённые, посещённые и с наведением мыши, а потом просто спозиционировал так как мне понравилось.
И вот тут меня ждала неприятность. Дело в том, что некоторое время назад появился способ, позволяющий узнать какие сайты вы посещали; интернет пестрел скриптами, которые в шутку журили вас, если обнаруживали, что вы до этого посещали какие-то порносайты.
Способ проверки простой — на экран выводится ссылка, посещение которой пользователем мы хотим проверить, а потом мы смотрим у неё, скажем, цвет или другой параметр, который мы установили различающимся для посещённых и не посещённых ссылок. Я хорошо помню эту историю, потому что сделал на основе этого скрипт, который определял логинились ли вы в Гмейл — я просто смотрел загружал ли ваш браузер определённые ресурсы, которые грузятся только после логина. Но прежде чем я придумал как это можно практически использовать, дыру начали закрывать, так что скрипт не пригодился.
Естественно, браузеры не могли не отреагировать на эту дыру. Кажется, Файерфокс первым отреагировавшим на проблему — они предложили «врать» разработчику о стиле посещённых ссылок и разрешили менять для них только строго определённый список ЦСС-правил.
Увы, это меняет многое. У меня для того, чтобы цвет посещённых ссылок не различался с цветом подчёркивания, нужно было поменять background-image, а он не входит в список разрешённых к изменению стилей для посещённых ссылок (это естественно, если подумать). На этом этапе я загрустил и долго ничего не мог придумать, но когда начал засыпать, меня осенило.
В голове перед сном я прокручивал список разрешённых к изменению свойств и одно из них, background-color показалось мне подходящим, чтобы решить мою проблему. Я нарисовал ГИФ единичной ширины, совершенно белый, но с одним прозрачным третьим с конца пикселем:
Теперь, если выставить его в качестве стиля заднего фона ссылки, а потом ещё задать цвет фона, ссылка оказывается аккуратно подчёркнутой в нужном мне, регулируемом месте (я же могу сделать прозрачным любой пиксель в фоне).
Ок, это сработало для посещённых ссылок, но в «Хроме» и «Сафари» меня ждал неприятный сюрприз: на мгновение, до того как браузер успевал отрисовать мой ГИФ на заднем фоне, все ссылки выглядели уродливо: был виден их цветной задний фон:
Я подумал, что мне бы помогло, если я бы как-то рисовал подходящий фон без картинки. Долго думать не пришлось, я когда-то эксперементировал с картинками, сделанными при помощи linear-gradient, поэтому для меня было естественными решением сделать стиль, который рисует нужный мне фон этим способом.
Получился следующий стиль:
a {
background: #00e url(data:image/gif;base64,R0lGODlhAQA7APABAP …и так далее… AAACCISPqcvtEEwBADs=) 0 100% repeat-x;
background-image: -webkit-linear-gradient(90deg, #fff 0, #fff 2px, rgba(0,0,0,0) 2px, #fff 3px, #fff 59px);
}
Это полностью решило проблему — мигание на вебкитовских браузерах пропало. Кстати, я применил стиль линейного градиента, в новом формате — он работает в «Сафари» с версии 5.1 и в «Хроме» с десятой. Мне кажется, в этом нет ничего страшного — доля старых браузеров, в данном случае, ничтожна мала.
Когда я поставил подчёркивание куда мне хочется, возникла другая проблема. Эстетическая. Подчёркивание довольно уродливо перечёркивало нижние выносные элементы букв. На память, по аналогии, пришло моё баловство с фильтром Glow в Интернет Эксплорере. Там удавалось добиться интересных эффектов с задним фоном, поскольку эффект ложится и на него. Тут у меня ситуация такая же, но фильтров больше не существует, правда есть их реинкарнация —W3C заботливо слизало идею в другом синтаксисе.
После некоторых экспериментов, я решил, что тут подходит text-shadow — если сделать тень белого цвета, она очень хорошо закрашивает задний фон. Для этого я сделал несколько однопиксельных теней, и одну двухпиксельную на самой границе разрыва — тогда края разрыва размываются и он становится более мягким. И поднял тень немного вверх, иначе некоторые буквы давали неприятные «блики» на подчёркивание:
a {
text-shadow: 1px -1px 1px white, -1px -1px 1px white, 2px -1px 2px white, -2px -1px 2px white;
}
В браузерах, которые этот стиль не поддерживают, подчёркивание просто не будет разорвано.
Стиль, в результате выглядит примерно так:
a {
text-shadow: 1px -1px 1px white, -1px -1px 1px white, 2px -1px 2px white, -2px -1px 2px white;
text-decoration: none;
background: #00e url(data:image/gif;base64,R0lGODlhAQA7APABAP … и так далее … AAACCISPqcvtEEwBADs=) 0 100% repeat-x;
background-image: -webkit-linear-gradient(90deg, #fff 0, #fff 2px, rgba(0,0,0,0) 2px, #fff 3px, #fff 59px);
}
a:visited {
color: #551a8b;
background-color: #551a8b;
}
a:hover {
background-color: red;
color: red;
}
Очень компактно, без лишнего и с плавной деградацией для старых браузеров.
Евгений, не вам одному приходят подобные идеи. Можете сравнить с http://kizu.ru/
:-)
Опера 12.15. При наведении на ссылку «отреагировал на проблему» происходит страшный ужас.
http://img-fotki.yandex.ru/get/4138/130297105.0/0_144047_1bf44b44_L#opera_bg.png%7Chttp%3A%2F%2Ffotki.yandex.ru%2Fusers%2Feyeless-watcher%2Fview%2F1327175%2F%3Fpage%3D0#500x203
Комментарий для Филипп Андрейчев:
О, спасибо! Меня очень интересовало как он решил проблему с посещёнными ссылками, а он её не решил, увы. Зато я у него подсмотрел очистку стиля выделения, у себя я даже ещё пока не столкнулся с этим.
Комментарий для Eyeless:
Да, баги ещё могут быть, этот поправил, спасибо!
Плавный уход в прозрачность выглядит как-то неаккуратно и смазанно под хвостами.
Второй момент — подчеркивание надо делать прозрачнее и бледнее (чтобы было, но при не рябило), в этом был изначальный смысл замены всех этих экспериментов Бирмана, Темы и прочих.
У Комарова разрыв под хвостами выглядит гораздо аккуратнее, кстати.
Вы только что сломали интернет.
вот такое вот в хроме
http://img849.imageshack.us/img849/3193/bolkruchrome.png
Комментарий для Паша:
Спасибо, поправлю!
Здорово, очень приятно выглядит. Вы -- маньяк в самом лучшем смысле этого слова :)
Комментарий для ichik:
Ошибки поправил, хвост сделал как у Комарова, так лучше? Мне нравится пока мой вариант, может я и не прав.
Комментарий для Константин:
Спасибо :)
Комментарий для ichik:
У меня вчера на это времени уже не было, спать хотелось. Сегодня подрихтовал.
Да, я тоже наткнулся на проблему с посещёнными ссылками, но решать не стал т. к. у меня ссылки подчёркиваются по умолчания, а я посещённым ссылкам делал по ховеру цвет не посещённых.
Решение с картинкой/градиентом, накладывающейся поверх background-color — отличное! Возможно, утащу себе когда-нибудь :)
Комментарий для Роман Комаров:
Ок, кстати, зайдя к тебе сегодня, я обнаружил, что ты уже 100 лет ничего нового не писал, кажется, я в последний раз год назад заходил, всё то же :(
Технически интересно, но результат ужасен. Привычные прямые линии разрываются и гразу неприятно читать. Затыкается и приглядывается.
Комментарий для Евгения Степанищева:
Идея прикольная, вот только в хроме под линуксом, у обычных ссылок в тексте, подчеркивание прилипает к буквам и выглядит не очень
Но тут проблема в том, что в линуксе (в данном случае Ubuntu) нет из коробки шрифтов ’Segoe UI’ и ’Helvetica’, а хром, почему-то, не берет следующий в очереди ’Trebuchet MS’(хотя он и установлен), а использует сразу ’Arial’. Вот с Arial оно так плохо и выглядит
Комментарий для Роман Сукочев:
Интересно, почему «Trebuchet MS» не берётся. Надо будет поэксперементировать на выходных.
Комментарий для rmcreative.ru:
Результат ужасен, потому что непривычен? Так многое непривычное кажется ужасным, разве это повод ничего не менять?
Да, виноват, нет мне оправданий. Но! Я с завтрашнего дня ухожу в отпуск и постараюсь разгрести все наброски, что накопились. Так что новое будет и много :)
А нельзя ли сделать CSS-спрайт и менять только background-position?
Подчеркивание ссылок гуд, но еще больше порадовал флаг на статью на английском. Может и раньше было, но я через читалку читаю, не замечал.
P.S. ctrl+enter в хроме не работает.
Комментарий для egorinsk:
Это свойство тоже не входит в список разрешённых.
Комментарий для Дмитрий Шишкин:
Это давно уже так :) Несколько лет.
Посмотрю, спасибо! ОС какая?
Браузер в андроиде виснет намертво когда открывает эту заметку.
Жрет полностью одно ядро процессора и не убивается без перезагрузки.
А как там выглядят ссылки я вообще молчу. :-)
Комментарий для alpha.fm:
Посмотрю в понедельник, на работе есть планшеты на Андроиде.
А еще это дело плохо реагирует на масштабирование страницы: толщина линии скачет, иногда она вообще пропадает. Всё та же Опера 12.15, но подозреваю, что и в остальных браузерах не лучше.
Комментарий для Eyeless:
В «Сафари» (вебкит) всё идеально, а «Оперы» не будет скоро, зачем на неё рассчитывать?
Далеко отстоящий бордюр от строки можно решить задав высоту строки — line-height: 1 и меньше. На ретине картинка выглядет мыльной, кстати.
Комментарий для Ярослав Федин:
Я уже эксперементировал, работает только с display: inline-block, при переносе строки — глюки.
«Ретины» у меня сейчас под рукой нет. Посмотрю в понедельник, это поправимо. Какой браузер, кстати?
Джентльмены, пожалуйста, направьте свою энергию на лоббирование нормальной типографики во всех ОС, на введение новых свойств CSS, а не на ломание интернета.
Вы же все достаточно влиятельны и умны, пожалуйста, делает как нужно, а не как лениво.
Комментарий для jankkhvej.tumblr.com:
Боюсь, мою влиятельность вы преувеличиваете.
Комментарий не постится (или я зобанен)
Только одно «но» — если я не ошибаюсь, то поисковики «не любят» когда есть ссылки, которые сливаются с фоном — это считается признаком black hat SEO. Но может я и ошибаюсь.
ЗЫ — странно, если я указываю адрес блога, то комментарий не постится.
Комментарий для Agonych:
А причём здесь ссылки, которые сливаются с фоном (даже если бы поисковики это умели определять)?
А что за блог? У вас там OpenID?
Комментарий для Евгения Степанищева:
Ну вообще любой текст, если у него цвет как у фона — это один из признаков SEO-спама. В данном случае у твоих ссылок как раз так и получается:
color: #551a8b;
background-color: #551a8b;
Понятно, что там есть что-то еще, но это «еще» вставлено достаточно нестандартным способом и я сомневаюсь что фильтры поисковых роботов умеют такое правильно парсить, а значит теоретически они могут выставить страницам плохой рейтинг из-за таких ссылок. Как там на самом деле — не берусь утверждать, я черным SEO не занимаюсь и о практиках знаю только в стиле «чего стоит избегать». Со своим сайтом, понятное дело, можно извращаться по всякому, но на клиентских я бы не стал рисковать.
Комментарий для Евгения Степанищева:
О, сейчас ссылка прошла, наверно был времнный баг со связью.
Комментарий для agonych.livejournal.com:
Насколько я понимаю, работу различных чекалок, они не работают только по одному критерию. И уж точно я не стал бы полагаться на «мозг» робота в таких спорных вопросах как разбор правил ЦСС.
У Лайвжорнала постоянно какие-то проблемы :(
Евгений, можно ещё у Славы подсмотреть стилистику подчёркивания ссылок http://mrprn.ru/.
Придумался еще вот такой код:
a {
color: blue;
text-decoration: none;
box-shadow: 0 -2px 0 white inset, 0 -3px 0 blue inset;
text-shadow: 1px 0 0 white, -1px 0 0 white;
}
a:active {
color: red;
box-shadow: 0 -2px 0 white inset, 0 -3px 0 red inset;
}
a:visited {
color: purple;
box-shadow: 0 -2px 0 white inset, 0 -3px 0 red purple;
}
масштабируется лучше (линия не разблуривается) но, увы, :visited не работает — линия остается синей.
Комментарий для agonych.livejournal.com:
Да кодов можно сколько угодно придумать (вариант http://kizu.ru, например, подсказали в комментариях), это не фокус. Самая трудность в visited как раз.
Комментарий для Филипп Андрейчев:
OMG. Но он тоже не решил проблему посещённых ссылок.
Комментарий для Евгения Степанищева:
стабильный хром, андроид. все ссылки имеют тонкую рамку.
Комментарий для zg.livejournal.com:
Да, мне уже прислали скриншот, спасибо! Но я ещё не успел посмотреть в чём там дело.
Win7
Комментарий для zg.livejournal.com:
Поправил.
Очень интересный способ, спасибо!
Нашлось несколько особенностей.
Теперь с ссылками на фоне, отличном от белого, нужно (?) что-то делать — http://troloload.ru/f/5451_bg.png
В Файрфоксе линия выглядит лучше всего, одинаково чёткая, при выделении исчезает — http://troloload.ru/f/5452_ff.png
В Хроме курсивный текст ссылки при выделении светится ( http://troloload.ru/f/5453_chrome_glow.png ), а подчёркивание неодинаково — http://troloload.ru/f/5454_chrome_various.png
В Эксплорере 10 линия оказывается по-разному поднята ( http://troloload.ru/f/5455_ie_high.png и http://troloload.ru/f/5456_ie_normal.png%29, ну и несколько проблем с выделением — http://troloload.ru/f/5457_ie_glow.png
Если что, Вин 8.
Комментарий для Сергей Васильев:
Спасибо за баги, я ещё не все нашёл :) Буду исправлять потихоньку :)
Комментарий для Сергей Васильев:
Что при выделении исчезает — не страшно совсем. Никакой дополнительной информации подчёркивание при выделении в себе не несёт.
Это поправил уже.
Вот чёрт, это из-за исправления багов в Андроиде появилось. Теперь надо срочно думать что делать…
Похоже, неодинаковое подчёркивание в Хроме вы уже исправили, по крайней мере, у меня всё отлично!
Отчего-то ИЕ 10 в Винфоне 8 проигнорировал тень — http://troloload.ru/f/5463_ie_wp.jpg
Решил, раз у вас Люмия, вам будет это интересно :)
Комментарий для Сергей Васильев:
Да, поправил :)
Это я вижу, мобильный ИЕ10 вообще странный. Возможно, он просто не поддерживает тень, надо пробовать.
В последних фойрфоксе и хроме подчеркивание прилеплено к буквам снизу. В последней опере нормально, а в старой опере 10.63 вместо ссылок синяя жуть. Система — Win XP.
Комментарий для petya:
Я думаю, что Netscape Navigator 4.03 вообще ужас. Есть какая-то причина по которой вы вынуждены использовать эту древность?
Можете скриншот показать в каком это месте и что вы конкретно имеете ввиду.
Комментарий для Евгения Степанищева:
Firefox 20.0.1 http://i.piccy.info/i7/c46a1c2e6768c6b3651766ff444caec0/4-58-182/54627067/ff_1.png
Chromium 26.0.1410.64 http://i.piccy.info/i7/ea721e6a9ed80f8d00752b4a1c8097fd/4-58-183/1413414/chromium_1.png
В сайдбаре слева и в обычных ссылках в тексте то же самое.
Причина есть, но ее описание выходит за рамки данного топика. Так надо! ;)
Комментарий для petya:
Хм… доберусь до Винды, гляну в чём дело.
Сочувствую :)
Комментарий для Евгения Степанищева:
Судя по тому, что всё осталось как было (подчеркивание прилеплено к буквам снизу), прихожу к такому выводу: нет смысла городить велосипеды, которые хороши только для велосипедистов ростом 1.97 м и размером ноги 36, а потом каждый раз допиливать его для тех, у кого рост 1.50 м, или размер ноги 45...
Комментарий для petya:
…или у меня нет никакой возможности пока посмотреть что происходит под Windows XP. У меня ни одной идеи где я её могу найти.
Привет. А как сделать, чтобы подчеркивание располагалось строго под текстом, а не растягивалось на всю ширину блока?
Исправляет inline-block. Спасибо за хорошую статью.