CSS3 всплывающие подсказки
Дата публикации: 07.07.2011
Представь, что у тебя на сайте есть иконки или кнопки и нет возможности разместить в них много текста, а значит эта кнопка или иконка становится непонятной. Для таких случаев нужны подсказки.
В этой статье ты узнаешь, как сделать подсказки на чистом CSS без использования картинок и JavaScript.
Проверено в:
- IE 6-8
- Firefox 4
- Opera 9.5-10
- Safari 4
- Chrome
А мне нужны подсказки на CSS?
HTML атрибут title — это подсказка по умолчанию и ты вполне можешь воспользоваться таким вариантом. Но подсказки по умолчанию невозможно стилизовать. И, если нам нужны необычные подсказки, значит нужно сделать их самим.
Как это делается
Ты можешь быть знаком с этим методом: абсолютно позиционируемый элемент располагается внутри относительно позиционируемого. Но я сейчас не буду пытаться заново изобрести велосипед, а просто расскажу, как при помощи CSS3 сделать действительно классные подсказки.
Ниже на рисунке можешь увидеть правильную структуру подсказки. И здесь нужно обратить внимание на два указателя (сделаны с использованием псевдоэлементов :before и :after), которые перекрывают друг друга:
как делается окаймленный указатель
При создании подсказки использовались:
- градиенты;
- box-shadow;
- псевдоэлементы.
<a href="#" class="tooltip"> your text <span>Your tooltip description</span> </a>
Почему именно ссылка?
Просто из соображений совместимости. В IE6 возникают проблемы с псевдоклассом :hover, если он используется с каким либо другим другим элементом кроме ссылки.
Если хочешь сделать такие подсказки без ссылки, можно использовать вот такой прием для вызова подсказки в IE6:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script> <script type="text/javascript"> $(function() { if ($.browser.msie && $.browser.version.substr(0,1)<7) { $('.tooltip').mouseover(function(){ $(this).children('span').show(); }).mouseout(function(){ $(this).children('span').hide(); }) } }); </script>
.tooltip { position: relative; background: #eaeaea; cursor: help; display: inline-block; text-decoration: none; color: #222; outline: none; } .tooltip span { visibility: hidden; position: absolute; bottom: 30px; left: 50%; z-index: 999; width: 230px; margin-left: -127px; padding: 10px; border: 2px solid #ccc; opacity: .9; background-color: #ddd; background-image: -webkit-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0)); background-image: -moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0)); background-image: -ms-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0)); background-image: -o-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0)); background-image: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0)); -moz-border-radius: 4px; border-radius: 4px; -moz-box-shadow: 0 1px 2px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.5) inset; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.5) inset; box-shadow: 0 1px 2px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.5) inset; text-shadow: 0 1px 0 rgba(255,255,255,.4); } .tooltip:hover { border: 0; /* IE6 fix */ } .tooltip:hover span { visibility: visible; } .tooltip span:before, .tooltip span:after { content: ""; position: absolute; z-index: 1000; bottom: -7px; left: 50%; margin-left: -8px; border-top: 8px solid #ddd; border-left: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 0; } .tooltip span:before { border-top-color: #ccc; bottom: -8px; }
Поддержка в браузерах
Решение кроссбраузерное и работает даже в IE6 и IE7 (для того чтобы в этих древних браузерах выводился указатель воспользуйся приемом, описанным в статье Эмуляция псевдоэлементов after и before для IE 6-7).
Долой лишний тег! Юзаем атрибуты.
Update 14.07.2011 by SelenIT и Александр Головко.
В предыдущем решении есть один большой минус — используется совершенно левый тег span. Давай попробуем от него избавится и расположить подсказку там, где она должна быть — в атрибуте. Идеальное решение выглядело бы так:
<a href="#" title="Текст подсказки"> Ссылка, нуждающаяся в подсказке </a>
К сожалению, похоже, это тот случай, когда идеальное решение подходит только для шарообразных тегов в вакууме.
Проблема в том, что использовать атрибут title нам никак нельзя. Стилизовать его, по крайней мере кроссбраузерно, точно не получится. Поэтому выводить подсказку будем с помощью псевдоэлемента, например, before, который будет показываться по hover. При этом, если все-таки юзать title, то появятся сразу две подсказки одновременно — красивая и простая. Мягко говоря, не совсем то, что нам нужно.
вот почему нельзя использовать атрибут title
Давай использовать атрибут data-title. HTML тогда станет таким:
<a href="#" data-title="Текст подсказки"> Ссылка, нуждающаяся в подсказке </a>
Для того, чтобы получить текст подсказки (содержащийся в атрибуте) используем хитрый прием:
.tooltip:hover:before { content: attr(data-title); /* дальше идет просто оформление */ }
Собственно, это правило и есть главная фишка метода. В остальном, оформление не будет отличаться от предыдущего варианта.
Проверено в:
- IE 8
- Firefox 4+
- Opera 10.5
- Safari 4
- Chrome
Проблемы метода
В данном методе есть две проблемы. Во-первых он не работает в IE6-7. Связанно это с тем, что эти браузеры не понимают псевдоэлементы after и before. В обычных условиях их можно эмулировать. Но, в данном случае у меня не получилось (по крайней мере, без помощи скрипта) перенести в эмулируемый псевдоэлемент содержимое атрибута data-title.
Вторая проблема в том, что в подсказке, сделанной таким образом, нельзя использовать разметку — она будет просто выводиться, как текст. С другой стороны, во всплывающих подсказках никакая разметка, как правило и не нужна.
Тем не менее считаю это одним из ограничений. Если у кого-нибудь есть идеи, как его преодолеть — пишите, с удовольствием дополним статью.
Пока единственное, чего удалось добиться — это использование переноса строки (в демопримере первая всплывающая подсказка):
.tooltip:hover:before { content: attr(data-title); white-space: pre-line; /* это правило позволит использовать перенос строки */ /* дальше идет просто оформление */ }