Calling a CSS class inside another class? - css

Is it possible to have one CSS class reference another? Instead of rewriting all the css code again?
For example, I have this:
.btn{
/* Whatever btn related styles I have */
}
.btn:hover{
box-shadow:0 0 4px black;
}
.btn:active{
/* This is where I want to reference the '.red' class */
}
.red{
/* There is a LOT of CSS code here for cross browser gradients */
}
The thing is, I'm already using the .red class as is in certain places, and I'd also like to apply the same gradient style to the 'active' state of all elements with the .btn class...
If you can help solve (it need not be the way I've requested it) this, I'd greatly appreciate it...

You can't actually do a reference (one of CSS's major failings), but you can do this:
.btn:active, .red {
/* Block A: Most (or all) of what used to just be in .red below */
}
.btn:active {
/* Block B: Stuff *just* for .btn:active, if any */
}
.red {
/* Block C: Stuff *just* for .red, if any */
}
The comma means that the definitions in the body of Block A apply separately to each of those selectors, and so they apply to any ".btn" elements that are ":active", and separately apply to any ".red" elements.
Block B and Block C are optional. They're for any definitions you only want to apply to the given selector. You usually list these after Block A because rules of equal specificity are applied top-to-bottom, so you can override anything from Block A that you want to in Block B or Block C, and those blocks will "win".

For call class to another class.
.classA{
}
.classB .classA:hover{
visibility: visible;
/*classA -> onmouseover , classB -> visible*/
}
classB{
visibility: hidden;
}
Sample code show popUp onmouseover
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* Popup container - can be anything you want */
.popup {
position: relative;
display: inline-block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.popup:hover .popuptext{
visibility: visible;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s;
/*onmouseover .popup class .popuptext is visible*/
}
/* The actual popup */
.popup .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 8px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -80px;
}
/* Popup arrow */
.popup .popuptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
/* Add animation (fade in the popup) */
#-webkit-keyframes fadeIn {
from {opacity: 0;}
to {opacity: 1;}
}
#keyframes fadeIn {
from {opacity: 0;}
to {opacity:1 ;}
}
</style>
</head>
<body style="text-align:center">
<h2>Popup</h2>
<div class="popup">over me to toggle the popup!
<span class="popuptext" id="myPopup">A Simple Popup! </span>
</div>
</body>
</html>

Related

Close hamburger menu when click on anchor links on same page

I'm using this Pure CSS hamburger menu code: https://codepen.io/erikterwan/pen/EVzeRP
/*
* Made by Erik Terwan
* 24th of November 2015
* MIT License
*
*
* If you are thinking of using this in
* production code, beware of the browser
* prefixes.
*/
body
{
margin: 0;
padding: 0;
/* make it look decent enough */
background: #232323;
color: #cdcdcd;
font-family: "Avenir Next", "Avenir", sans-serif;
}
a
{
text-decoration: none;
color: #232323;
transition: color 0.3s ease;
}
a:hover
{
color: tomato;
}
#menuToggle
{
display: block;
position: relative;
top: 50px;
left: 50px;
z-index: 1;
-webkit-user-select: none;
user-select: none;
}
#menuToggle input
{
display: block;
width: 40px;
height: 32px;
position: absolute;
top: -7px;
left: -5px;
cursor: pointer;
opacity: 0; /* hide this */
z-index: 2; /* and place it over the hamburger */
-webkit-touch-callout: none;
}
/*
* Just a quick hamburger
*/
#menuToggle span
{
display: block;
width: 33px;
height: 4px;
margin-bottom: 5px;
position: relative;
background: #cdcdcd;
border-radius: 3px;
z-index: 1;
transform-origin: 4px 0px;
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
background 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
opacity 0.55s ease;
}
#menuToggle span:first-child
{
transform-origin: 0% 0%;
}
#menuToggle span:nth-last-child(2)
{
transform-origin: 0% 100%;
}
/*
* Transform all the slices of hamburger
* into a crossmark.
*/
#menuToggle input:checked ~ span
{
opacity: 1;
transform: rotate(45deg) translate(-2px, -1px);
background: #232323;
}
/*
* But let's hide the middle one.
*/
#menuToggle input:checked ~ span:nth-last-child(3)
{
opacity: 0;
transform: rotate(0deg) scale(0.2, 0.2);
}
/*
* Ohyeah and the last one should go the other direction
*/
#menuToggle input:checked ~ span:nth-last-child(2)
{
transform: rotate(-45deg) translate(0, -1px);
}
/*
* Make this absolute positioned
* at the top left of the screen
*/
#menu
{
position: absolute;
width: 300px;
margin: -100px 0 0 -50px;
padding: 50px;
padding-top: 125px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
/* to stop flickering of text in safari */
transform-origin: 0% 0%;
transform: translate(-100%, 0);
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0);
}
#menu li
{
padding: 10px 0;
font-size: 22px;
}
/*
* And let's slide it in from the left
*/
#menuToggle input:checked ~ ul
{
transform: none;
}
<!-- Made by Erik Terwan -->
<!-- 24th of November 2015 -->
<!-- MIT License -->
<nav role="navigation">
<div id="menuToggle">
<!--
A fake / hidden checkbox is used as click reciever,
so you can use the :checked selector on it.
-->
<input type="checkbox" />
<!--
Some spans to act as a hamburger.
They are acting like a real hamburger,
not that McDonalds stuff.
-->
<span></span>
<span></span>
<span></span>
<!--
Too bad the menu has to be inside of the button
but hey, it's pure CSS magic.
-->
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Info</li>
<li>Contact</li>
<li>Show me more</li>
</ul>
</div>
</nav>
The problem i'm having is that it remains open when I click on a menu item as it is a one-page site with anchor links. What would be the best method to close the menu on click of any of the menu item links? Using javascript to remove the menu onclick is not a good option because the X also needs to revert back to a hamburger and it doesn't if you use this method. Any help appreciated, thanks in advance!
It is possible to add a little JavaScript without breaking the behaviour of your closing icon.
See your modified code snippet below, when adding an eventListener on click of your menu links, just uncheck the input field corresponding to toggle the menu burger icon:
var menu = document.getElementById('menu');
var closeIcon = document.getElementById("closeIcon");
menu.addEventListener('click', handleMenuClick);
function handleMenuClick(event) {
if (event.target instanceof HTMLAnchorElement) {
closeIcon.checked = false;
}
}
/*
* Made by Erik Terwan
* 24th of November 2015
* MIT License
*
*
* If you are thinking of using this in
* production code, beware of the browser
* prefixes.
*/
body
{
margin: 0;
padding: 0;
/* make it look decent enough */
background: #232323;
color: #cdcdcd;
font-family: "Avenir Next", "Avenir", sans-serif;
}
a
{
text-decoration: none;
color: #232323;
transition: color 0.3s ease;
}
a:hover
{
color: tomato;
}
#menuToggle
{
display: block;
position: relative;
top: 50px;
left: 50px;
z-index: 1;
-webkit-user-select: none;
user-select: none;
}
#menuToggle input
{
display: block;
width: 40px;
height: 32px;
position: absolute;
top: -7px;
left: -5px;
cursor: pointer;
opacity: 0; /* hide this */
z-index: 2; /* and place it over the hamburger */
-webkit-touch-callout: none;
}
/*
* Just a quick hamburger
*/
#menuToggle span
{
display: block;
width: 33px;
height: 4px;
margin-bottom: 5px;
position: relative;
background: #cdcdcd;
border-radius: 3px;
z-index: 1;
transform-origin: 4px 0px;
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
background 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
opacity 0.55s ease;
}
#menuToggle span:first-child
{
transform-origin: 0% 0%;
}
#menuToggle span:nth-last-child(2)
{
transform-origin: 0% 100%;
}
/*
* Transform all the slices of hamburger
* into a crossmark.
*/
#menuToggle input:checked ~ span
{
opacity: 1;
transform: rotate(45deg) translate(-2px, -1px);
background: #232323;
}
/*
* But let's hide the middle one.
*/
#menuToggle input:checked ~ span:nth-last-child(3)
{
opacity: 0;
transform: rotate(0deg) scale(0.2, 0.2);
}
/*
* Ohyeah and the last one should go the other direction
*/
#menuToggle input:checked ~ span:nth-last-child(2)
{
transform: rotate(-45deg) translate(0, -1px);
}
/*
* Make this absolute positioned
* at the top left of the screen
*/
#menu
{
position: absolute;
width: 300px;
margin: -100px 0 0 -50px;
padding: 50px;
padding-top: 125px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
/* to stop flickering of text in safari */
transform-origin: 0% 0%;
transform: translate(-100%, 0);
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0);
}
#menu li
{
padding: 10px 0;
font-size: 22px;
}
#menu a {
display: block;
}
/*
* And let's slide it in from the left
*/
#menuToggle input:checked ~ ul
{
transform: none;
}
<!-- Made by Erik Terwan -->
<!-- 24th of November 2015 -->
<!-- MIT License -->
<nav role="navigation">
<div id="menuToggle">
<!--
A fake / hidden checkbox is used as click reciever,
so you can use the :checked selector on it.
-->
<input id="closeIcon" type="checkbox" />
<!--
Some spans to act as a hamburger.
They are acting like a real hamburger,
not that McDonalds stuff.
-->
<span></span>
<span></span>
<span></span>
<!--
Too bad the menu has to be inside of the button
but hey, it's pure CSS magic.
-->
<ul id="menu">
<li>
Home
</li>
<li>
Info
</li>
<li>
Contact
</li>
<li>
Show me more
</li>
</ul>
</div>
</nav>
Notice, that I also fixed the semantic of the menu list element as putting a elements into li elements and not vice versa as it was before. Plus adding display: block; to the menu a elements to provide them to be full width and be correctly clickable.
That, however should not effect the appearance of your menu.
Note
In case you are wondering if a pure CSS only solution would be possible.
In theory you would try to uncheck the burger-icons input field by clicking on a menu link. You would try that by using radio inputs with the same name, so they will toggle each other.
Unfortunately there are 2 things which speak against that:
It would blow your code on the menu links more than needed and add more non-semantic html.
With the approach of radio inputs on the menu links, you would have a hard time to toggle the menu by pressing the burger item itself, as one radio input presenting the burger would not toggle itself.
You can use Jquery to toggle the Menu:
Open: $('#menuToggle input').prop( "checked" ,true);
Close: $('#menuToggle input').prop( "checked" ,false);

How to make CSS tooltip stay up strictly while over original item, not also over newly generated tooltip?

I only want the tooltip text to remain while the user is STRICTLY hovering over the original element, but it by default also stays while no longer hovering over the original element if the user is hovering over the tooltip text body generated by the hover. So how can (if possible) I make the tooltip text disappear once the user moves the cursor to be no longer over the original element with the hover styling even though the cursor may still be hovering over the tooltip text?
Sadly, I can't even imagine what to attempt to change this behavior so my code is exactly the same (in all relevant ways) as that provided by w3schools on how to make/use a tooltip. The code is below or you can go to their link here - https://www.w3schools.com/css/tryit.asp?filename=trycss_tooltip
<style>
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
/* Position the tooltip */
position: absolute;
z-index: 1;
}
.tooltip:hover .tooltiptext {
visibility: visible;
}
</style>
<body style="text-align:center;">
<p>Move the mouse over the text below:</p>
<div class="tooltip">Hover over me
<span class="tooltiptext">Tooltip text</span>
</div>
I figured it out myself!
My solution was to take care of the visibility styling with JavaScript instead of CSS so that I could have more control of conditionally rendering the tooltiptext.
I also fancied it up a little and my solution is a bit overkill because I wanted to be able to render this feature to many elements though the example here only bothers with one :)
Here's the code!
strictHoverStyle();
function strictHoverStyle(){
let overTooltipTexts = false;
let tooltipSet = document.getElementsByClassName('tooltip');
let tooltiptextSet = document.getElementsByClassName('tooltiptext');
let tooltips = Array.from(tooltipSet);
let tooltiptexts = Array.from(tooltiptextSet);
for(let i = 0; i<tooltips.length; i++){
tooltips[i].addEventListener('mouseover', function(){
if(overTooltipTexts){
tooltiptexts[i].style.visibility = 'hidden';
tooltiptexts[i].style.opacity = 'opacity 1s';
tooltiptexts[i].style.transition = 0;
} else{
tooltiptexts[i].style.visibility = 'visible';
tooltiptexts[i].style.opacity = 1;
}
});
tooltips[i].addEventListener('mouseout', function(){
tooltiptexts[i].style.visibility = "hidden";
tooltiptexts[i].style.opacity = 0;
});
tooltiptexts[i].addEventListener('mouseover', function(){
overTooltipTexts = true;
});
tooltiptexts[i].addEventListener('mouseout', function(){
overTooltipTexts = false;
});
}
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
}
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
top: 150%;
left: 50%;
margin-left: -60px;
opacity: 0;
transition: opacity 1s;
}
.tooltip .tooltiptext::after {
content: "";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent black transparent;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Strict Hover</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<h1>
<span class="tooltip">STRICT HOVER!<span class="tooltiptext">Tooltip text</span></span>
</h1>
</body>
<script src="index.js"></script>
</html>

Ripple Effect Buttons CSS3

Here is a code from W3Schools on how to create a ripple effect button.
.button {
position: relative;
background-color: #4CAF50;
border: none;
font-size: 28px;
color: #FFFFFF;
padding: 20px;
width: 200px;
text-align: center;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
text-decoration: none;
overflow: hidden;
cursor: pointer;
}
.button:after {
content: "";
background: #f1f1f1;
display: block;
position: absolute;
padding-top: 300%;
padding-left: 50%;
margin-left: -20px !important;
margin-top: -120%;
opacity: 0;
transition: all 15s;
}
.button:active:after {
padding: 0;
margin: 0;
opacity: 1;
transition: 0s;
}
Can someone help me understand the code bit by bit, especially why the padding and margin in the button:after are so highly set and how the zero values in the button:active:after affect the animation?
Any help will be highly appreciated. (I know the basic of padding and margin, but I think that I am not getting the 'after' class and the technique used).
:after is not a class is a pseudo-element that it's used to add content to the content of an element .see here ::after
so it uses that pseudo-element to create a new space with CSS that it's not defined in your initial HTML . it's like making another element inside the button
for eg if you had a structure like this :
.no_pseudo, .with_pseudo {
width:100px;
height:100px;
background:red;
margin:40px 0
}
.likeAfter {
background:blue;
width:50%;
margin:0 auto;
height:100%;}
.with_pseudo {
position:relative;
}
.with_pseudo:after {
content:"";
position:absolute;
background:blue;
width:50%;
margin:0 auto;
height:100%;
lefT:0;
right:0;}
<div class="no_pseudo">
<div class="likeAfter">
</div>
</div>
<div class="with_pseudo">
</div>
as you can see, the :after element can be used just like a child element inside a div. but you can achieve that just by using CSS .you don't have to change the HTML structure.
so this trick is using :after , which has a background: #f1f1f1; and it's positioned under the button ( margin-top:-120% ) . and then, when you click on the button , it has (margin:0 ) that's how this effect is done
also with paddings and opacity.
i would've done it differently :
.button {
position: relative;
background-color: #4CAF50;
border: none;
font-size: 28px;
color: #FFFFFF;
padding: 20px;
width: 200px;
text-align: center;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
text-decoration: none;
overflow: hidden;
cursor: pointer;
z-index:2;
}
.button:after {
content: "pseudo element >!<";
color:green;
background: #f1f1f1;
display: block;
position: absolute;
bottom:0;
left:0;
height:0%;
width:0%;
opacity: 0;
transition: all 3s;
}
.button:focus:after {
width:50%;
height:100%;
opacity: 1;
}
<button class="button">
I AM A BUTTON
</button>
i positioned the :after at the bottom-left of the button , with width:0%;height:0%;opacity:0 ;
then, when i click on the button, i added width:50%;height:100%;opacity:1 on the :after and that's how you get that effect . maybe is not exactly the same as in your example but it works.
also added some content:"" to the :after element. you can add text,images etc. almost anything. but if you don't want to add anything, you must use content:"" and leave it empty, otherwise the :after is not created.
:before is the same as after > see here more about pseudo elements
css_pseudo_elements or here Pseudo-elements
there is much to talk about this things, but i hope you kind of understood what's going on with the pseudo-elements and with this effect. let me know. cheers !
EDIT AFTER COMMENT :
1. ' transition backwards ' is because of the :active state ( :active ) . the button has the :active state only when you click on it . after that it's not active anymore and :after goes back to it's original style
and because it has transition:15s it takes 15 sec to get back to it's original position and color.
the same with the ripple effect. you click on the button, the effects starts , :after gets from one style to another , for example from opacity:0 to opacity:1 then because the button doesn't have :active state anymore, :after returns to it's original style of opacity:0 , all this happens in 15 seconds ( because of the transition:15s )
2
content:"" inserts the space for the :after or :before into the HTML structure
you need content:"" on :after because , as i said in the beginning ,
::after is a pseudo element which allows you to insert content onto a page from CSS (without it needing to be in the HTML). While the end result is not actually in the DOM, it appears on the page as if it is
key word content . so even if you don't insert text or images but you just want to insert an empty space , you need to set up a content:"" which means empty but still there .
elem:after{content:""} generates a space with width:0;height:0 after the element.
i will make two short examples , one with something inside content:"" one with nothing inside it
h1:before {
content:"i am before < < < ";
font-size:14px;
color:red;
}
h1:after {
content:" > > > i am after";
font-size:14px;
color:blue;
}
h2:before {
content:"";
background:red;
width:20px;
height:20px;
position:absolute;
}
h2:after {
content:"";
background:blue;
width:20px;
height:20px;
position:absolute;
}
<h1>Text Before me </h1>
<h2>Just empty content </h2>

a::hover/after not for images

For some nice links on a website, I'm using the pseudo class a::hover and the pseudo-element a::after:
a {
position: relative;
display: inline-block;
outline: none;
color: #404d5b;
vertical-align: bottom;
text-decoration: none;
white-space: nowrap;
}
a::hover,
a::after {
pointer-events: none;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-font-smoothing: antialiased;
font-smoothing: antialiased;
}
Now this is applied also to images when inserted into a link-element like this:
<img src="source.jpg" />
How can I hide this styling for my images? I don't want them to have this background when hovering...
You can use the sibling trick:
.parent {
width:100px;
height:100px;
padding:50px;
}
.parent:hover {
}
.child {
height:100px;
width:100px;
background:#355E95;
transition:background-color 1s;
position: relative;
top: -200px;
}
.child:hover {
background:#000;
}
.sibling{
position: relative;
width:100px;
height:100px;
padding: 50px;
top: -50px;
left: -50px;
background:#3D6AA2;
transition:background-color 1s;
}
.sibling:hover{
background:#FFF;
transition:background-color 1s;
}
<div class="parent">
<div class="sibling"></div>
<img src="http://www.dunbartutoring.com/wp-content/themes/thesis/rotator/sample-1.jpg" class="child" />
</div>
See this answer: https://stackoverflow.com/a/17924223/586051
Links can have a broad range of specific styles:
a.mylink{border-bottom:2px solid red;}
a #mylink{border-bottom:2px solid green;}
You could try this:
a img::hover, a img::after { /* Empty */ }
You should take a look at the negation feature of CSS (take care of the Browser-Compatibility). Reference
One possible way is to make those anchor tags selectable by adding a specific class and define that this element is not touched by the a::hover.
Another way is to use the selector an the .not-Feature.
Another "dirty" way is to overwrite this behaviour by using "!important".
This example should reset these values to default (initial):
a::hover img,
a::after img {
pointer-events: initial;
-webkit-backface-visibility: initial;
backface-visibility: initial;
-webkit-font-smoothing: initial;
font-smoothing: initial;
}
If not you should be able to do so at the basic element level:
a img {
pointer-events: initial;
-webkit-backface-visibility: initial;
backface-visibility: initial;
-webkit-font-smoothing: initial;
font-smoothing: initial;
}

Tooltip CSS ONLY: focus and hover prevents access to following button

http://codepen.io/anon/pen/wBaGgW
I currently have what a list of items and then a button next to them on the right:
The tooltip must appear on focus and the tooltip must appear on hover - this works but the problem is that when an item is focused (after clicking on it) - the following item cannot be accessed via mouse (because preceeding is item focused!):
The tooltip must disappear when the mouse over the tooltip itself, but the focus is forcing it stay.
The test-case is here: http://codepen.io/anon/pen/wBaGgW
can anyone offer a solution that does not have any javascript? Also, the html markup cannot be changed too much. Minimal changes to HTML are OK. Just trying to prevent too much as I'll most likely need to compensate other parts of the application to fit the html changes.
Here shows the tooltip:
button:hover>.tooltip,
button:focus>.tooltip,
button:active>.tooltip {
visibility: visible;
opacity: 1;
}
I can hide the tooltip doing the following:
button:focus>.tooltip:hover {
visibility: hidden;
opacity: 0;
}
But that causes a crazy flickering effect as the mouse moves within the area in which the tooltip would appear.
Keep in mind the restrictions:
No JavaScript
Compatibility with IE8+ (please note, the tooltip css is coming from our global module, and I dont have direct access to change it, I am working on a separate module that I can of course override because my css loads after the global css does)
Tooltip must appear below (unfortunately)
With those restrictions, I don't know of any way to resolve your issue perfectly.
As a workaround, you can change the tooltip to be a sibling of the button, instead of a child and use the CSS adjacent sibling selector. This makes it so that when a user clicks the tooltip, it loses focus from the button and the tooltip is hidden. This will require you to fix the position of the tooltip a little (I used margin-top as a quick fix).
Code
button:hover + .tooltip,
button:focus + .tooltip,
button:active + .tooltip {
visibility: visible;
opacity: 1;
margin-top:20px;
}
<ul>
<li><span>Lorem Ipsum Dlar Set</span>
<button>X
</button>
<span class="tooltip">Hello ToolTip
</span>
</li>
...
</ul>
Live example: http://codepen.io/anon/pen/azONYP
Based my answer on this: Answer
html
<button tooltip="Tooltip text">Test</buttoN>
css
[tooltip]:before {
position : absolute;
content : attr(tooltip);
pacity : 0;
}
[tooltip]:hover:before {
opacity : 1;
margin-top:10px;
}
Here is the Fiddle
Update
Fiddle now with focus.
Added pointer event: none;
IE8 YEP YEP
No Javascript YEP
Must be below YEP
when mouse leave the tooltip, it's needs to be removed completely? (like removing the ":focus")...beacuse if it's allow for the tooltip to be visible again after mouse leave so you can use:
button:focus>.tooltip:hover
{
background: none;
border: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
text-indent: -9999px;
}
codepen: http://codepen.io/anon/pen/OPVNaW
Use <a> instead of buttons and style them as buttons.
/* `border-box`... ALL THE THINGS! */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 64px auto;
text-align: center;
font-size: 100%;
max-width: 640px;
width: 94%;
}
a:hover {
text-decoration: none;
}
header,
.demo,
.demo p {
margin: 4em 0;
text-align: center;
}
/**
* Tooltip Styles
*/
/* Add this attribute to the element that needs a tooltip */
[data-tooltip] {
position: relative;
z-index: 2;
cursor: pointer;
}
/* Hide the tooltip content by default */
[data-tooltip]:before,
[data-tooltip]:after {
visibility: hidden;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
pointer-events: none;
}
/* Position tooltip above the element */
[data-tooltip]:before {
position: absolute;
top: 150%;
left: 50%;
margin-top: 5px;
margin-left: -80px;
padding: 7px;
width: 160px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #000;
background-color: hsla(0, 0%, 20%, 0.9);
color: #fff;
content: attr(data-tooltip);
text-align: center;
font-size: 14px;
line-height: 1.2;
}
/* Triangle hack to make tooltip look like a speech bubble */
[data-tooltip]:after {
position: absolute;
top: 150%;
left: 50%;
margin-left: -5px;
width: 0;
border-bottom: 5px solid #000;
border-bottom: 5px solid hsla(0, 0%, 20%, 0.9);
border-right: 5px solid transparent;
border-left: 5px solid transparent;
content: " ";
font-size: 0;
line-height: 0;
}
/* Show tooltip content on hover */
[data-tooltip]:hover:before,
[data-tooltip]:hover:after {
visibility: visible;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
/* Show tooltip content on focus */
[data-tooltip]:focus:before,
[data-tooltip]:focus:after {
visibility: visible;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<h1>CSS Simple Tooltip</h1>
<div class="demo">
<p>I’m a button with a tooltip</p>
</div>
Try refactoring your CSS to something like this:
button:hover>.tooltip,
button:active>.tooltip {
visibility: visible;
opacity: 1;
}
button:focus>.tooltip {
visibility: visible;
opacity: 1;
outline: none;
}

Resources