Can this JS be written in pure CSS? - javascript

jQuery('.parent:visible').each(function () {
if (jQuery(this).find('.child-1').is(':hidden')) {
jQuery(this).find('.child-2').css('color', '#000')
}
});
Selecting the children are easy, separately, but since there are no if statements in CSS, I'm hoping there's some magic CSS I'm missing.
edit: fixing js as per suggestions

.parent:not(.hidden) .child-1:not(.hidden) + .child-2 perhaps?
Demo
.parent { border:1px solid red; }
.hidden { display:none; }
.parent:not(.hidden) .child-1:not(.hidden) + .child-2 {
color:green;
}
<div class="parent">
<div class="child-1">one</div>
<div class="child-2">two</div>
</div>
<div class="parent">
<div class="child-1 hidden">one</div>
<div class="child-2">two</div>
</div>
<div class="parent hidden">
<div class="child-1">one</div>
<div class="child-2">two</div>
</div>
<div class="parent">
<div class="child-1">one</div>
<div class="child-2">two</div>
</div>

If you can add classes to the elements based on their visibility, then you can do this.
.parent.visible .child-1.not-visible + .child-2 {
color: #000
}
This will check if a .child-1 inside a .parent.visible has a class of .not-visible -- if it does, then the adjacent sibling with a class .child-2 will inherit this rule.
Otherwise, you have to use JavaScript as CSS doesn't have a way to test if an element is visible or not.

Related

Is it possible to select a element to hover it and it is not it's child with CSS only?

I have an <aside> and <header> and the header has child called container and cont. has some children one of them is called burger bar so what I want here is when I :hover the burger bar the <aside> will be visible so I wonder how to do that or if it is impossible I tried to do this header .container .burger_bar:hover + aside but the aside is not element beside the burger_bar so it's not going to work.
more explain...
<div class='header'>
<div class='container'>
<div class='burger_bar'>...</div>
</div>
</div>
<aside>...</aside> /* <---when hovering the burger bar this will be
transform: translate(0%) right after being transform: translate(-100%) */
If trigger and target are on the same level, you can use .trigger:hover ~ .target to target your .target element while .trigger is being hovered.
.trigger:hover ~ .target {
color: green;
}
<div class="trigger">Hover Me</div>
<div class="target">Target</div>
If your trigger and target are not on the same level, it's better to use some javascript to add a class to your target.
const trigger = document.querySelector('.trigger');
const target = document.querySelector('.target');
trigger.addEventListener('mouseover', () => {
target.classList.add('active');
});
trigger.addEventListener('mouseleave', () => {
target.classList.remove('active');
});
.target.active {
color: green;
}
<div class="parent1">
<div class="trigger">Hover Me</div>
</div>
<div class="parent2">
<div class="target">Target</div>
</div>
Or you could use :has() pseudo class but be aware if its poor coverage (only works in Safari right now)
.parent1:has(.trigger:hover) ~ .parent2 .target {
color: green;
}
<div class="parent1">
<div class="trigger">Hover Me</div>
</div>
<div class="parent2">
<div class="target">Target</div>
</div>

jquery remove div inside of other divs

I have a main <div> with many other divs inside like this:
[HTML]
<div class="container">
<div class="row">
<div class="col">
<div class ="deleteMe">
delete me
</div>
</div>
</div>
</div>
I want to remove the div with class name "deleteMe", i tried to remove it by using ,find() method from jquery:
$('.container').find('.row').find('.col').find('deleteMe').remove();
or
$('.container').find('.row').find('.col').removeClass('.deleteMe');
But didn't work, what is the best way to remove it?
here is the fiddle link test this exemple:
fiddle
//$('.container').find('.row').find('.col').find('deleteMe').remove();
$('.container').find('.row').find('.col').removeClass('.deleteMe');
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
.deleteMe {
border: solid 1px #6c757d;
padding: 10px;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<div class="container">
<div class="row">
<div class="col">
<div class="deleteMe">
delete me
</div>
</div>
</div>
</div>
You do not need jquery for the job, see the following code snippet ( The setTimeout wrapper delays the deletion by 1s and only serves to see what is happening.
setTimeout ( () => {
document.querySelector(".deleteMe").remove();
}, 1000);
<div class="container">
<div class="row">
<div class="col">
<div class ="deleteMe">
delete me
</div>
</div>
</div>
</div>
Given your original code, you might want the selector to be more specific:
document.querySelector(".container > .row > .col > .deleteMe").remove(); // Adjacent sub-selectors reference elements in a parent/child relation
document.querySelector(".container .row .col .deleteMe").remove(); // The elements are in a ancestor/descendant relation, not necessarily child/parent
Try this
$(".container .deleteMe").remove();
below line will do
$( ".container .row .col .deleteMe" ).remove();
There is a little typo in your code: a . is missing before deleteMe.
$('.container').find('.row').find('.col').find('.deleteMe').remove();
correctly.
Another thing: removeClass don't remove an element with the specified class; It removes the specified class from the element.

Tricky toggle active onmouseover with Vanilla JavaScript

I have a structure like below and I want to toggle active the currently hovered .item element.
I'm using a simple Vanilla JavaScript function that I usually use for click-like situations and it works.
function myFunction(e) {
var elems = document.querySelectorAll(".hover");
[].forEach.call(elems, function(el) {
el.classList.remove("hover");
});
e.target.classList.add("hover");
}
<div class="main-container">
<div class="item hover" onmouseover="myFunction(event)">
item 1
</div>
<div class="item" onmouseover="myFunction(event)">
item 2
</div>
<div class="item" onmouseover="myFunction(event)">
item 3
</div>
</div>
So far so good, but here comes the tricky part. When the mouse goes to a sibling element the hover correctly is changing to the inner one.
I tried some CSS ticks but I can't manage to make it work, any thoughts would be much appreciated
P.S. I prefer Vanilla JavaScript than jQuery
You can use CSS to add and remove the hover. Basic code showing that and added code to toggle active so it can move around.
const menu = document.querySelector(".main-container")
menu.addEventListener("click", function (evt) {
const item = evt.target.closest(".item")
if (item) {
menu.querySelector(".item.active").classList.remove("active")
item.classList.add("active")
}
});
.main-container .item.active {
background-color: green;
}
.item,
.main-container:hover .item.active {
background-color: yellow;
transition: background-color .3s;
}
.main-container:hover .item:hover {
background-color: lime;
transition: background-color .3s;
}
<div class="main-container">
<div class="item active">
item 1
</div>
<div class="item">
item 2
</div>
<div class="item">
item 3
</div>
</div>
You don't need JS for that.
Just overwrite style when the container is hovered
.main-container:hover .item.hover {
background-color: transparent;
}
.item.hover {
background-color: red;
}
.item:hover {
background-color: red !important;
}
<div class="main-container" >
<div class="item hover">
item 1
</div>
<div class="item">
item 2
</div>
<div class="item">
item 3
</div>
</div>
See jsfiddle: https://jsfiddle.net/hs2yfxm1/
If you're trying to style this based on a hover event you should be utilizing the proper pseudo-class. You mentioned that you always want the first item to be "active", why not set an .active class that matches the format styling of :hover? For example:
SCSS
.item {
border-color: red;
&.active,
&:hover {
border-color: blue;
}
}
CSS
.item {
border-color: red;
}
.item.active,
.item:hover {
border-color: blue;
}
Note: In general, it's best practice to limit your use of JS whenever possible. If something is attainable simply with HTML and CSS, that should be the preferred implementation in most cases.
Other than the stylistic portion, just one comment on your JS. In your example, you're utilizing e.target this can be dangerous if the element has children in that the target could be the child. Since you're targeting each element individually (a lot of event listeners that you may want to consider re-working) you can make use of e.currentTarget for other JS needs.
Is this what you are after?
.active { background-color:grey; }
.item:hover { background-color:yellow; }
<div class="main-container" >
<div class="item active">
item 1
</div>
<div class="item">
item 2
</div>
<div class="item">
item 3
</div>
</div>

How I hide a div when jquery show another div?

I want that when the click activate the element2 div, the element should disappear. And the element2 div should not appear at the beginning.
$(".toggle").click(function() {
$(".element2").toggle();
});
$(".close").click(function() {
$(".element2").hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="element">
Element 1
<div class="toggle">
toggle
</div>
<div class="element2">
Element 2
<div class="close">close Element 2</div>
</div>
</div>
Add display none to hide an element from the start:
<div class="element2" style="display:none">
The rest of your code appears to be doing what it's supposed to, unless I am misunderstanding "I want that when the click activate the element2 div, the element should disappear"... which is entirely possible.
In order to have element2 hidden at the beginning you need to either add a style tag or even better add a CSS file where you will keep all of your stylings in one place.
For style tag:
<div class="element2" style="display:none">
For CSS:
.element2 {
display: none;
}
Then for your code you are close. In order to make element hide, you need to change it to:
$(".toggle").click(function() {
$(".element2").show();
$(".element").hide();
});
$(".close").click(function() {
$(".element2").hide();
$(".element").show();
});
The HTML will need some changes to, this will make what I wrote work the way I believe you want it to:
<div class="element">
Element 1
<div class="toggle">
toggle
</div>
</div>
<div class="element2">
Element 2
<div class="close">close Element 2</div>
</div>
You should probably do something like this:
$(".toggle").click(function() {
$(this).parent().find(".element2").toggle();
});
$(".close").click(function() {
$(this).parent().hide(); // close the correct .element2
});
In CSS you need to:
.element2 {
display: none;
}
just $(".element2").hide(); hide it at start
$(function() {
$(".element2").hide();
$(".toggle").click(function() {
$(".element2").toggle();
});
$(".close").click(function() {
$(".element2").hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="element">Element 1
<div class="toggle">Toggle </div>
<div class="element2"> Element 2
<div class="close"> close</div>
</div>
</div>
HTML
<div class="element">
<div class="toggle"></div>
<div class="element2" style="display:none">
<div class="close"></div>
</div>
</div>
EXAMPLE CSS
.toggle
{
display:block;
width:20px;
height:20px;
margin-left:10px;
float:left;
background:green;
}
.element2{
display:block;
width:40px;
height:40px;
margin-left:10px;
float:left;
background:yellow;
}
.close{
display:block;
width:20px;
height:20px;
margin-left:10px;
float:right;
border:1px solid #000;
}
JQUERY
$(".toggle").click(function() {
$(".element2").toggle();
});
$(".close").click(function() {
$(".element2").css({"display":"none"});
});
fiddle to check
I hope it is helpfull answer. Good Luck !

How to change styling of a specific div onhover of another element when divs share an id

I have multiple rows with 3 divs per row. Each div consists of two rows; in the first row a picture is displayed, in the second row a description is shown. HTML is like this:
<div id="row">
<div id="block1">
<div id="block1-top"><a><img></a></div>
<div id="block1-bottom">Text here</div>
</div>
<div id="block2">
<div id="block2-top"><a><img></a></div>
<div id="block2-bottom">Text here</div>
</div>
<div id="block3">
<div id="block3-top"><a><img></a></div>
<div id="block3-bottom">Text here</div>
</div>
</div>
<div id="row">
<div id="block1">
<div id="block1-top"><a><img></a></div>
<div id="block1-bottom">Text here</div>
</div>
<div id="block2">
<div id="block2-top"><a><img></a></div>
<div id="block2-bottom">Text here</div>
</div>
<div id="block3">
<div id="block3-top"><a><img></a></div>
<div id="block3-bottom">Text here</div>
</div>
</div>
Some CSS:
#block1, #block2, #block3
{
width: 25%;
height: 150px;
display: inline-block;
vertical-align: top;
background-color: #FFFFFF;
border: 1px solid #154494;
}
#block1-bottom, #block2-bottom, #block3-bottom
{
color:#FFFFFF;
}
I want the color of the text in the bottom of the block to change to #FEB90D on hover of the parent div. So for example when hovering over block1, I want the text color of block1-bottom to change into #FEB90D. I found a script which does this for me:
$(function() {
$('#block1').hover(function() {
$('#block1-bottom').css('color', '#FEB90D');
}, function() {
// on mouseout, reset the background colour
$('#block1-bottom').css('color', '#FFFFFF');
});
});
However, this only works for the first block of the first row. I think this is because the id's of the 1st, 2nd and 3rd blocks have the same name and the script cannot figure out on which block to apply the script.
Does anyone have any thoughts on how to fix this, without changing all the divs id's? I have 11 rows in total so using separate names for each div is not really an option in my opinion. So basically, the scripts needs to change the color of the second child of the hovered div.
You shouldn't be using id for more than one element. Change those ids for classes and it will work.
It's better to do this with CSS
.block1 > .block1-bottom {
color: #FFFFFF;
}
.block1:hover > .block1-bottom {
color: #FEB90D;
}
<div class='block1'>
<p class='block1-top'>This is paragraph 1</p>
<p class='block1-bottom'>This is paragraph 2</p>
</div>
IDs should be unique anyways. If you do it in jQuery, it should look like this.
$(function() {
$('.block1').on("mouseover", function() {
$('.block1-bottom').css('color', '#FEB90D');
}).on("mouseout", function() {
$('.block1-bottom').css('color', '#FFFFFF');
});
});
Ids should be unique. So add necessary classes and use class selector. So code is similar to below
$('.row .box').hover(function() {
$(this).find(".boxbottom").css('color', '#FEB90D');
}, function() {
// on mouseout, reset the background colour
$(this).find(".boxbottom").css('color', '#FFFFFF');
});
Here is the demo https://jsfiddle.net/afnhjdjy/
After you clean up your duplicate IDs problem, you can do this without javascript at all:
<div class="row">
<div class="block">
<div class="block-top"><a><img></a></div>
<div class="block-bottom">Text here</div>
</div>
<div class="block">
<div class="block-top"><a><img></a></div>
<div class="block-bottom">Text here</div>
</div>
</div>
CSS:
.block:hover .block-bottom {color: #FEB90D}
According to this situation:
I want the color of the text in the bottom of the block to change to #FEB90D on hover of the parent div
You may simply use:
.block:hover .block-bottom{
color: #FEB90D;
}

Categories