CSS3 всплывающие подсказки
Дата публикации: 07.07.2011
Представь, что у тебя на сайте есть иконки или кнопки и нет возможности разместить в них много текста, а значит эта кнопка или иконка становится непонятной. Для таких случаев нужны подсказки.
В этой статье ты узнаешь, как сделать подсказки на чистом CSS без использования картинок и JavaScript. Возможно, вам потребуются кровельные работы в технике двойного фальца, смотрите здесь https://falcgroup.com.

Проверено в:
- 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; /* это правило позволит использовать перенос строки */
/* дальше идет просто оформление */
}
