This question already has answers here:
CSS Child vs Descendant selectors
(8 answers)
Closed 1 year ago.
I tried this solution but am missing something: change background of parent div on hover
Here is my html:
<div class="box">
<h3 class="page-header item-title">
<a class="titlelink" href="/index.php?option=com_content&view=category&id=11&Itemid=234">
Modeling</a>
This is what I tried to use in an override here: /templates/shaper_helixultimate/html/com_content/category/default_children.php
$document = JFactory::getDocument();
$document->addScriptDeclaration('
$('.box > .titlelink').hover(function(){
$(this).parent().toggleClass('hover');
})
});
');
http://jsfiddle.net/t5hf8qdc/
What am I doing wrong?
$('.box > .titlelink').hover(function() {
$(this).parent().toggleClass('hover');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
<h3 class="page-header item-title">
<a class="titlelink" href="/index.php?option=com_content&view=category&id=11&Itemid=234">
Modeling</a>
</h3>
</div>
The selector .box > .titlelink looks for a parent-child relationship. You don't have that.
Use .box .titlelink instead.
$('.box .titlelink').hover(function() {
$(this).parent().toggleClass('hover');
});
.hover {
background: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
<h3 class="page-header item-title">
<a class="titlelink" href="/index.php?option=com_content&view=category&id=11&Itemid=234">
Modeling</a>
</h3>
</div>
As #isherwood mentioned, the solution you linked to uses a different structure than what you have. The > in CSS selectors specifies that you're targeting a direct child, while just leaving a space between the two selectors looks for any descendant.
.box > .titlelink {
/* targets where .titlelink is a child of .box */
}
.box .titlelink {
/* targets where .titlelink is a descendant of .box */
}
If you want to use a strict CSS selector like the solution you referenced, you could do:
$('.box > .item-title > .titlelink').hover(function(){
$(this).parent().toggleClass('hover');
});
Although this will add the hover class to the .item-title element, not to the .box element. Assuming that you specifically want target the .box ancestor of whatever you're listening for the hover event on, then you want:
$('.box > .item-title > .titlelink').hover(function(){
$(this).parents('.box').toggleClass('hover');
});
since jQuery's parents method allows you to pass a selector to target a specific ancestor, travelling multiple levels up through the tree.
Related
<div class="parent">
<div class="child-class">
<div>
<div class="child-class">
<div>
<div class="child-class">
<div>
</div>
I need to add a class to second child-class using jQuery
Adress the second child of the parent via CSS Selector:
$('.parent > .child-class:nth-of-type(2)').addClass('your-class');
Advantage over using nth-of-type instead of nth-child is beeing more precise in selecting what you want. The nth-child will select any child of your parent. nth-of-type will only select children with a certain type (in this case class child-class).
You can use :nth-child selector at this context,
var elem = $(".parent > .child-class:nth-child(2)");
Note that, the index that is being passed into the selector would start from 1 not from 0.
Here you go with a solution
$('.parent > .child-class:eq(1)').addClass('newClass');
.child-class {
width: 100px;
height: 50px;
border: 1px solid;
}
.newClass {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="child-class"></div>
<div class="child-class"></div>
<div class="child-class"></div>
</div>
I've used jQuery eq selector.
Documentation: https://api.jquery.com/eq-selector/
Hope this will help you.
I have two instances of elements in my document. One is with just a class of slide and the other with a class of slide and slide--current. Below is an example of this markup.
<div class="slide slide--current">
<h2 class="title title--centered title--modifier">Slide 1</h2>
<div class="text-block">
<p>text</p>
</div>
</div>
<div class="slide">
<h2 class="title title--centered title--modifier">Slide 2</h2>
<div class="text-block">
<p>text</p>
</div>
</div>
If I want to target text-block when it has slide--current as the parent I would use .slide--current > .text-block as my selector. But what if I want to target text-block when it doesn't have slide--current? I'm asking because both elements need to have the class slide applied to them at all times. If I use .slide .text-block styles will be applied to slide--current when they shouldn't be. Is this a case foe the :not() selector?
You can use a pseudo-selector:
.slide:not(.slide--current) {
// styling here
}
In your case, as long as .text-block is always a direct child of .slide:
.slide > .text-block {
// Apply to all text blocks regardless of state of slide
}
.slide:not(.slide--current) > .text-block {
// Only applied if parent slide is not current
}
You could probably achieve the same result by reading the answer by #Rounin and avoid pseudo-selectors by reversing your thought process and setting some base styles for all text-blocks first then overriding them when the slide is current.
But what if I want to target text-block when it doesn't have
slide--current?
This is a lesson in how to use the cascade in CSS in the right order.
.text-block {
BASIC .text-block STYLES
}
.slide .text-block {
ADDITIONAL .slide .text-block STYLES
}
.slide--current .text-block {
ADDITIONAL .slide--current .text-block STYLES
}
Basically, you start with the core styles and you add, cumulatively, as the context grows increasingly specific.
A previous developer built a webpage with a woman and numbers on it to click for to show services related to a bodypart. You can see the current page here...
http://dermanaissance.com/nos-solutions/
My issue here is that he built the solution with CSS VS using JS or Jquery. I'm trying to hide the other blocks when a specific block has been clicked using what he's already done but am afraid isn't possible only using CSS.
I'm not quite sure how to tackle this one without using Jquery as this is usually how I would approach this, any ideas?
This is the code right now...
<div id="anchor-1" class="nos-anchor">1
<span class="nos-block">
<span class="nos-line"> </span>
<ul>
<li>Lift Sans Chirurgie</li>
<li>Atténuation des Rides</li>
<li>Contour des Yeux</li>
<li>Double-menton</li>
<li>Bajoues</li>
<li>Relâchement du Cou</li>
<li>Ouverture du Regard</li>
<li>Augmentation du Volume</li>
<li>Amélioration du Teint de la Peau</li>
<li>Acné Active</li>
<li>Cicatrices d’Acné</li>
<li>Décolleté</li>
<li>Atténuation des Cicatrices</li>
<li>Photorajeunissement</li>
<li><a href="/taches-pigmentaires-et-melasma/">
Taches pigmentaires et Mélasma</a></li>
<li>Couperose et Rosacée</li>
<li>Varicosités</li>
</ul>
</span>
</div>
and the CSS that makes this solution work...
.page-id-9 #main-content .nos-anchor {
position: absolute;
display: block;
z-index: 9;}
.page-id-9 #main-content .nos-anchor .nos-block {
position: absolute;
display: none;}
.page-id-9 #main-content .nos-anchor .nos-block a {
display: block;}
.page-id-9 #main-content .nos-anchor .nos-line {
display: block;
position: absolute;
top: 20px;}
If you want a pure CSS solution I suggest looking into the Target psuedo element, otherwise -
Here is a pure javascript solution. Just give the divs you are hiding and showing an ID, and call them with the clickable object using onclick="hideShow(sectionID);"
<div style="height:40px; width:40px; background:red;" onclick="hideShow('div1')">
<div id="div1" style="display:none; background:orange; width:15px; height:15px;"></div>
</div>
<div style="width:40px; height:40px; background:yellow;" onclick="hideShow('div2')">
<div id="div2" style="display:none; background:green; width:15px; height:15px;"></div>
<div></div>
</div>
<div style="width:40px; height:40px; background:blue;" onclick="hideShow('div3')">
<div id="div3" style="display:none; background:purple; width:15px; height:15px;"></div>
<div></div>
</div>
var currrentElementShowing;
function hideShow(sectionID) {
if (document.getElementById(sectionID) != currrentElementShowing) {
document.getElementById(sectionID).style.display = "block";
if (currrentElementShowing != undefined) {
currrentElementShowing.style.display = "none";
}
currrentElementShowing = document.getElementById(sectionID);
} else {
}
}
https://jsfiddle.net/cxjndqzu/
Wow "page-id-9" is pretty terrible naming convention (I know you didn't do it, but MAN!).
So, what I would do is create two CSS classes:
"ToggleClass"
"Active"
You would assign "ToggleClass" to all of your list items. Using CSS, you make "ToggleClass" items that ALSO have the "Active" class display how you would like. "ToggleClass" items WITHOUT the "Active" class would be hidden as you would like.
Then, using jQuery (sorry, but I think it has to be done), make the following function:
$(document).ready(function(){
$(".ToggleClass").on("click", function(){
$(".ToggleClass").removeClass("Active");
$(this).addClass("Active");
});
});
This event will fire anytime someone clicks a "ToggleClass" element. First, it removes the "Active" class from ALL elements that have "ToggleClass" (this ensures that you won't simultaneously have two elements with the "Active" class). Next, it adds the "Active" class to the element that was clicked.
Leave a comment and let me know how this works for you - Good luck!
Having looked at your page, you could apply something like this. You'll have to use pure Javascript or Jquery. Since you mentioned JQuery as your preference:
html
<div>
<div class="pill">1</div>
</div>
<div>
<div class="pill">2</div>
</div>
js
$('.pill').click(function(){
$(this).toggleClass('active')
if ($(this).hasClass('active')){
$('.pill').not(this).fadeOut(200)
}else{
$('.pill').not(this).fadeIn(200)
}
});
The idea here is to use Jquery's toggleClass method and to check whether the click element has the active class, and if it does hide the other elements. This should steer you in the right direction
Fiddle
How could I make it so that given two elements let's say these boxes:
If I clicked over one, it would grow, and the other would shrink like and vice versa:
How can I do this?
I have seen this sort of done with CSS, using the focus tag and adjusting the width. But I have two problems there, first how could I affect the other element, and second as far as I can tell adjusting width will only stretch them right. I have seen people change the way they float the elements to deal with that, but I don't want to move them around the page to do this.
Here are 2 examples without Javascript/jQuery:
Pure CSS - Trigger on click: (example)
Using the checkbox hack in CSS you can effectively toggle the widths of the elements when the checkbox is :checked. Here is what part of the CSS looks like:
input[type=checkbox]:checked ~ .red {
width:70%;
}
input[type=checkbox]:checked ~ .green {
width:20%;
}
Go to the example for the full CSS.
HTML
<input type="checkbox" id="toggle" />
<div class="red">
<label for="toggle"></label>
</div>
<div class="green">
<label for="toggle"></label>
</div>
You might also be interested in the original example I made. It takes a different approach, though it doesn't fully work.
Pure CSS - Trigger on hover: (example)
Unfortunately, neither the adjacent selector, nor the general sibling selector can select previous elements, therefore it makes this a little difficult. I placed 2 general elements before the main elements in order to somewhat solve this issue.
.greenS:hover, .greenS:hover ~ .green,
.redS:hover, .redS:hover ~ .red {
width:72%;
}
.greenS:hover ~ .redS, .greenS:hover ~ .red,
.redS:hover ~ .greenS, .redS:hover ~ .green {
width:22%;
}
HTML
<div class="redS"></div><div class="greenS"></div>
<div class="red"></div>
<div class="green"></div>
Since this was tagged as JS/jQuery, here are 2 alternative solutions.
JS/jQuery - Trigger on click: (example)
$('.red, .green').click(function(){
$('.red').toggleClass('expanded')
.next('.green').toggleClass('contracted');
});
JS/jQuery - Trigger on hover: (example)
$('.red').hover(function(){
$(this).toggleClass('expanded')
.next('.green').toggleClass('contracted');
});
$('.green').hover(function(){
$(this).toggleClass('expanded')
.prev('.red').toggleClass('contracted');
});
See jQuery .animate() method documentation.
Example on jsfiddle:
.box {
width: 100px;
height: 100px;
display: inline-block;
}
#box1 {
background: red;
}
#box2 {
background: blue;
}
<div class="box" id="box1"></div>
<div class="box" id="box2"></div>
$('.box').click(function() {
var currentWidth = $(this).outerWidth(),
siblingCurrentWidth = $(this).siblings('.box').outerWidth();
$(this).animate({'width' : currentWidth/2})
.siblings('.box').animate({'width' : siblingCurrentWidth*2});
});
This is a very simple example with several flaws, but it demonstrates a possibility for what your purpose is.
Simple example http://jsfiddle.net/PeLub/ ( modify how you need) .
<div class="box" id="first"></div>
<div class="box" id="second"></div>
$("#first").click(function(){
$(this).animate({width:'50px'}, 500);
$("#second").animate({width:'150px'}, 500);
});
$("#second").click(function(){
$(this).animate({width:'50px'}, 500);
$("#first").animate({width:'150px'}, 500);
});
I have an image and rollover image. Using jQuery or CSS, I want to show/hide the rollover image when the onmousemove/onmouseout event happen on the parent div (containing the image).
How can I do it?
Edit: HTML posted below by request. Not relevant to the question, but as an FYI HTML is built on a 30 column fluid grid.
Upon hover of the top div (row-fluid) the image (image.png) should change to a different source image (imagehover.png).
<div class="row-fluid" style="padding-top:1em">
<div class="span4">
//Random content
</div>
<div class="span8 offset1">
//Random content
</div>
<div class="span9 offset3">
<ul>
<li>//Random content</li>
<li>//Random content</li>
<li>//Random content</li>
</ul>
</div>
<img src='../../images/image.png>
<div>
You want to do something like this: full_path_to_css parent:hover child
full_path_to_css parent:hover child {
styles for your item
}
eg:
html (the div.img can be anything):
<div class="parent">
<div class="img">
</div>
</div>
css:
div.parent {
width:200px;
height:200px;
background-color:red;
}
div.img {
width:100px;
height:100px;
background-color:blue;
}
div.parent:hover div.img {
background-color:green;
}
if you want to test check here: http://jsfiddle.net/NicosKaralis/kd6wy/
just to remember, the div with img class can be any element, doesn't need to be div and you can change the css styles as you wish, the only thing you need to watch is the parent:hover child
EDIT
Just to clarify one thing: the item with :hover is the parent on witch you want to detect the hover action, and the child is the item on witch you want to change the css rules
EDIT AGAIN
<div id="parent" class="row-fluid" style="padding-top:1em">
<div class="span4">
//Random content
</div>
<div class="span8 offset1">
//Random content
</div>
<div class="span9 offset3">
<ul>
<li>//Random content</li>
<li>//Random content</li>
<li>//Random content</li>
</ul>
</div>
<img class="child" src='../../images/image.png>
<div>
on your code you will need:
div#parent.row-fluid img.child {
display:none;
}
div#parent.row-fluid:hover img.child {
display:block;
}
this will make your image only show up if the mouse is over your div
Should just be as easy as attaching a mouseover and mouseout event handlers to the parent div and then manipulating the containing img element.
var rolloverImage = ...
var origImage = ...
$("#parentDivId")
.mouseover(function() {
$("#parentDivId img").attr("src", rolloverImage)
})
.mouseout(function() {
$("#parentDivId img").attr("src", origImage)
})
Try:
$('div.row-fluid').hover(function() {
$(this).find('img').attr('src', 'http://dummyimage.com/100x100/000/fff');
}, function() {
$(this).find('img').attr('src', 'http://www.placekitten.com/100/100');
});
jsFiddle example
Without having any html to test with, this is just something I thought up in my head. Not sure if it will work or not, but I don't see why it wouldn't.
$('div').mouseenter(function() {
var image = $('img', this);
$(image.attr('src', 'new-image-src.jpg');
}).mouseleave(function () {
var image = $('img', this);
$(image).attr('src', 'old-image-src.jpg');
});
You can use this code to "show/hide the rollover image"
#parentDiv > img {
display: none;
}
#parentDiv:hover > img {
display: block;
}
The > allows you to select img tags that are the direct descendents of #parentDiv (I gave the outer div that ID). Then we're just setting a different style for it on regular and hover states.
Answering my own question, as I used elements of others' comments and answers to create a hybrid: a sprite, totally CSS solution. I find this to be optimal.
Per #gilly3 "Image swaps are best done with a sprite, so that there is never any delay switching between the images. Put both versions of the image side by side in a single file. Set that image to be the background of a div, and adjust the background position to display one or the other image." For this example, I will use a 96px (height) by 27px (width) sprite, using my em values.
In HTML replace img line with:
<div class="sprite-image"></div>
CSS:
.sprite-image {
{
background-image: url(../../images/image.png);
height: 3.7em;
width: 27px;
}
.row-fluid:hover .sprite-image
{
background-position: 0px -3.7em;
}