How to make a tooltip without needing any child elements - javascript

I've been trying to make a tooltip that activates upon hovering an <a> tag and displays a <div> from another place
Example:
<p>
blah blah <a class="tooltiphover">hover me</a> blah blah
</p>
<div class="tooltip">
<!-- tooltip info code goes here -->
</div>
But every tutorial and site I've stumbled upon has been adamant on using child elements and biggest problem with that is it makes the code look bad or forces me to use a <div> tag which then screws up the look of the site
Example:
<div class="tooltiphover">Hover me</div>
<span class="tooltip">Tooltip stuff</span>
</div>
Especially when it comes to their css with .tooltiphover:hover .tooltip.
Also if there is any way to call for both elements in css to be modified when one is hovered, without being a child element, that would be great as well because adding a comma doesn't seem to do the trick and neither does adding a plus
Thanks.
EDIT: Actually, to make it simpler, how would I make the div appear in front of everything and appear next to the <a> tag like a proper tooltip because I might just use JS to deal with the mouseover event. To be honest, not sure why I went through the effort of trying to use CSS and HTML for this when it is a lot easier with JS, but I think it was probably due to all the tooltip tutorials I searched up confused me too much 😅
What would be the CSS code for that?

There are multiple ways to accomplish this, and note that none specifically require a <div> tag. CSS has many different types of selectors with different rules for how each behave. Generally speaking, CSS cascades and interacts forwards, meaning it can be difficult to interact with elements prior in your document (i.e. a child telling its parent how to behave is rare.)
The most common type of selector for this is either the element element selector or the element > element selector. They require the affected/target element be a child of the parent element.
They look something like this.
div:hover > h2{
display:block;
}
h2{
display:none;
}
<div>hover me
<h2>i am revealed</h2>
</div>
<p>don't hover me</p>
However, as you said, this requires a highly coupled relationship between the element you are selecting for and its parent. This is where the element ~ element selector comes into play.
div:hover ~ h2{
display:block;
}
h2{
display:none;
}
<div>hover me</div>
<p>don't hover me</p>
<h2>i am revealed</h2>
Where element > element requires a vertical relationship between your parent and child, element ~ element requires a horizontal sibling relationship. In the example given, all elements matching your selection would be revealed so long as they are siblings within the same context.
But what would happen if your desired target was a child of a sibling, rather than the sibling itself?
div:hover ~ h2{
display:block;
}
h2{
display:none;
}
<div>hover me</div>
<p>don't hover me</p>
<article>
<h2>i am revealed</h2>
</article>
Oh no! It doesn't work now, because they are no longer siblings within the same context. There are many ways to solve this issue, both general and specific, but one simple way is as follows:
div:hover ~ * h2{
display:block;
}
h2{
display:none;
}
<div>hover me</div>
<p>don't hover me</p>
<article>
<h2>i am revealed</h2>
<article>
By combining the element ~ element selector with the * element selector, we can interact with any h2 that is a child of any sibling of our original selector with the :hover pseudo-class.
If I am understanding the second part of your question correctly, and you want both the hover element AND its target to change in some way when the hover event takes place, it's as simple as separately declaring the styles.
div:hover ~ * h2{
display:block;
}
div:hover{
color: red;
}
h2{
display:none;
}
<div>hover me and i turn red</div>
<p>don't hover me</p>
<article>
<h2>i am revealed and not red</h2>
<article>

Related

How can I select text in an element that isn't inside another element? [duplicate]

I have the following HTML markup:
<h1>
<div class="sponsor">
<span>Hello</span>
</div>
World
</h1>
When I use the CSS selector h1 I get Hello World.
I can't unfortunately change the markup and I have to use only CSS selectors because I work with the system that aggregates RSS feeds.
Is there any CSS selector which I can take only the text node? Specifically the World in this example?
The current state of CSS can't do this, check this link: W3C
The problem here is that the content you write to the screen doesn't show up in the DOM :P.
Also ::outside doesn't seem to work yet (at least for me in Safari 6.0.3) or it simply doesn't generate the desired result yet.
Check my fiddle and then check the DOM source: JSfiddle
Finally there are attribute selectors a { content: attr(href);}, making CSS able to read DOM-node attributes. There doesn't seem to be a innerHTML equivalent of this yet. It would be great tho if that was possible, whereas you might be able to manipulate the inner markup of a tag.
Bit of a workaround:
h1 {
color: red;
}
h1 * {
color: lime;
}
<h1>
<div class="sponsor">
<span>Hello</span>
</div>
World
</h1>
This is almost the opposite of a question I asked last week: Is it possible to select the very first element within a container that's otherwise pure text without using classes or identifiers in pure CSS?
The short answer is no. "World" in this example isn't an element of its own - therefore there isn't a way to select it.
What you would have to do here is style the h1 then override that styling with div.sponsor. For instance, if you wanted "World" here to have a black background with white text you woud use something similar to:
h1 {
background:black;
color:white;
}
h1 div.sponsor {
background:white;
color:black;
}
Unfortunately, however, this wouldn't work if you were only wanting the word "World" styled and your markup had more than just that within <div>Hello</div> World Foo, for instance.
I don't believe it would be possible with pure CSS to style just "World" in this situation.
I also met same problem, where I can't touch the markup and have no control with js.
I needed to hide a text nodes in a div element, but the element to remain visible.
So here is my solution:
markup:
<div id="settings_signout_and_help">
<a id="ctl00_btnHelpDocs" class="ico icoHelp" href="http://" Help Guide</a>
Signed in as: <a id="ctl00_lUsr" href="Profile.aspx">some</a>
Home
Sign out
</div>
css:
#settings_signout_and_help {
font-size: 1px !important;
}
#settings_signout_and_help a {
font-size: 13px !important;
}
Hope this helps guys!
I had a similar problem where I had to remove the "World" text from html generated by a C# function.
I set the font-size to 0 on the 'h1' element and then applied my css to div class. Basically hiding the extra text, but keeping content in the div.
I don't know how to do it with just CSS, but...
Using JQuery, you could select all the elements inside except the stuff inside its child element
$("h1:not(h1 > div)").css()
and put whatever CSS effect you want inside there.

select elements with css :hover declaration

I did not find any answer in the web, so may be somebody could help me.
For example if we have next CSS declaration:
.hot_imgs li .detail{position:absolute;left:0;top:0;display:none;width:190px;height:190px;padding:0 40px;color:#fff;font-size:16px;font-family:"Microsoft YaHei","\5fae\8f6f\96c5\9ed1","\5b8b\4f53"}
.hot_imgs li .detail h3{margin-top:75px}
.hot_imgs li a:hover .img_bg,.hot_imgs li a:hover .detail{display:block}
And given elements:
<div class="hot_imgs">
<li id="711F">
<a href="#">
<img src="www.fishki.com" alt="Young" width="270" height="190">
<span class="img_bg"></span>
<div class="detail">
<h3>Young</h3>
</div>
</a>
</li>
<div>
As we can see from CSS declaration, when link of the list inside div with class hot_imgs is hovering, the div will be overlaid by another div with details class.
I'd like to use jQuery to identify which elements can potentially have a ":hover" attribute triggered on roll over without any mouse interaction.
Thanks a lot
You cannot target pseudo elements themselves, so if you are going to use jquery for this it has something for hover built in. You need to know what items you want to check for hovering, so for example if you wanted to check the image you could do.
$(".hot_imgs img").hover(function(){
//your logic here
});
Just a side note - All elements can have ':hover', so you will need to target with jquery. So there is nothing to check which elements 'can potentially' have :hover, as it is a pseudo selector/class.
Here is a fiddle for this example - http://jsfiddle.net/W4Km8/5413/

How to make one element get hovered when hover on other element

I need such a scenario at where if anyone hover on a div, another div will be hovered. Just like:
HTML
<div class="box"></div>
<div class="link-box">
Touch the Grey Box and I get hovered!
</div>
CSS:
.link-box a:hover {
color: red;
}
Foddle Work
If anyone hover on the div.box, div.link-box will get hovered I mean get the red color. Is it possible? Please, don't tell it like this CSS way:
.box:hover .link-box a {
color: red;
}
My scenario is not like this. I've more complex scenario. So, it's only possible with jQuery. As I ain't good at jQuery, I can't write the script. That's why I need your help. What's the jQuery for it? May be, something like this?
$('.box').hover(function(){
$('.link-box').hover();
});
..............................................Update..................................
All the answer is related with CSS. Basically, div.link-box is such a complex div at my webpage that if anyone hover on the div.link-box many action happened, like pop-up box coming, multiple child elements of div.link-boxwill change. All happened with jQuery + CSS. And I need all the hover action of div.link-box when anyone hover on div.box. I just make here div.link-box as a link to make you understand my problem. But, basically it's not just css change. So, is it possible to bring all div.link-box hover action by hover on another div/button/link just like div.box by jQuery ?
As long as they stay in the same layout you can use the adjacent selector (+) in css.
Updated Fiddle
.link-box a:hover, .box:hover + .link-box a{
color: red;
}
The important thing to remember about the adject selector is that the two divs have to have the same parent, and the box has to immediately precede the second div.
More information on the adjacent selector
Edit:
Another option would be to wrap both divs in another div, and use the hover of the wrapper div.
This second option doesn't have the drawbacks of using the adjacent selector. As long as the anchor is anywhere inside of the wrapper, it will be styled when any part of the wrapper is hovered.
FIDDLE
Like so:
<div class='box-wrapper'>
<div class="box"></div>
<div class="link-box"> Touch the Grey Box and I get hovered!
</div>
</div>
with the following style:
.box-wrapper:hover a {
color: red;
}
Create a CSS class called "hover" (to affect you a make it .hover a)
.hover a
{
color: red;
}
Then your JQuery would read:
$('.box').hover(function(){
$(".link-box").toggleClass("hover");
});
Instead of the :hover css selector, I would use classes.
CSS:
.hover{
color:red;
}
JS:
$('.box').hover(
function(){
$('.link-box').addClass('.hover');
},
function(){
$('.link-box').removeClass('hover');
}
);

How to limit a JQuery effect to one Element within a nested block

I have an H1 tag that contains text and an image. The tag looks something like this:
<h1 id="title">My Title
<img class="image" src="/icons/image.png">
</h1>
I have some CSS:
#title{
position:absolute;
font-family:"Papyrus";
color:purple;
font-size:80px;
left: 42%;
margin-top:-.1%;
}
.image{
position:absolute;
margin-left:-120px;
margin-top:35px;
}
I have nested these two so that the image stays with the h1 tag as the screen is re-sized.
What I would like to do is have two different JQuery effects run simultaneously; however, the ".image" portion is getting caught up in the effect of the "#title". The Jquery looks like this:
$("#title").hover(function(){
$("#title").effect("puff","slow",function(){
$("#title").fadeIn()});
$(".image").effect("bounce","slow");
});
What appears to happen is that the image class gets pulled into the puff effect which I don't want. It then does the bounce effect but it does it far away from its normal spot. I think it does this perhaps based on the the extended puff location but I am not sure. Regardless, I want the puff effect to only act on the #title and not the .image portion.
Thanks.
You could move the image outside of the heading and into a div. You might need to apply some additional styling, but this is probably your best option.
<div>
<h1 id="title">My Title</h1>
<img class="image" src="/icons/image.png">
</div>
Do not nest them. Instead use absolute positioning to make them appear to be overlapped.

Performance of adding CSS class & number of children

I need to dynamically apply some styling to elements .child-1 and .child-2 by adding CSS classes.
Should I add them once to #parent or to each .child-? If I add it to #parent would existence of #large-container affect the performance?
<div id="parent">
<div class="child-1"></div>
<div class="child-2"></div>
<div id="large-container">
<!-- a bunch of content here - p tags, images... -->
</div>
</div>
(.child-1 and .child-2 are absolute positioned elements on top of #large-container)
$('#parent').addClass('myClass1 myClass2');
vs
$('.child-1, .child2').addClass('myClass1 myClass2');
Same with just CSS:
.myClass1 .child-1,
.myClass2 .child-2 {
color: red;
}
/* vs */
.myClass1.child-1,
.myClass2.child-2 {
color: blue;
}
myClass1 myClass2 only apply styles to #child-1 and 2, they don't add any styles to #large-container.
Thank you for advice!
although i think my answer is impossible to verify from a profiler (are there any css/html profiling tools out there in terms of rendering the page etc?) I'll state it based on my experience:
$('#parent').addClass('myClass1 myClass2');
is faster than
$('#child-1, #child2').addClass('myClass1 myClass2');
simply because you are traversing the dom tree once rather than twice ie
$('#child-1, #child2').addClass('myClass1 myClass2'); is the same as
$('#child-1).addClass('myClass1 myClass2');
$('#child-1).addClass('myClass1 myClass2');
to theoretically prove that last point imagine your html code looked something like this:
<div id="parent">
<div id="child-1"></div>
... lots and lots of html nodes
<div id="child-2"></div>
</div>
then looking for #child-1 is a completely separate operation than looking for #child-2.. and when it comes to css/html optimisation.. one of the most expensive operations is the DOM tree traversal.
in the case of $('#parent').addClass('myClass1 myClass2'); you are traversing the DOM tree once (ie finding where #parent is then using css cascading to apply to the elements within the narrowed down #parent DOM subtree
to address the concern that #tMagwell raised about repainting #large-container here is another optimized way of applying css:
// store the child-1 node in a variable.. ie whenever you
// refer to it in the future.. you won't have to traverse the entire DOM again
var child1element = $('#child-1');
$('#child-1).addClass('myClass1 myClass2');
// referring to child1element costs you nothing big, it's already stored in a variable
child1element.siblings().addClass('myClass1 myClass2');
this code works of course assuming that there are only child-1 and child-2.. if you got child-3, child-4.. child-n and only want to apply it to child-n.. then you can use
child1element.siblings()[n] // where n is the index of the child you want to target, since siblings() returns an array
hope this helps!
update:
to address this specific point you raised in the comments:
Does the presence of #large-container slows down something when I add classes to #parent?
the answer is yes. let me give you a scenario where it definitely does:
css:
#parent .class1 .class2
{
font-size:10pt;
}
html:
<div id="parent">
<div id="child-1"></div>
<div id="child-2"></div>
<div id="large-container">
<!-- images etc -->
<p>hello world!<p>
<!-- many more p tags that has a lot of text and stuff -->
</div>
</div>
so in this example.. the font-size:10pt placed under #parent .class1 .class2 will definitely impact the contents of #large-container.. and the operation costs something.. i have no way to quantify how expensive that is (it would depend on the browser rendering engine etc).. but suffice it to say that there is some cost x that is higher than if you didn't just add class1 and class2 to the parent div.

Categories