Как изменить стиль атрибута title внутри тега привязки?

244

Пример:

<a href="example.com" title="My site"> Link </a>

Как изменить представление атрибута title в браузере? По умолчанию у него просто желтый фон и маленький шрифт. Я хотел бы сделать его больше и изменить цвет фона.

Есть ли способ CSS для стилизации атрибута title?

Kunpha
источник

Ответы:

133

Вот пример того, как это сделать:

a.tip {
    border-bottom: 1px dashed;
    text-decoration: none
}
a.tip:hover {
    cursor: help;
    position: relative
}
a.tip span {
    display: none
}
a.tip:hover span {
    border: #c0c0c0 1px dotted;
    padding: 5px 20px 5px 5px;
    display: block;
    z-index: 100;
    background: url(../images/status-info.png) #f0f0f0 no-repeat 100% 5%;
    left: 0px;
    margin: 10px;
    width: 250px;
    position: absolute;
    top: 10px;
    text-decoration: none
}
<a href="#" class="tip">Link<span>This is the CSS tooltip showing up when you mouse over the link</span></a>

Valli
источник
не работает должным образом в FF , если вместо тега использовать тег, например, тд
dnim
6
См. Sixrevisions.com/css/css-only-tooltips для примера вышеупомянутой техники с подробным объяснением.
Джордж
1
Когда я делаю это, я вижу двойную подсказку. Стилизованный, а вскоре после этого и не стилизованный. Это на твоей скрипке. Я использую хром. Это ненормальность?
8
Ответ без атрибута title в коде имеет более 100 голосов здесь ...?
Бен
1
Даже не отвечает на фактический вопрос ... бу!
Мэтт
127

Кажется, что на самом деле существует чистое решение CSS, требующее только attrвыражения css , сгенерированного содержимого и селекторов атрибутов (что предполагает, что оно работает еще в IE8):

a[title]:hover:after {
  content: attr(title);
  position: absolute;
}

Источник: https://jsfiddle.net/z42r2vv0/2/

обновление с вводом @ViROscar: обратите внимание, что нет необходимости использовать какой-либо конкретный атрибут, хотя я использовал атрибут «title» в приведенном выше примере; на самом деле, я бы рекомендовал использовать атрибут «alt», так как есть некоторый шанс, что контент будет доступен пользователям, которые не могут воспользоваться CSS.

обновите снова Я не изменяю код, потому что атрибут «title» в основном стал означать атрибут «tooltip», и, вероятно, не очень хорошая идея скрывать важный текст внутри поля, доступного только при наведении, но если вы заинтересованный в том, чтобы сделать этот текст доступным, атрибут "aria-label" кажется лучшим местом для него: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute

Jon Z
источник
11
И если вы не хотите, чтобы родная всплывающая подсказка в конечном итоге также отображалась, вы всегда можете использовать тег «alt» ..
Jon z
1
@Jonz Я пробовал с пользовательским свойством "data-alt = 'alt'", и все идет хорошо. Нет необходимости использовать свойство alt или title.
ViROscar
7
Чистые подсказки CSS имеют серьезные недостатки - они привязаны к элементу и, следовательно, привязаны к его элементу stacking context. Все элементы, positionкроме staticсоздания нового контекста стека и чистых подсказок CSS, не видны снаружи и не могут выходить за пределы такого контекста стека , поэтому, если у вас есть жесткий элемент с положением relative, ваша подсказка CSS не будет видна. Единственное решение - прикрепить всплывающую подсказку к верхнему контексту стека (например <body>), который требует JavaScript.
Вацлав Новотный
к сожалению, это не исчезает при нажатии.
user2705463
72

Вы не можете стилизовать фактический titleатрибут

Способ titleотображения текста в атрибуте определяется браузером и зависит от браузера. Веб-страница не может применить какой-либо стиль к всплывающей подсказке, отображаемой браузером на основе titleатрибута.

Однако вы можете создать нечто очень похожее, используя другие атрибуты.

Вы можете создать псевдо-всплывающую подсказку с помощью CSS и пользовательского атрибута (например data-title)

Для этого я бы использовал data-titleатрибут. data-*Атрибуты - это метод хранения пользовательских данных в элементах DOM / HTML. Есть несколько способов доступа к ним . Важно отметить, что они могут быть выбраны с помощью CSS.

Учитывая, что вы можете использовать CSS для выбора элементов с data-titleатрибутами, вы можете затем использовать CSS для создания :after(или :before), contentкоторый содержит значение атрибута с помощью attr().

Примеры всплывающих подсказок

Больше и с другим цветом фона (по запросу вопроса):

[data-title]:hover:after {
    opacity: 1;
    transition: all 0.1s ease 0.5s;
    visibility: visible;
}
[data-title]:after {
    content: attr(data-title);
    background-color: #00FF00;
    color: #111;
    font-size: 150%;
    position: absolute;
    padding: 1px 5px 2px 5px;
    bottom: -1.6em;
    left: 100%;
    white-space: nowrap;
    box-shadow: 1px 1px 3px #222222;
    opacity: 0;
    border: 1px solid #111111;
    z-index: 99999;
    visibility: hidden;
}
[data-title] {
    position: relative;
}
<a href="example.com" data-title="My site"> Link </a> with styled tooltip (bigger and with a different background color, as requested in the question)<br/>
<a href="example.com" title="My site"> Link </a> with normal tooltip

Более сложный стиль (адаптировано из этого поста в блоге ):

[data-title]:hover:after {
    opacity: 1;
    transition: all 0.1s ease 0.5s;
    visibility: visible;
}
[data-title]:after {
    content: attr(data-title);
    position: absolute;
    bottom: -1.6em;
    left: 100%;
    padding: 4px 4px 4px 8px;
    color: #222;
    white-space: nowrap; 
    -moz-border-radius: 5px; 
    -webkit-border-radius: 5px;  
    border-radius: 5px;  
    -moz-box-shadow: 0px 0px 4px #222;  
    -webkit-box-shadow: 0px 0px 4px #222;  
    box-shadow: 0px 0px 4px #222;  
    background-image: -moz-linear-gradient(top, #f8f8f8, #cccccc);  
    background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #f8f8f8),color-stop(1, #cccccc));
    background-image: -webkit-linear-gradient(top, #f8f8f8, #cccccc);  
    background-image: -moz-linear-gradient(top, #f8f8f8, #cccccc);  
    background-image: -ms-linear-gradient(top, #f8f8f8, #cccccc);  
    background-image: -o-linear-gradient(top, #f8f8f8, #cccccc);
    opacity: 0;
    z-index: 99999;
    visibility: hidden;
}
[data-title] {
    position: relative;
}
<a href="example.com" data-title="My site"> Link </a> with styled tooltip<br/>
<a href="example.com" title="My site"> Link </a> with normal tooltip

Известные проблемы

В отличие от реальной titleвсплывающей подсказки, всплывающая подсказка, созданная вышеупомянутым CSS, не обязательно должна быть видимой на странице (т.е. она может находиться за пределами видимой области). С другой стороны, он гарантированно находится в текущем окне, что не относится к реальной всплывающей подсказке.

Кроме того, псевдо-всплывающая подсказка располагается относительно элемента, который имеет псевдо-всплывающую подсказку, а не относительно того, где находится мышь на этом элементе. Вы можете настроить точную настройку псевдо-всплывающей подсказки. Его появление в известном месте относительно элемента может быть преимуществом или недостатком, в зависимости от ситуации.

Вы не можете использовать :beforeили :afterна элементы, которые не являются контейнерами

В этом ответе есть хорошее объяснение: «Могу ли я использовать псевдоэлемент: before или: after в поле ввода?»

Фактически, это означает , что вы не можете использовать этот метод непосредственно на элементах , как <input type="text"/>, <textarea/>, <img>и т.д. Простое решение , чтобы обернуть элемент это не контейнер в <span>или <div>и есть псевдо-подсказка на контейнере.

Примеры использования псевдо-всплывающей подсказки для <span>переноса неконтейнерного элемента:

[data-title]:hover:after {
    opacity: 1;
    transition: all 0.1s ease 0.5s;
    visibility: visible;
}
[data-title]:after {
    content: attr(data-title);
    background-color: #00FF00;
    color: #111;
    font-size: 150%;
    position: absolute;
    padding: 1px 5px 2px 5px;
    bottom: -1.6em;
    left: 100%;
    white-space: nowrap;
    box-shadow: 1px 1px 3px #222222;
    opacity: 0;
    border: 1px solid #111111;
    z-index: 99999;
    visibility: hidden;
}
[data-title] {
    position: relative;
}

.pseudo-tooltip-wrapper {
    /*This causes the wrapping element to be the same size as what it contains.*/
    display: inline-block;
}
Text input with a pseudo-tooltip:<br/>
<span class="pseudo-tooltip-wrapper" data-title="input type=&quot;text&quot;"><input type='text'></span><br/><br/><br/>
Textarea with a pseudo-tooltip:<br/>
<span class="pseudo-tooltip-wrapper" data-title="this is a textarea"><textarea data-title="this is a textarea"></textarea></span><br/>


Из приведенного выше кода в сообщении блога (который я впервые увидел в ответе, который его занимал плагиатом), для меня стало очевидным использование data-*атрибута вместо titleатрибута. Это также было предложено в комментарии snostorm к этому (теперь удаленному) ответу.

Makyen
источник
1
Возможно, это не ответ на вопрос, но это пока лучшее решение. Спасибо.
Джей Джей Лабахо
@JJLabajo Спасибо за дополнение к тому, что это лучшее решение на сегодняшний день. Тем не менее, я не уверен, как это не отвечает на вопрос. Вопрос в том, чтобы спросить что-то, что просто невозможно. Этот ответ говорит, что это невозможно, но предлагает альтернативу, которая выполняет нечто подобное тому, что желает ОП.
Макьен
Я думаю, что это решение не относится к таким элементам, как input[type='text']или textarea, но я не знаю почему. Кто-нибудь может объяснить?
Cheeso
@Cheeso Вы правы, псевдоэлементы :beforeи :afterне работают с элементами, которые не являются контейнерами. В ответе есть хорошее объяснение: можно ли использовать псевдоэлемент: before или: after в поле ввода? Чтобы использовать этот метод, вероятно, проще всего обернуть элементы, которые не являются контейнерами в <span>или <div>в котором вы помещаете data-titleатрибут. Вы, вероятно, также захотите дать их display: inline-block;, так как это сделает их того же размера, что <input>и <textarea>. Я обновил этот ответ с примером.
Макьен,
Этот ответ фактически учит нас тому, что происходит, и предоставляет все виды хорошо структурированной справочной информации.
Идеограмма
26

CSS не может изменить внешний вид всплывающей подсказки. Это зависит от браузера / ОС. Если вы хотите что-то другое, вам придется использовать Javascript для создания разметки при наведении курсора на элемент вместо всплывающей подсказки по умолчанию.

Клетус
источник
22
Для этого не нужно использовать JS.
ANeves
9
Риск ответов «вы не можете» состоит в том, что они могут устареть. (Другой риск заключается в том, что вы можете просто не знать, как.)
Майкл Шепер,
12

Я думал, что выложу свое решение на 20 строк JavaScript здесь. Это не идеально, но может быть полезно для некоторых в зависимости от того, что вам нужно из ваших подсказок.

Когда его использовать

  • Автоматически стилизует всплывающую подсказку для всех элементов HTML с определенным TITLEатрибутом (это включает элементы, динамически добавляемые в документ в будущем)
  • Никаких изменений или хаков Javascript / HTML не требуется для каждой подсказки (только TITLEатрибут, семантически чистый)
  • Очень легкий (добавляет около 300 байтов в сжатом и сжатом виде)
  • Вы хотите только очень простую стилизованную подсказку

Когда НЕ использовать

  • Требуется jQuery, поэтому не используйте, если вы не используете jQuery
  • Плохая поддержка вложенных элементов, которые имеют всплывающие подсказки
  • Вам нужно более одной подсказки на экране одновременно
  • Вам нужна всплывающая подсказка через некоторое время

Код

// Use a closure to keep vars out of global scope
(function () {
    var ID = "tooltip", CLS_ON = "tooltip_ON", FOLLOW = true,
    DATA = "_tooltip", OFFSET_X = 20, OFFSET_Y = 10,
    showAt = function (e) {
        var ntop = e.pageY + OFFSET_Y, nleft = e.pageX + OFFSET_X;
        $("#" + ID).html($(e.target).data(DATA)).css({
            position: "absolute", top: ntop, left: nleft
        }).show();
    };
    $(document).on("mouseenter", "*[title]", function (e) {
        $(this).data(DATA, $(this).attr("title"));
        $(this).removeAttr("title").addClass(CLS_ON);
        $("<div id='" + ID + "' />").appendTo("body");
        showAt(e);
    });
    $(document).on("mouseleave", "." + CLS_ON, function (e) {
        $(this).attr("title", $(this).data(DATA)).removeClass(CLS_ON);
        $("#" + ID).remove();
    });
    if (FOLLOW) { $(document).on("mousemove", "." + CLS_ON, showAt); }
}());

Вставьте его куда угодно, он должен работать, даже если вы запустите этот код до того, как DOM будет готов (он просто не покажет ваши всплывающие подсказки, пока DOM не будет готов).

Настроить

Вы можете изменить varобъявления во второй строке, чтобы немного их настроить.

var ID = "tooltip"; // The ID of the styleable tooltip
var CLS_ON = "tooltip_ON"; // Does not matter, make it somewhat unique
var FOLLOW = true; // TRUE to enable mouse following, FALSE to have static tooltips
var DATA = "_tooltip"; // Does not matter, make it somewhat unique
var OFFSET_X = 20, OFFSET_Y = 10; // Tooltip's distance to the cursor

Стиль

Теперь вы можете стилизовать ваши всплывающие подсказки, используя следующий CSS:

#tooltip {
    background: #fff;
    border: 1px solid red;
    padding: 3px 10px;
}
ChrisF
источник
2
Прекрасно работает! Исправление для незначительной ошибки (если заголовок пуст) можно найти здесь: stackoverflow.com/questions/26702472/…
Malasorte
Если вы быстро перемещаетесь по элементу, я получаю пустую подсказку, даже с указанным выше исправлением ошибки. Это ошибочно и останавливается, если я снимаю $ (this) .removeAttr ("title"). Но, конечно, через некоторое время я получаю стандартную справку.
Аллен Конквест
10

Я нашел ответ здесь: http://www.webdesignerdepot.com/2012/11/how-to-create-a-simple-css3-tooltip/

мой собственный код выглядит следующим образом: я изменил имя атрибута. Если вы сохраняете имя заголовка для атрибута, в результате у вас появляются два всплывающих окна для одного и того же текста, другое изменение заключается в том, что мой текст при наведении курсора отображается под отображаемым текстом.

.tags {
  display: inline;
  position: relative;
}

.tags:hover:after {
  background: #333;
  background: rgba(0, 0, 0, .8);
  border-radius: 5px;
  bottom: -34px;
  color: #fff;
  content: attr(glose);
  left: 20%;
  padding: 5px 15px;
  position: absolute;
  z-index: 98;
  width: 350px;
}

.tags:hover:before {
  border: solid;
  border-color: #333 transparent;
  border-width: 0 6px 6px 6px;
  bottom: -4px;
  content: "";
  left: 50%;
  position: absolute;
  z-index: 99;
}
<a class="tags" glose="Text shown on hovering">Exposed text</a>

Андрес Чандия
источник
7

Jsfiddle для пользовательского шаблона всплывающей подсказки здесь

Он основан на CSS позиционировании и селекторах псевдо-классов

Проверьте MDN документы для кросс-браузерной поддержки псевдо-классов

    <!-- HTML -->
<p>
    <a href="http://www.google.com/" class="tooltip">
    I am a 
        <span> (This website rocks) </span></a>&nbsp; a developer.
</p>

    /*CSS*/
a.tooltip {
    position: relative;
}

a.tooltip span {
    display: none;    
}

a.tooltip:hover span, a.tooltip:focus span {
    display:block;
    position:absolute;
    top:1em;
    left:1.5em;
    padding: 0.2em 0.6em;
    border:1px solid #996633;
    background-color:#FFFF66;
    color:#000;
}
prasun
источник
5

Родная подсказка не может быть стилизована.

При этом вы можете использовать некоторую библиотеку, которая отображала бы стили с плавающими слоями при наведении элемента (вместо собственных всплывающих подсказок и подавляющих их), требующих небольших или никаких изменений кода ...

Понча
источник
Я не думаю, что вы можете подавить всплывающие подсказки, если элемент имеет titleатрибут. Поэтому, если вы настроите свою собственную реализацию всплывающей подсказки, лучше использовать какой-либо другой атрибут (скажем, data-tip) вместо title.
Юкка К. Корпела
1
Вы можете, если после присоединения к событию вы очистите атрибут заголовка
Понча
1
Я понимаю вашу точку зрения, но дело не в стилизации подсказок; Речь идет об их избежании (путем изменения DOM).
Юкка К. Корпела
@ JukkaK.Korpela да, и я сказал в своем первом предложении, что это было невозможно;)
Понча
Преимущество использования атрибута title и его очистки позже заключается в том, что всплывающая подсказка по-прежнему доступна, если у пользователя отключен JavaScript.
JJJ
2

Вы не можете стилизовать всплывающую подсказку браузера по умолчанию. Но вы можете использовать javascript для создания своих собственных подсказок HTML.

bfavaretto
источник
-1
a[title="My site"] {
    color: red;
}

Это также работает с любым атрибутом, который вы хотите добавить, например:

HTML

<div class="my_class" anything="whatever">My Stuff</div>

CSS

.my_class[anything="whatever"] {
    color: red;
}

Смотрите, как это работает на: http://jsfiddle.net/vpYWE/1/

Шана.
источник
14
Стилизует элемент с указанным заголовком; не заголовок всплывающей подсказки, который отображает браузер
Rowland Shaw
1
Кроме того, anythingнедопустимый атрибут HTML. Для пользовательских атрибутов используйте data-атрибуты.
user4642212