4

I am reading css-tricks and in the end I can see the following.

Using an HTML5 data attribute, then pulling that attribute in and styling it as a pseudo element, we can create completely custom tooltips through CSS.

enter image description here

The problem is that the link inside of the article is dead, and I am not such a good html/css guy to be able to understand how to do this. Can anyone help?

4
  • 1
    You can do it like this mate. Note: It doesn't have the arrow shape at the bottom but that can be achieved with a little more work :) Commented Aug 9, 2014 at 2:19
  • This is the non-broken version of the link: codepen.io/css-tricks/pen/wFeaG Commented Aug 9, 2014 at 3:04
  • This is a great website to keep update.. Here you can see how to create tooltip with data attribute.webdesign.tutsplus.com/articles/…. Commented Aug 9, 2014 at 3:20
  • Added a canonical answer here. Commented Sep 14, 2014 at 18:25

4 Answers 4

9

JSFiddle is here. Note: The original content is here.

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

.tooltip:hover {
  color: #c00;
  text-decoration: none;
}

.tooltip:hover:after {
  background: #111;
  background: rgba(0, 0, 0, .8);
  border-radius: .5em;
  bottom: 1.35em;
  color: #fff;
  content: attr(title);
  display: block;
  left: 1em;
  padding: .3em 1em;
  position: absolute;
  text-shadow: 0 1px 0 #000;
  white-space: nowrap;
  z-index: 98;
}

.tooltip:hover:before {
  border: solid;
  border-color: #111 transparent;
  border-color: rgba(0, 0, 0, .8) transparent;
  border-width: .4em .4em 0 .4em;
  bottom: 1em;
  content: "";
  display: block;
  left: 2em;
  position: absolute;
  z-index: 99;
}
<p>Vestibulum mollis mauris <a href="#" class="tooltip" title="Sample tooltip">pellentesque</a></p>

Sign up to request clarification or add additional context in comments.

1 Comment

Nice solution, however instead of the title attribute I'd use the HTML5 data attributes (e.g. data-title) in order to prevent the browser to display the default tooltip.
7

The good answers have already been given, but they all lack generality. Hence, I want to provide a more general solution to create tooltips with just span and its pseudo-elements (before and after) which provides positions also using data attributes.

Here is the markup for a span element.

  <span 
    class="tooltip"
    data-tooltip-position="right"
    data-tooltip="Only gmail will be accepted!">?</span>

And here is final code snippet:

body {
  margin: 0;
  background-color: #359;
}

.form-box {
  position: relative;
  width: 400px;
  padding: 50px 60px;
  margin: 5% auto;
  background-color: rgb(240, 230, 255);
  border-radius: 10px;
  text-align: center;
}

.form-box > input[type='text'] {
  box-sizing: border-box;
  padding: 8px;
  border-radius: 5px;
  outline: none;
  border: 2px solid #aaa;
  transition: all 0.2s ease-out;
}

.form-box > input:focus {
   border-color: dodgerblue;
   box-shadow: 0 0 8px 0 dodgerblue;
}

/* Tooltip Styles */

.tooltip {
  position: relative;
  padding: 5px 10px;
  margin-left: 15px;
  margin-right: 15px;
  background-color: rgb(56, 56, 56);
  border-radius: 50%;
  color: #fff;
  cursor: help;
  transition: all 0.2s ease-out;
}

.tooltip:hover {
  box-shadow: 0 0 6px 0 black;
}


.tooltip::before, .tooltip::after {
   position: absolute;
   left: 50%;
   opacity: 0;
   transition: all 0.2s ease-out;
}

.tooltip::before {
  content: "";
  border-width: 5px 4px 0 5px;
  border-style: solid;
  border-color: rgba(56, 56, 56, 0.8) transparent;
  margin-left: -4px;
  top: -8px;
}

.tooltip::after {
  content: attr(data-tooltip);
  top: -8px;
  width: 150px;
  margin-left: -75px;
  padding: 5px;
  font-size: 12px;
  background-color: rgba(56, 56, 56, 0.8);
  border-radius: 4px;
  transform: translate3d(0, -100%, 0);
  pointer-events: none;
}

/* 4 tooltip positions */

.tooltip[data-tooltip-position='left']::before {
  margin-left: -21px;
  top: 12px;
  transform: rotate(-90deg);
}

.tooltip[data-tooltip-position='left']::after {
  transform: translate3d(-65%, 40%, 0);
}

.tooltip[data-tooltip-position='right']::before {
  margin-left: 14px;
  top: 12px;
  transform: rotate(90deg);
}

.tooltip[data-tooltip-position='right']::after {
  transform: translate3d(60%, 40%, 0);
}

.tooltip[data-tooltip-position='bottom']::before {
  margin-left: -4px;
  top: 32px;
  transform: rotate(-180deg);
}

.tooltip[data-tooltip-position='bottom']::after {
  transform: translate3d(0, 186%, 0);
}

/* end of 4 tooltip positions */

.tooltip:hover::before, .tooltip:hover::after {
  opacity: 1;
}
<div class="form-box">

  <span 
    class="tooltip"
    data-tooltip-position="left"
    data-tooltip="Only gmail will be accepted!">?</span>

  <span 
    class="tooltip"
    data-tooltip-position="up"
    data-tooltip="Only gmail will be accepted!">?</span>

  <input type="text" class="input" placeholder="Email">
  

    
  <span 
    class="tooltip"
    data-tooltip-position="bottom"
    data-tooltip="Only gmail will be accepted!">?</span>    
    
  <span 
    class="tooltip"
    data-tooltip-position="right"
    data-tooltip="Only gmail will be accepted!">?</span>

</div>

2 Comments

How to invoke from a button click instead of hover? eg. ( invalid email address )
@patrick I believe that would be an entirely different question with answers probably found here: stackoverflow.com/questions/59527327/…
4

You can achieve this by using the HTML5 data attributes, a couple of pseudo-elements and a bit of positioning like below:

a {
  position: relative;  /* to position the tooltip relative to the anchor tag */
}
a:hover {  /* for achieving the arrow shape at the bottom of the tooltip */
  text-decoration: none;
}
a::after,
a::before {
  position: absolute;
  display: none;  /* initially hide it from view */
}
a::before {
  content: '';
  top: -2px;
  left: 6px;
  height: 0px;
  width: 0px;
  /* the arrow */
  border-left: 5px solid transparent;
  border-top: 5px solid #ffe4b5;
  border-right: 5px solid transparent;
}
a::after {
  content: attr(data-tooltip);  /* set content of pseudo element as the value of data-tooltip attribute */
  top: -25px;
  left: -5px;
  background: #ffe4b5;
  border-radius: 4px;  /* just a bit of extra styling */
  padding: 2px 6px;
  white-space: nowrap;
  color: black;
}
a:hover::after,
a:hover::before {
  display: block;  /* display both tooltip and arrow mark when a is hovered on */
}

/* Just for demo */

* {
  font-family: Calibri;
}
.wrapper {
  margin: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<!-- the data-tooltip attribute in the a tag has the tooltip's contents -->
<div class='wrapper'>Some long long text blah blah with some <a href='#' data-tooltip='Tooltip'>link</a> inside it.
  <br/>Some more text blah blah with some <a href='#' data-tooltip='Long Tooltip'>link</a> inside it</div>

You can also use the title attribute for the tooltip content. That will make fallback easy in older browsers also. Also, I have used some generic selectors, you can make it more specific.


Advanced Sample: Below is a more advanced version of the tool-tip with borders and transition effects achieved using CSS3 properties.

a {
  position: relative;
}
a:hover {
  text-decoration: none;
}
a::after,
a::before {
  position: absolute;
  visibility: hidden;
  background: #ffe4b5;
  border: 1px solid #f3b445;
  opacity: 0;
  transition: all 0.4s ease-out;
}
a:hover::after,
a:hover::before {
  visibility: visible;
  opacity: 1;
}
a::before {
  content: '';
  top: -3px;
  left: 6px;
  height: 4px;
  width: 4px;
  border-color: transparent #f3b445 #f3b445 transparent;
  transform: rotate(45deg);
  z-index: 2;
}
a::after {
  content: attr(data-tooltip);
  top: -25px;
  left: -5px;
  border-radius: 4px;
  padding: 2px 6px;
  white-space: nowrap;
  color: black;
}
/* Just for demo */

* {
  font-family: Calibri;
}
.wrapper {
  margin: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='wrapper'>Some long long text blah blah with some <a href='#' data-tooltip='Tooltip'>link</a> inside it.
  <br/>Some more text blah blah with some <a href='#' data-tooltip='Long Tooltip'>link</a> inside it</div>

Points to note:

  1. Transitions on pseudo elements is well supported in Firefox but doesn't work on Chrome v24 (and less). For the browsers that don't support it, there would be no transition effect.
  2. The sample with a border to the tool-tip uses CSS3 transforms for the arrow and hence would need a CSS3 compatible browser to work properly.

Comments

0

I can see that the accepted answer has been already provided using attr css method. But if we hover over our element, we find that the default browser tooltip also appears along with the custom tooltip. This isn't a correct approach in terms of user experience.

So creating 2 CSS classes with absolute positioning on a tooltip element like span would still provide a

reusable tooltip experience

You can find the code here and video here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.