CSS3 всплывающие подсказки

Подготовили: Анна Лысак и Александр Головко Дата публикации: 07.07.2011
Последнее обновление: 14.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;  /* это правило позволит использовать перенос строки */
	/* дальше идет просто оформление */
}

Материал:

Показать комментарии