Sibling selector on image wrapped with links - html

I'm trying to sibling-select images. There's a sequence of images that are wrapped with links and I want to select all but the first one.
img {
max-width: 50px;
}
.content img {
max-width: 400px;
}
img.a ~ img.a {
border: 1px #333 solid;
}
<div class="content">
<a href="/">
<img class="a b c" src="https://upload.wikimedia.org/wikipedia/commons/6/6d/Astrodon1DB.jpg">
</a>
<a href="/">
<img class="a b c" src="https://upload.wikimedia.org/wikipedia/commons/2/27/Nipponosaurus_dinosaur.png">
</a>
<a href="/">
<img class="a b c" src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Macronaria_scrubbed_enh.jpg/800px-Macronaria_scrubbed_enh.jpg">
</a>
</div>
Here's a fiddle: http://fiddle.jshell.net/efsev59z/
Why doesn't img.a ~ img.a select all images with class "a" that follows an image with class "a"? From my understanding they're both children of a common element, .content. What's wrong, and how do I make it happen?

To be considered siblings, the elements need to be children of the same immediate parent (not just a common ancestor, since all DOM elements share body as an ancestor for example). Consider something like this:
a ~ a > img.a {
/* styles */
}

sibling selectors only apply to siblings. Each one of those images have their own parents. They are cousins, rather than siblings.

A different approach is to apply the border to all images but then override it for the first image. You can use the :first-child selector to get the first anchor and target the image within it.
img {
max-width: 50px;
}
.content img {
max-width: 400px;
}
img.a {
border: 1px #333 solid;
}
.content a:first-child img {
border:none;
}
http://fiddle.jshell.net/efsev59z/4/

Related

How to not execute parent's :hover on child :hover

When the .post-item <div> is hovered I want to execute some specific styles (change background-color and cursor) but I don't want this to happen if the .rating-wrapper <div> is hovered too. This happens because I want the .rating-wrapper to do something different than the hover of its parent. Basic question: How to do only child's hover, ignoring the parent's hover
HTML:
<div class="post-item">
<div class="rating-wrapper">
<div class="upvote">
<img src="/images/upvote_arrow.png" alt="upvote" />
</div>
<div class="rating"></div>
<div class="downvote">
<img src="/images/downvote_arrow.png" alt="downvote" />
</div>
</div>
<span class="owner-data">
<img src="" alt="" class="owner-avatar" />
<span class="owner-username"></span>
</span>
<span class="creation-date"></span>
<div class="title"></div>
</div>
Since you want to change the style of the parent element based on a pseudo-class of the child element, this isn't really possible with CSS alone today.
You can do it with the :has() pseudo-class but that is currently only supported in Safari (with support for Chrome a few months away and no sign of it in Firefox, Edge, Opera or elsewhere).
#parent {
background: white;
border: solid black 1px;
padding: 2em;
max-width: 50%;
margin: auto;
}
#parent:hover:not(:has(#child:hover)) {
background: orange;
}
#child {
background: #aaa;
border: solid black 1px;
padding: 2em;
}
#child:hover {
background: green;
}
<div id="parent">
<div id="child"></div>
</div>
For a more reliable approach, you should probably look at adding a splash of JavaScript to the mix.
Use mouseenter and mouseleave events to modify the classes of the parent element, then reference the class in your stylesheet.
const parent = document.querySelector('#parent');
const child = document.querySelector('#child');
const enter = event => parent.classList.add('child-hover');
const leave = event => parent.classList.remove('child-hover');
child.addEventListener('mouseenter', enter);
child.addEventListener('mouseleave', leave);
#parent {
background: white;
border: solid black 1px;
padding: 2em;
max-width: 50%;
margin: auto;
}
#parent:hover:not(.child-hover) {
background: orange;
}
#child {
background: #aaa;
border: solid black 1px;
padding: 2em;
}
#child:hover {
background: green;
}
<div id="parent">
<div id="child"></div>
</div>
You can use this CSS Selector,
.post-item>:not(.rating-wrapper):hover {
background-color: white;
}
This will select all immediate children of .post-item which are not .rating-wrapper.
To change the block of the remaining items background color, you can enclose them in another div.
There is a css property called not property.The syntax is like:
:not(element) {
// CSS Property}
If you want to learn more, please visit this link:
https://www.geeksforgeeks.org/how-to-exclude-particular-class-name-from-css-selector/
The pointer-events CSS property sets under what circumstances (if any) a particular graphic element can become the target of pointer events.
try:
pointer-events: none
you can read more here: https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

meaning and role of [class*=] css class selector

Asking here since I can't pass a proper search query with that.
Here's a code sample:
[class*="button_type"].state_2,
[class*="button_type"]:not(.state_2):hover{
background-color:#fff;
}
Furthermore what would be the use of the :not suffix?
I cannot understand why it isn't just:
.button_type.state_2,
.button_type:hover { etc..}
[class*="button_type"] is CSS class Selector (equivalent to CSS attribute selector) means that will select all elements whose class contains at least one substring "button_type".
take a look at this example:
[class*="button_type"] {
background: red;
width: 50px;
height: 50px;
display: inline-block
}
<div class="button_type"></div>
<span class="one_button_type"></span>
<article class="button_type_final"></article>
Regarding the :not() that means it will select everything but that selector which is inside the :not()
Take a look at this example:
[class*="button_type"] {
background: red;
width: 50px;
height: 50px;
display: inline-block
}
[class*="button_type"]:not(.state_2) {
border: black solid
}
<div class="button_type state_1"></div>
<span class="one_button_type state_2"></span>
<article class="button_type_final state_3"></article>

Hover to multiple elements at the same time?

I'm trying to apply a hover for a whole block (the same block must point to a link), but can't make this happen.
http://codepen.io/anon/pen/GogjQK
I've tried to wrap an <a> tag around the entire frame class and edit the hover states individually, but nothing happens.
This is how I'm trying to make it appear on hover, as well when the the link is clicked and active
Hope someone can help me out with this one. Thank you in advance.
You can use child selectors on your frame div to affect the children within.
For example, I added the following code to color the h3 tag when the main frame is hovers.
.frame:hover > div > h3 {
color: #00bb00;
}
If you modify your HTML slightly to be
<div class="frame">
<img src="http://imagizer.imageshack.us/v2/xq90/903/WUtWQJ.png" class="thumbnail" />
<img src="http://placehold.it/60x60" class="thumbnail" id="hidden" />
<div class="info">
<h3>H3</h3>
<p>pppppp</p>
</div>
</div>
You can use the following CSS to change the image as well:
.frame:hover > .thumbnail {
display:none;
}
.frame:hover > #hidden {
display:inline;
}
#hidden {
display:none;
}
Here's an example codepen.
Try adding a hyper reference after the creation of the div that contains your block, like this:
<div class="frame"> <a href="http://stackoverflow.com">
<img src="http://imagizer.imageshack.us/v2/xq90/903/WUtWQJ.png"
class="thumbnail" />
<div class="info">
<h3>H3</h3>
<p>pppppp</p>
</div>
</a>
</div>
Then in CSS, refer to the entire block as a link, like this:
.frame a {
float: left;
width: 300px;
min-height: 60px;
background-color: ##00F;
margin: 0px 10px;
border: 1px solid black
}
.frame a:hover > .info > h3 {
color: green;
}
Example: codepen

How to style another object in when a user hover object in css

I want to style an object 2 when the user hovers object 1 in css. For Example:
<style>
.object1:Hover then style object2{
Styling of object2 Goes Here
}
</style>
how can i do that
You can do this in several ways, as long as the html element 1 and 2 fulfill some conditions:
Object 1 has to come before Object 2 in your markup (as you
cannot go "up" or "back" in css selectors).
Object 2 has to be reachable by a css selector from Object 1's perspective (again, you cannot go "up" or "back" in css
selectors), that means that Object 2 cannot for example be in a
parent context of Object 1 (which would also violate 1.).
Examples for such selectors:
1. Child selector
.object1:hover .object2 { your css rules here }
works for an html structure, where .object2 is a child element of .object1:
<div class="object1">
<div class="object2">Some content</div>
</div>
2. Adjacent sibling selector
.object1:hover + .object2 { your css rules here }
works for the (one!) immmediately following sibling .object2:
<div class="object1"></div
<div class="object2">This will be affected.</div>
<div class="object2">This will NOT be affected.</div>
3. All siblings selector
.object1:hover ~ .object2 { your css rules here }
will apply your style for all (possibly many!) sibling .object2 (but just as + NOT for child .object2):
<div class="object1">
<div class="object2">This will NOT be affected.</div>
</div>
<div class="object2">This will be affected.</div>
<someElementWhichisNotAffected></someElementWhichisNotAffected>
<p class="object2">This will be affected.</p>
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
div{
width: 200px;
height: 200px;
border: 2px solid #ccc;
margin: 10px auto;
}
.div1:hover{
border: 2px solid #000;
}
.div1:hover ~ .div2{
background: #f00;
}
<div class="div1"></div>
<div class="div2"></div>

Why is General sibling combinator not always working?

I have four divs, and i want to change their width and height on hover so the one you are hovering over expands and all others shrink for how much hovered one expanded. I managed to get it working when i hover over first div, but when i try to do the same with other three nothing happens.
My HTML:
<div id="main">
<div id="mainOne">
<h3>text</h3>
</div>
<div id="mainTwo">
<h3>text2</h3>
</div>
<div id="mainThree">
<h3>text3</h3>
</div>
<div id="mainFour">
<h3>text4</h3>
</div>
</div>
My CSS:
/* HOVER 1 */
#mainOne:hover{
width:748px;
height:600px;
}
#mainOne:hover + #mainTwo{
width:248px;
height: 600px;
}
#mainOne:hover ~ #mainThree{
height:200px;
}
#mainOne:hover ~ #mainFour{
height:200px;
}
/* END HOVER 1 */
/* HOVER 2 */
#mainTwo:hover{
width:748px;
height:600px;
}
#mainTwo:hover + #mainOne{
width:248px;
height: 600px;
}
#mainTwo:hover + #mainThree{
height:200px;
}
#mainTwo:hover ~ #mainFour{
height:200px;
}
/* END HOVER 2 */
So when i hover over mainOne, everything changes, but when i hover over mainTwo just mainTwo changes and messes up everything else. What am i doing wrong?
Thanks.
CSS can only (currently) target elements that appear later in the DOM, therefore #mainTwo + #mainThree will work, but #mainTwo + #mainOne cannot.
To target previous siblings you'd have to wrap the siblings within another, parent, element and then style the previous siblings based on the hover of that parent.
div > div {
border: 1px solid #000;
padding: 0.5em 1em;
width: 80%;
margin: 0 auto;
color: #f00;
}
#main:hover > div {
width: 50%;
}
#main:hover > div:hover ~ div {
width: 50%;
}
#main:hover > div:hover {
width: 80%;
}
JS fiddle proof-of-concept
All your mainTwo rules with :hover use the adjacent sibling combinator.
Only #mainTwo + #mainThree can match as neither #mainOne or #mainFour are the next sibling to #mainTwo.
If you used the general sibling combinator (~) then you could match #mainFour too.
Since #mainOne precedes #mainTwo, you can't match it with a rule that depends on the existence of #mainTwo.