Trying to make my tooltips show and hide on click. I managed to do it with the first tooltip but this doesn´t work for the others.
I know that the problem might be with the code document.getElementById but I don´t know with which code I have to replace that, so that every tooltip gets triggered one after the other when clicked.
How can I manage that all the tooltips are shown and hidden as the first one?
Thanks for your support! ;)
//Showing the tooltip on click
document.getElementById("website-tooltip-container").addEventListener("click", function() {
var element = document.getElementById("test");
element.classList.add("website-tooltiptext-visible");
});
//Removing tooltip when clicked outside tooltip container or outside tooltip itself
document.addEventListener('mouseup', function(e) {
var container = document.getElementById('test');
if (!container.contains(e.target)) {
container.classList.remove("website-tooltiptext-visible");
}
});
/* Tooltip Container */
.website-tooltip {
position: relative;
display: flex;
justify-content: center;
cursor: pointer;
font-family: Roboto;
font-size: 18px;
font-weight: 400;
color: #666;
}
/* Tooltip text */
.website-tooltip .website-tooltiptext {
visibility: hidden;
max-width: 350px;
font-family: open sans;
font-size: 13px;
line-height: 22px;
background-color: #FFFFFF;
color: #666;
text-align: left;
padding: 11px 15px 11px 15px !important;
border-radius: 3px;
box-shadow: 0px 5px 10px -2px rgba(0, 0, 0, 0.5);
/* Position the tooltip text */
position: absolute;
z-index: 1;
top: 100%;
margin: 0px 0px 0px 0px;
}
/* Show the tooltip text when you mouse over the tooltip container */
.website-tooltip:hover .website-tooltiptext {
visibility: visible;
}
/* Hide when hovering over tooltip div */
div.website-tooltiptext:hover {
display: none;
}
/* Toggle this class to show Tooltip on click via Javascript */
.website-tooltiptext-visible {
visibility: visible !important;
display: block !important;
}
<div id="website-tooltip-container" class="website-tooltip"><span class="dottedunderline">Tooltip 1</span>
<div id="test" class="website-tooltiptext">Blabalabalbalablablabla.
</div>
</div>
<div id="website-tooltip-container" class="website-tooltip"><span class="dottedunderline">Tooltip 2</span>
<div id="test" class="website-tooltiptext">Blabalabalbalablablabla.
</div>
</div>
<div id="website-tooltip-container" class="website-tooltip"><span class="dottedunderline">Tooltip 3</span>
<div id="test" class="website-tooltiptext">Blabalabalbalablablabla.
</div>
</div>
<div id="website-tooltip-container" class="website-tooltip"><span class="dottedunderline">Tooltip 4</span>
<div id="test" class="website-tooltiptext">Blabalabalbalablablabla.
</div>
</div>
Thanks for your help!
This question got answered in a similar question I made.
Here the link to the question also in stackoverflow
There you will find deeper insights and possible solutions for tooltips via JavaScript or :hover pseudo class.
Related
I wanted to put a lot of dropdowns on one page, and I could easily get them there. The problem is that when I click on the second one, it displays what's on the first, despite having different contents. Is there a solution for this?
Code because it wouldn't fit here:
https://jsfiddle.net/ne720zps/
Send the button that was clicked to myFunction. Get the appropriate dropdown from the button's relative position to that dropdown (the dropdown is the next element after the button in your code). Delete the duplicated IDs on the dropdown divs.
<button onclick="myFunction(this)">
and
function myFunction(button) {
// the dropdown is the next element after the button that was clicked
button.nextElementSibling.classList.toggle("show");
}
Here's a restructuring of that HTML, with ID tags removed and an example on how to target elements based on their proximity/relationship to the button.
// let the page load...
document.addEventListener('DOMContentLoaded', () => {
// assign the button click
document.querySelectorAll('.dropbtn').forEach(btn => {
btn.addEventListener('click', e => {
// first close all
document.querySelectorAll('.dropdown-content').forEach(div => div.classList.remove('show'))
// open the one you want which is CLOSEST
e.target.closest('.dropdown').querySelector('.dropdown-content').classList.add('show');
})
})
// catch the click outside
document.addEventListener('click', e => {
if (e.target.classList.contains('dropbtn')) return;
document.querySelectorAll('.dropdown-content').forEach(div => div.classList.remove('show'))
})
})
body {
background: black;
color: white;
}
.dropbtn {
background-color: #ffffff;
color: black;
padding: 10px;
font-size: 20px;
border: none;
cursor: pointer;
width: auto;
margin-bottom: 0;
font-weight: 600;
}
/* Dropdown button on hover & focus */
.dropbtn:hover,
.dropbtn:focus {
background: linear-gradient(90deg, #00ffa8, #2300ff);
color: white;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
display: inline-block;
text-align: center;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
text-align: left;
background-color: black;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
width: 30%;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: center;
background: white;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
display: block;
}
#center {
text-align: center;
}
<div class="center">
<div class="dropdown">
<button class="dropbtn">Embedded Browser</button>
<div class="dropdown-content">
<b><i>Unblocked browser that won’t show up in your history. Doesn’t work with a lot of websites, so you can mostly just search.
</i></b>
</div>
</div>
</div>
<div class="center">
<div class="dropdown">
<button class="dropbtn">Fullscreen Browser</button>
<div class="dropdown-content">
<b><i>Same as the last one, but takes up your whole screen.
</i></b>
</div>
</div>
</div>
I need to display tooltips for specific terms in a multiple-column div, and I need them to work across multiple browsers. I began with the w3schools CSS Tooltip example, which works great in a normal (single-column) container. But with multiple columns, Chrome has some serious (perhaps not deal-breaking) formatting issues, and Safari fails badly, cropping the tooltip to the column in which it should appear. Firefox works properly.
Firefox:
Chrome:
Safari:
I thought perhaps Safari was treating overflow as though it were set to hidden, but if so, I couldn't find any way to change its behavior. And I couldn't find any existing questions that address tooltip formatting problems in multi-column layouts.
Now I'm worried that I may have to bite the bullet and write the custom javascript to detect hover, grab the text of the tooltip, stuff the text into a div that floats above the content of my page, reveal the div properly positioned in relation to the link, and hide it again when the mouse moves off the link. Obviously, it would be a lot easier if I could make the w3schools tooltip code work with multiple columns. (Using a table or grid in place of multiple columns is not an for this project.)
Has anyone else encountered (and hopefully solved) this issue?
Here's my code; if you run the snippet you'll see that the upper div shows a normal single-column div that works fine across browsers; the lower div is the two-column div that generated the screenshots above.
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 150px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px;
border-radius: 6px;
/* Position the tooltip text */
position: absolute;
z-index: 1;
top: 160%;
left: 50%;
margin-left: -75px;
/* Use half of the width (150/2 = 75), to center the tooltip */
}
.tooltip .tooltiptext::after {
/* Add an arrow */
content: " ";
position: absolute;
bottom: 100%;
/* At the top of the tooltip */
left: 50%;
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent black transparent;
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
}
.contentDiv {
margin-left: 50px;
padding: 5px;
width: 100px;
border: 1px solid black;
}
.contentDiv p {
margin: 0;
}
.contentDiv.twoColumn {
width: 210px;
column-count: 2;
-moz-column-count: 2;
-webkit-column-count: 2;
column-rule: 1px solid black;
-moz-column-rule: 1px solid black;
-webkit-column-rule: 1px solid black;
}
<div class="contentDiv">
<p>
<span class="tooltip">Hover 1
<span class="tooltiptext">Tooltip text for Hover #1.</span>
</span>
</p>
<p>
<span class="tooltip">Hover 2
<span class="tooltiptext">Tooltip text for Hover #2.</span>
</span>
</p>
</div>
<div style="clear:both;"></div>
<br>
<div class="contentDiv twoColumn">
<p>
<span class="tooltip">Hover 3
<span class="tooltiptext">Tooltip text for Hover #3.</span>
</span>
</p>
<p>
<span class="tooltip">Hover 4
<span class="tooltiptext">Tooltip text for Hover #4.</span>
</span>
</p>
</div>
Link to JsFiddle
.tooltip .tooltiptext {
-webkit-column-break-inside: avoid;
-webkit-backface-visibility: hidden;
}
This can fix for the overflow part but i notice that the last item of the column, the tooltip will still go up instead of below it.
Feel like column overflow issue still haven't fix for chrome yet, maybe can try to use flex.
The incompatibilities among browsers have defeated my effort to find a css-only solution, so I bit the bullet, added a bit of javascript, and provide below a solution that works for me. This solution supports both text tooltips (which can include html markup) and picture tooltips.
$(function() {
var $tip;
function makeTip () {
$(document.body).append ("<div id='tooltip'></div>");
$tip = $("#tooltip");
}
$(".tipLink").hover (function () {
var st = $(this).data ("tip"),
rect = this.getBoundingClientRect(),
hasImage = st.match(/^<img/) ? true : false,
bottomPadding = hasImage ? "5px" : "10px";
if (!$tip) {
makeTip ();
}
// It'd be good to preload the image!
$tip.html (st);
// Center tooltip and arrow below link.
$tip.css ({"display":"block",
"top": window.pageYOffset + rect.bottom + 10 + "px",
"left": window.pageXOffset + rect.left + rect.width/2,
"padding-bottom": bottomPadding});
},
function () {
$tip.css ("display", "none");
});
});
#tooltip {
display: none;
background-color: #444;
font-family:"Times New Roman", Times, serif;
font-size: 1.2rem;
line-height: 1.3rem;
color: #fff;
text-align: center;
padding: 10px;
border-radius: 6px;
/* Position the tooltip text */
position: absolute;
z-index: 1;
max-width: 200px;
transform: translateX(-50%); /* translate left by half the tip width */
}
#tooltip::after { /* Add an arrow */
content: " ";
position: absolute;
bottom: 100%; /* At the top of the tooltip */
left: 50%; /* Centered horizontally */
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent #444 transparent;
}
/* The styles below are for the demo, and aren't needed in actual use. */
.contentDiv {
margin-left: 100px;
padding: 5px;
width: 150px;
border: 1px solid black;
}
.contentDiv p {
margin: 0;
}
.contentDiv.twoColumn {
width: 300px;
column-count:2;
-moz-column-count: 2;
-webkit-column-count: 2;
column-rule: 1px solid black;
-moz-column-rule: 1px solid black;
-webkit-column-rule: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class = "contentDiv">
<p>
Item 1: <span class="tipLink" data-tip="Tooltip text for Hover #1.">Hover 1</span>
</p>
<p>
Item 2: <span class="tipLink" data-tip="Tooltip text for Hover #2.">Hover 2</span>
</p>
</div>
<div style="clear:both;"></div>
<br>
<div class = "contentDiv twoColumn">
<p>
Item 3: <span class="tipLink" data-tip="Tooltip text for Hover #3.">Hover 3</span>
</p>
<p>
Item 4: <span class="tipLink" data-tip="<img src='https://upload.wikimedia.org/wikipedia/commons/thumb/archive/b/b3/20091118075632%21UN_flag.png/120px-UN_flag.png'>">Hover 4</span>
</p>
</div>
This solution (using jQuery) shows the tooltip text when you mouse over a tipLink element, such as this span:
<span class="tipLink" data-tip="Tooltip text">Link</span>
In this example, "Link" is the text on the page, and the contents of the data-tip are displayed as the tooltip when the user hovers over the word "Link".
Alternatively you can use the data-tip to specify an img element that will appear as the tip.
This code centers the tooltip below the tipLink element, and the tooltips appear properly in multi-column layouts on at least FireFox, Safari, and Chrome.
I hope others who want to make tooltips available in multi-column page elements may find this useful.
I have a textarea for comments and a button to show or hide it (toggle). If I want to hide it by default (display: none) when I click the button to show it, the style is broken but if it's not hidden (display: block) I can click without problems, the style will be fine.
html:
<a id="1" class="comment_button a_button" title="Dejar un comentario">Comentar</a>
<div id="hide_1" class="rows" style="display: none;">
<ul id="UL_101">
<!-- New comment row -->
<li class="newComment_row">
<div class="userComments_photo">
<img class="photo" src="/images/profile/' . $_SESSION['photo'] .'" alt="" />
</div>
<textarea id="' . $imgID . '" class="textarea" rows="1" placeholder="Escribe un comentario..." title="Escribe un comentario..."></textarea>
</li>
</ul>
</div>
css:
.rows {
height: auto;
width: 494px;
background: rgb(246, 247, 248) none repeat scroll 0% 0% / auto padding-box border-box;
border-radius: 0 0 3px 3px;
margin: 8px -12px -12px;
}
#UL_101 {
width: 494px;
list-style: none outside none;
margin: 0px;
padding: 0px;
border-top: 1px solid rgb(225, 226, 227);
}
/* li */
.newComment_row {
height: auto;
position: relative;
width: 470px;
background: rgb(246, 247, 248) none repeat scroll 0% 0% / auto padding-box border-box;
border-radius: 0 0 2px 2px;
list-style: none outside none;
margin: 0px 12px;
padding: 4px 0px 8px 0px;
}
.textarea {
resize: none;
width: 416px;
font: normal normal normal 12px/15.3599996566772px Helvetica, Arial, 'lucida grande', tahoma, verdana, arial, sans-serif;
position: initial;
padding: 8px 3px 0 3px;
margin: 0 7px;
overflow: hidden;
}
and jquery:
// show rows
$('.comment_button').on('click', function () {
$('#hide_' + this.id).slideToggle('fast');
});
function h(e) {
$(e).css({
'height': 'auto',
'overflow-y': 'hidden'
}).height(e.scrollHeight);
}
$('textarea').each(function () {
h(this);
}).on('input', function () {
h(this);
});
display: none breaks the style: http://jsfiddle.net/cb41hmpo/
display: block does not break it: http://jsfiddle.net/cb41hmpo/1/
It seems the problem is the auto-height function... Is there a way to fix this?
I'd like to keep that textarea size if possible, whatever the changes are.
It's not a big deal but if display is set to block and I click the button, the textarea placeholder text appears some fuzzy or blurred for a second, is that a normal thing or can it be fixed?
If we go through your code
function h(e) {
alert(e.scrollHeight);
$(e).css({
'height': 'auto',
'overflow-y': 'hidden'
}).**height(e.scrollHeight)**;
}
If you look at the bold section here you are assigning the scrollHeight to $e. If we do an alert we can see that the height of textarea when the parent div is hidden is 0 and it is 23 when the div is shown it is 23 px. Now in the (star marked -->height(e.scrollHeight) text we are assigning explicitly that height to the textarea (bold text). Hence, it is smaller in size. Hence your height auto is not coming into picture as you are assigning height by e.scrollHeight.
Try removing the bold text from both the snippets. The result you will get will be the same.
Hope this be of some help.
Happy Learning :)
I've got an element with overflow: hidden, which I'd like to expand when clicked.
This is what I have so far.
http://jsfiddle.net/up6bW/2/
It does expand the element, but not as it's supposed to. It should not push the element below it, but overlap and hide it. I can make this work partially by using position: absolute, but this makes the next element collapse to the top.
Can this be done by only using CSS on the clicked element? Other elements should not be adjusted.
Or if they are, this should be calculated automatically using JavaScript.
Another solution could also involve wrapping the div in a container like so:
HTML:
<div class="container">
<div class="a" onclick="z(this)">
click here click here click here click here click here
</div>
</div>
<div>1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
CSS:
body { margin: 10px; }
div { font-family: sans-serif; font-size: 16px; line-height: 20px; margin-bottom: 10px; width: 150px; word-break: break-all; }
div.a { color: tomato; cursor: pointer; height: 20px; overflow: hidden; }
.container { height: 20px; overflow: visible; }
JS:
function z (a) {
a.style.cssText = a.style.border ? "" : "\
background: #fff;\
border: 1px solid #ccc;\
height: auto;\
margin-left: -5px;\
margin-top: -5px;\
padding: 4px;\
position: absolute;\
";
};
DEMO HERE
Obviously adding HTML elements for presentational reasons is less than ideal, but I think it's better than a JavaScript alternative.
Tested in IE7+, Chrome, and Firefox
Here's an example of what you might need:
http://jsfiddle.net/up6bW/39/
All I did was make the position:absolute on your dropdown Div and then gave the first of the other divs a padding on top to compensate for the loss of space from the absolute positioning:
First you can change your second div a bit to add a class:
<div class="a" onclick="z(this)">click here click here click here click here click here</div>
<div class="second">1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
Then change the CSS to something like this:
body {
margin: 10px;
}
div {
width: 150px;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
margin-bottom: 10px;
word-break: break-all;
}
div.a {
cursor: pointer;
color: tomato;
height: 20px;
overflow: hidden;
position:absolute;
}
.second{
padding:25px 0px 0px 0px;
}
The div you want to expand will have absolute positioning then the second div will have enough padding to make up for that first div.
Placing elements on top of each other requires absolute positioning. You can put some padding-top on the first element to compensate for the positioning of the overlap.
I'm using this solution, which automatically adds padding to the next element.
http://jsfiddle.net/up6bW/47/
HTML
<div class="a" onclick="z(this)">click here click here click here</div>
<div>1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
<div class="a" onclick="z(this)">click here click here click here</div>
<div>1234567890</div>
<div>1234567890</div>
<div>1234567890</div>
<div class="a" onclick="z(this)">click here click here click here</div>
CSS
div {
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
width: 150px;
word-break: break-all;
}
div.a {
color: tomato;
cursor: pointer;
height: 20px;
overflow: hidden;
}
JavaScript
function z (a) {
// nextElementSibling equivalent
var b = a.nextSibling;
while (b && b.nodeType != 1)
b = b.nextSibling;
if (b)
b.style.cssText = b.style.paddingTop ? "" : "padding-top: " + a.clientHeight + "px";
a.style.cssText = a.style.border ? "" : "\
background: #fff;\
border: 1px solid #ccc;\
height: auto;\
margin-left: -5px;\
margin-top: -5px;\
padding: 4px;\
position: absolute;\
";
};
I am using the following sliding div script:
http://www.webdesignerwall.com/demo/jquery/simple-slide-panel.html
Currently, the slidetoggle function is activated when the .btn-slide button is clicked. This slides up the "panel" div.
Upon clicking the .btn-slide button a second time, the panel div is closed.
I am a complete newb at js, so any assistance would be appreciated. Here's what I am trying to do:
1) When the mouse moves over (as opposed to clicking) the .btn-slide class, i would like the panel to slide out.
2) Then, when the mouse moves out of either the .btn-slide or #panel, i would like the panel to close. (but if the mouse is over either one, the panel should stay open).
I was able to get it working to where the slidetoggle function would close either one, or the other, but not both.
Thank you in advance for the help.
Sincerely,
Mac
Here is the JS:
<script type="text/javascript">
jQuery(function($){
$(document).ready(function(){
$('.btn-slide').click(function() {
$("#panel").slideToggle("slow");
$(this).toggleClass("active"); return false;
});
});
});
</script>
here is the HTML currently being used:
<div id="prod_nav_tab">
<div id="panel">
This is where stuff goes!
</div>
<p class="slide"><a class="btn-slide">Table of Contents</a></p>
</div>
I have played with the CSS to fit my particular web site and is as follows (the original js, html, css can be obtained from the link above).
div#prod_nav_tab {
width: 200px;
height: 31px;
overflow: hidden;
background-color:#F00;
float: left;
margin: 0px 0px 0px 75px;
}
a:focus {
outline: none;
}
#panel {
background-color:#F00;
width: 200px;
height: 200px;
display: none;
position: absolute;
bottom: 0px;
}
.slide {
margin: 0;
padding: 0;
/* border-top: solid 4px #422410; **Adds a line at top of slide button to distibuish it */
background: url(images/btn-slide.gif) no-repeat center top;
}
.btn-slide {
background: #d8d8d8;
text-align: center;
width: 200px;
height: 31px;
padding: 0px 0px 0 0;
margin: 0 0 0 0;
display: block;
font: bold 12pt Arial, Helvetica, sans-serif;
color: #666;
text-decoration: none;
position: relative;
cursor: pointer;
/* background: url(images/white-arrow.gif) no-repeat right -50px; ** Controls Arrow up/down */
}
.active {
background-position: right 12px;
}
When you move away from the .btn-slide to the #panel it hides it now because it triggers the mouseleave event of the .btn-slide.
To prevent this you should do something like:
HTML:
<div id="trigger">
Slide down
<div id="panel">
Content of your panel
</div>
</div>
JQuery:
jQuery(function($) {
$(document).ready(function() {
$("#trigger").mouseenter(function() {
$("#panel").slideDown("slow");
$(this).addClass("active");
}).mouseleave(function() {
$("#panel").slideUp("slow");
$(this).removeClass("active");
});
});
});
Make sure in your CSS you then set the panel to be hidden from start...
div#panel {
display: none;
}