Using CSS Tooltips in a Multiple-Column DIV - javascript

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.

Related

How to get different hover-over values of each item in a drop down?

Say we are using angular2-multiselect-drop down. What would be the proper way to get different hover over values for different items in the drop down?
In normal html, you have direct access to each element of the drop down list if you are hardcoding it, and you can set the style css for each item.
But how could I do this in an angular drop down?
You can achieve this using following code,
Your CSS will look like below,
/* Tooltip container */
.tooltip {
border: 2px solid #f5f5f5;
margin-left: 10%;
padding:20px;
max-height: 10%;
width: 300px;
position: relative;
display: block;
border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px 0;
border-radius: 6px;
/* Position the tooltip text - see examples below! */
position: absolute;
z-index: 1;
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
}
your HTML be like below,
<h1>See the numbers in tooltip when they change</h1>
<div *ngFor="let i of ['a','b','c','d','e','f']; let j = index;" class="tooltip">
<span>{{i}}</span>
<span class="tooltiptext">new tooltip text every time {{j}}</span>
</div>

Tooltips show / hide on click with JavaScript / CSS

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.

Label background-color based on input state

i’m working on a tab, trying to highlight the label of the actived content-section. I want to change label's background-color to distinguish the selected tab, is it possible to do that only with css? If not, how can i do that with javascript?
I try with css following this ticket (Style a <label> based on its <input>'s state), javascript to assign active state to an element without success.
/* Tabs Name Container */
.TabsHeader-container{
position: relative;
width: 120px;
float: left;
z-index: 20;
}
/* Tabs Names Label */
.TabsHeader-container label{
position: relative;
padding: 10px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
display: block;
font-size: 13px;
color: black;
cursor: pointer;
user-select: none;
}
.TabsHeader-container1 {
background-color:#f8ab1f;
width:50px;
height:50px;
border-radius:50px;
}
.TabsHeader-container2 {
background-color:#f8ab1f;
margin-top:20px;
width:50px;
height:50px;
border-radius:6px;
}
/* Hover effect on tabs names */
.TabsHeader-container label:hover{
background: rgba(0, 0, 0, 0.2);
}
/* Content area for tabs */
.TabsHeader-content{
position: relative;
background: white;
border-radius:10px;
width: calc(100% - 120px);
padding: 15px;
float: left;
box-sizing: border-box;
z-index: 19;
display: none;
}
.TabsHeader-content:after{
content: "";
clear: both;
}
/* Hide input radio from users */
input[name="TabsHeader"]{
display: none;
}
/* Show tab when input checked */
input[name="TabsHeader"]:checked + .TabsHeader-content{
display: block;
animation: slide 0.5s forwards;
}
/* Slide animation for tab contents */
#keyframes slide{
from{
left: -10%;
opacity: 0;
}
to{
left: 0;
opacity: 1;
}
}
<section class="TabsHeader-container">
<label class="TabsHeader-container1" for="TabsHeader1"></label>
<label class="TabsHeader-container2" for="TabsHeader2"></label>
</section>
<input name="TabsHeader" id="TabsHeader1" type="radio" checked />
<section class="TabsHeader-content">
<p class="text1" style="font-size:19px;">Your content goes here. Edit or remove this text inline or in the module Content settings. You can also style every aspect of this content in the module Design settings and even apply custom CSS to this text in the module Advanced settings.</p>
<!-- Any other content -->
</section>
<input class="text2" name="TabsHeader" id="TabsHeader2" type="radio" checked />
<section class="TabsHeader-content">
<p style="font-size:19px;"> Your content goes here. Edit or remove this text inline or in the module Content settings. You can also style every aspect of this content in the module Design settings and even apply custom CSS to this text in the module Advanced settings.</p>
</section>
Thanks a lot.
Could just use a bit of jquery? something like:
$(document).ready(function(){
$('.TabsHeader-container1').click(function(){
$(this).addClass("active");
$('.TabsHeader-container2').removeClass("active");
});
$('.TabsHeader-container2').click(function(){
$(this).addClass("active");
$('.TabsHeader-container1').removeClass("active");
});
});
Then just add .active{} to your stylesheet with your desired background colour and all should be good.

CSS - displaying a dynamic height floated DIV - missing background image

My Goal:
Here is what I'm trying to accomplish. We have an list of categories that appear on a page. The number of categories is unknown. The description can be pretty much any size... yet we want a uniform look. So, we are using the dotdotdot plugin to put ellipses on the paragraphs. When you hover over the item, it should expand the description and show the full text.
I want that hover to float or overlay whatever is below it. Due to some of my layout items (see my NOTE below) my sccontainer element doesn't have a set height. It's dynamic based on the content... with a max-height set.
When I change that height to AUTO in the hover event (which causes the text to flow down and displays all the content), I lose the background on the sccontainer element.
Some pertinent CSS:
.sccontainer { width: 280px; zoom: 1; float: left; margin: 5px 10px; padding: 0; border: 1px solid #8697a1; -moz-border-radius: 5px; border-radius: 5px; -moz-box-shadow: 0 0 6px #777; -webkit-box-shadow: 0 0 6px #777; box-shadow: 0 0 6px #777; -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777')"; filter: progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777'); position: relative; background: #fff url(http://imagecss.com/images/background.jpg) repeat-x left top; }
.sccontainer .parent { position: absolute; width: 270px; }
.sccontainer .image { margin: 5px; float: left; }
.sccontainer .image img { width: 48px; }
.sccontainer .icon { margin: 0; }
.sccontainer p { margin: 8px; padding: 0; max-height: 145px; }
.sccontainer h1 { line-height: 24px; display: inline-block; vertical-align: middle; width: 200px; height: 48px; padding: 0; margin: 5px 0 0 0; overflow: hidden; }
.sccontainer h1 a { padding: 0; font-size: 24px; color: #fff; font-weight: normal; }
.sccontainer .content { position: relative; height: 210px; padding: 0 5px; font-size: 15px; line-height: 22px; width: 270px; }
.sccontainer a:hover { text-decoration: underline; }
.sccontainer.hover { height: 250px; }
.sccontainer.hover .content { height: auto; }
.sccontainer.hover .content p { min-height: 135px; max-height: none; }
jsFiddle:
Here is a jsFiddle version of what I have right now. You can see this in action, if you hover over the text in the blue box. It's a bit large, so I used jsFiddle instead of putting all the bits here code tags...
http://jsfiddle.net/ztMM5/1/
And here is a mockup of what I'd like to see. Method 5a expands slightly to show the full content.... yets overlaps the red line. None of the other items move around or are affected.
NOTE: Sorry for the size of things. I've trimmed it down about as much as I can. Also, I am modifying an existing intranet website... it's 3rd party, so I have limited control of the source code - hence the table usage. :(
What I've Tried/Researched:
I believe the issue stems from the fact that my sccontainer item is floating, and doesn't have a height specified. That's why the image disappears.
I had a version that kept the background... but the sccontainer box didn't resize like we need... the text just overflowed it... rather ugly.
I don't know enough CSS to make this all work right. I'm not adverse to using jQuery to do more if needed.
I did work on a version that handled most of the hover using the :hover stuff... but it didn't work quite as well as the jQuery approach.
This answer may not solve your specific problem but it may help others with a similar scenario (working with tables makes difficult to render a clean layout in most cases.)
I ran into this issue before and this is how I solved it. It basically relies in an html nested div structure to achieve the expandability of the content without affecting the floating layout of the near elements :
<div id="wrapper" class="cf"><!--wrapper with border and CLEARED-->
<div class="sccontainer"><!--position relative-->
<div class="inner"><!--position absolute-->
<div class="content"><!--position relative-->
<!-- my content here -->
</div>
</div>
</div>
<!-- more containers etc-->
</div><!--END wrapper-->
First, we are going to apply the infamous clear-fix hack to the #wrapper container (use your preferred method):
.cf:after {
visibility:hidden;
display:block;
content:"";
clear:both;
height:0
}
* html .cf {
zoom:1
}
/* IE6 */
*:first-child+html .cf {
zoom:1
}
Then the style for the .sccontainer container :
.sccontainer {
width: 280px; /* or whatever - could be % for responsiveness */
padding-bottom:200px; /* any value to give height without using height ;) */
position: relative;
float: left;
margin: 5px 10px; /* or whatever */
overflow: hidden; /* this is important to keep all same height and big content out of sight */
z-index: 1; /* this is important too, see later */
background: white url("imagebackground.jpg") 0 0 repeat-x; /* need to explain? */
}
Then the .inner container, which actually will help to keep the layout in order if we hover the elements
.inner {
position: absolute; /* please don't move */
width: 100%; /* to fill the whole parent container */
height: 100%; /* same */
}
And the content :
.content {
position: relative;
background: white url("imagebackground.jpg") 0 0 repeat-x; /* not redundant though */
width: 100%; /* helps to fill the gaps with small content */
height: 100%; /* same, specially if using image backgrounds */
/* other styles, etc */
}
NOTE: we should apply same border-radius properties to the three containers and box-shadow to .sccontainer and .content for consistency
Now, what happens when we hover ?
.sccontainer:hover {
overflow: visible; /* show the full content */
z-index: 999; /* place me on top of the others if needed (which lower z-index, remember?) */
}
.sccontainer:hover .content {
height: auto; /* as it really is, including background image */
}
NOTES : this effect will happen regardless if the content's height is smaller than the parent container's height. You may not like the effect mostly if you are using borders and shadows (could be shown as smaller box inside the parent container) so we could add an extra class to .sccontainer like
<div class="sccontainer withhover">
and apply the hover effects only if that class exist like
.sccontainer.withhover:hover {
overflow: visible;
z-index: 999;
}
... and use a bit of jQuery to remove that class for shorter content, so it won't be affected :
jQuery(document).ready(function ($) {
$(".sccontainer").hover(function () {
var $contentHeight = $(this).find(".content").height();
if ($(this).innerHeight() > $contentHeight) {
$(this).removeClass("withhover");
}
});
});
See JSFIDDLE

Upside down tab like tabzilla from the Mozilla.com website

Mozilla.com has this tab on the top of their site that you can click and a menu drops down. I have a client who wants me to do the same thing but upside down, from the bottom half of the page. Apparently this is a really hard request. How do I make something like tabzilla that goes up and either overlaps or pushes the content away? Thanks!
Update: I love you guys.
Edit: http://hemakessites.com/mayukh/4/ Why does the top "Sign In/Register" pop down and the "Toggle" on the bottom pops up? I'm not seeing the difference besides 'top' and 'bottom' in the css. How does that change the direction of the popup?
Also, clicking the '337-9147' will expand the menu. I only want the button region to be clickable. How can I accomplish this?
You guys are awesome and I'm going to return the favor by answering some questions on here when I get time.
I took a similar approach as others, in that you set a div to have a fixed, or absolute position at the bottom of the screen (depending on whether the tab should always be visible, or only at the very bottom). Then, you can write some very simple javascript to vary the height of the element, and as the bottom is fixed, it will cause the tab to rise into the screen.
Essentially all you need is
.container{
position: absolute;
bottom: -1px;
}
And
$('.container').toggle(function(){
$(this).animate({height:'205px'}, 500)
},function(){
$(this).animate({height:'20px'}, 200)
});
Here's a jsfiddle demo.
Here's a jQuery solution, which is smoother than css3:
So, you'll want to do something like this jsfiddle (NOTE: This requires jQuery):
http://jsfiddle.net/cFkn2/
$(document).ready(function() {
$('#tab').click(function() {
if ($('#tab').css('height') == '20px') {
$('#tab').animate({
height: '100px'
}, 1000);
}
else {
$('#tab').animate({
height: '20px'
}, 1000);
};
});
});
and
#tab{
position: absolute;
bottom: 0;
width: 100%;
background-color: red;
height:20px;
}
and
<div id="tab">CONTENT</div>
Style, edit, and add easing to taste.
I was lazy to make here click handler, so it is css3 only hover sample
I used fixed position with {top: 100%}, transition for animation, margin <0 to show;
HTML
<div id="menu">
<div id="handler">handler</div>
<div id="menucontent">
menu menu<br>
menu menu<br>
</div>
</div>
<div id="content">
<div> text text text</div>
<div> text text text</div>
<!-- many of them -->
<div> text text text</div>
<div> text text text</div>
<div> text text text</div>
</div>
CSS:
#content > div {
font-size: 2em;
height: 2.1em;
border: 1px solid black;
margin-top: 10px;
}
#menu {
left: 30px;
position: fixed;
font-size: 20px;
width: 300px;
height: 300px;
top: 100%;
border: 1px solid red;
background: white;
-webkit-transition: all 1s;
-mozilla-transition: all 1s;
-o-transition: all 1s;
transition: all 1s;
}
#menu #handler {
position: absolute;
top: -40px;
background: green;
font-size: 30px;
height: 40px;
padding-left: 5px;
padding-right: 5px;
left: 10px;
}
#menu:hover {
margin-top: -300px;
}
with click, or
JS:
$(function() {
$('#menu #handler').click(function() {
$('#menu').toggleClass('shown');
});
});
in css change hover to class shown
#menu.shown {
margin-top: -300px;
}

Categories

Resources