:hover but :not on a specific class - html

How do I apply a hover effect on an a element, but not to an a element with the class active?
a:hover(not: .active)
Seems something is missing.

The functional notation is on :not(), not :hover:
a:not(.active):hover
If you prefer to put :hover first, that's fine:
a:hover:not(.active)
It doesn't matter which pseudo-class comes first or last; either way, the selector works the same. It just happens to be my personal convention to put :hover last as I tend to place user-interaction pseudo-classes behind structural pseudo-classes.

You have the option of using the not() selector.
a:not(.active):hover { ... }
However, this may not work in all browsers, as not all browsers implement CSS3 features.
If you are targeting a large audience and want to support older browsers, the best way would be to define a style for the .active:hover and undo whatever you're doing in a:hover.

We can use :not() operator on hover like below example.
We can use this when we don't want to apply :hover effect to the selected item
.block-wraper {
display: flex;
}
.block {
width: 50px;
height: 50px;
border-radius: 3px;
border: 1px solid;
margin: 0px 5px;
cursor: pointer;
}
.active {
background: #0095ff;
}
.block:not(.active):hover {
background: #b6e1ff;
}
<div class="block-wraper">
<div class="block"></div>
<div class="block active"></div>
<div class="block"></div>
<div class="block"></div>
</div>

Related

Apply style to div but not <strong> child

How can I possibly apply a style to a parent div but not the <strong> child. I've tried various ways of :not selector but none of my tries succeeded.
Here's what I came up with
.total:not(strong) {
color: gray;
}
<div class="total">Baloons <strong>$3.75</strong></div>
<div class="total">Pens <strong>$1.99</strong></div>
I know I can do apply the styles to those separately but I am looking for a :not way of doing it so I can do it on one line.
I also know I can give <strong> a class and do .total:not(.strong-class) but why doesn't it work the way I try it originally?
The :not rule refers to the target element. Your rule .total:not(strong) is translated to apply the styles (color: gray) to an element with class .total, which is not a strong node (the <strong> tag). Since the .total node is div, the rule still applies.
Reset the strong's color to initial or choose a different color:
.total {
color: gray;
}
.total strong {
color: initial;
}
<div class="total">Baloons <strong>$3.75</strong></div>
<div class="total">Pens <strong>$1.99</strong></div>
Check the default css of color in the element strong.
.total:not(strong) { works fine, but the default color is gray too!
:not
*{color:blue}
.total:not(strong) {
color: gray;
}
<div class="total">Baloons <strong>$3.75</strong></div>
<div class="total">Pens <strong>$1.99</strong></div>
You can use this code
body {
padding: 0;
margin: 0;
}
.total {
color: red;
}
.total strong {
color: gray;
}
<div class="total">Baloons <strong>$3.75</strong></div>
<div class="total">Pens <strong>$1.99</strong></div>

How to remove top margin when element is empty?

Here is my HTML structure:
p {
margin: 0;
border: 1px solid;
}
small {
display: block;
margin-top: 40px;
border: 1px solid #999;
}
small + span {
display: block;
border: 1px solid #ccc;
}
<p>content</p>
<small>tags</small>
<span>edit</span>
All fine. Sometimes <small> element is empty. Something like this:
<p>content</p>
<small></small>
<span></span>
In this case, I want to remove the margin-top of <small>.
Is that possible using pure CSS? It should be noted I don't want to use JS.
You could try using a combination of :not and :empty pseudo-classes.
small:not(:empty) {
margin-top: 40px;
}
The negation CSS pseudo-class, :not(X), is a functional notation taking a simple selector X as an argument. It matches an element that is not represented by the argument. X must not contain another negation selector. -MDN
The :empty pseudo-class represents any element that has no children at all. Only element nodes and text (including whitespace) are considered. Comments or processing instructions do not affect whether an element is considered empty or not. -MDN

CSS Select paragraphs and figures except the last [duplicate]

How would I select all but the last child using CSS3 selectors?
For example, to get only the last child would be div:nth-last-child(1).
You can use the negation pseudo-class :not() against the :last-child pseudo-class. Being introduced CSS Selectors Level 3, it doesn't work in IE8 or below:
:not(:last-child) { /* styles */ }
Make it simple:
You can apply your style to all the div and re-initialize the last one with :last-child:
for example in CSS:
.yourclass{
border: 1px solid blue;
}
.yourclass:last-child{
border: 0;
}
or in SCSS:
.yourclass{
border: 1px solid rgba(255, 255, 255, 1);
&:last-child{
border: 0;
}
}
easy to read/remember
fast to execute
browser compatible (IE9+ since it's still CSS3)
Nick Craver's solution works but you can also use this:
:nth-last-child(n+2) { /* Your code here */ }
Chris Coyier of CSS Tricks made a nice :nth tester for this.
When IE9 comes, it will be easier. A lot of the time though, you can switch the problem to one requiring :first-child and style the opposite side of the element (IE7+).
Using nick craver's solution with selectivizr allows for a cross browser solution (IE6+)
There is a:not selector in css3. Use :not() with :last-child inside to select all children except last one. For example, to select all li in ul except last li, use following code.
ul li:not(:last-child){ }
If you're using it within the nesting of the parent then the easiest way is:
&:not(:last-child){
....
}
Example:
.row { //parent
...
...
...
&:not(:last-child){
....
}
}
Using a more generic selector, you can achieve this as seen below
& > *:not(:last-child) {/* styles here */}
Example
<div class="parent">
<div>Child one</div>
<div>Child two</div>
</div>
This will capture all the child DIV in the parent
to find elements from last, use
<style>
ul li:not(:last-child){ color:#a94442}
</style>
Nick Craver's solution gave me what I needed but to make it explicit for those using CSS-in-JS:
const styles = {
yourClass: {
/* Styles for all elements with this class */
'&:not(:last-child)': {
/* Styles for all EXCEPT the last element with this class */
},
},
};
.nav-menu li:not(:last-child){
// write some style here
}
this code should apply the style to all except the last child

Why does ':last-child' change the priority of styles?

I encountered a scenario which confuses me - usage of :last-child affects how parent classes are applied.
What I have is a list of elements, and the goal is to apply some styles to the last element.
However, when I use :last-child, the priority of styles changes, and one of the parent classes stops working, only !important fixes the problem.
I made a simple demo here:
http://jsfiddle.net/wC2AX/1/
HTML:
<div class="hover">
<div class="focus_on_last_child" style="background-color:red; width:100px; height:100px">
<div class="attribution">
</div>
</div>
</div>
CSS:
/*this should be applied on hover always*/
.hover:hover .attribution{
background-color: black; /*try adding !important*/
bottom: 0px;
}
/*basic properties*/
.attribution {
height: 60px;
overflow: hidden;
position: absolute;
bottom: -60px;
width: 100px;
}
/*depending on a screen size styles are changed*/
.focus_on_last_child:last-child .attribution { /*try removing :last:child*/
background-color: pink;
bottom: -30px;
}
The example is a little bit stupid, the idea is on hover styles should be changed. But it works only when either !important is used or :last-child is removed.
Thanks for any suggestions!!
This is an issue of selector specificity.
Your first rule has two classes and a pseudo-class:
.hover:hover .attribution
And your last rule also has two classes and a pseudo-class (:last-child being that pseudo-class):
.focus_on_last_child:last-child .attribution
Since your two rules are equally specific, the one that comes later will take precedence. When you remove the :last-child pseudo-class, only the two class selectors remain and so the specificity of that rule is reduced, allowing your :hover rule to take precedence.
The simplest solution is to move your :hover rule underneath your :last-child rule, so that rule takes precedence and you won't have to make use of !important.
It's because:
.hover:hover .attribution{
Is more specific than:
.focus_on_last_child .attribution {
But if you would add .hover to it, it would be more specific, and will work:
.hover .focus_on_last_child .attribution {

Why can't I select the first div with the class 'offer'?

I'm trying to set the background color of the first div with the class offer. I thought .offer:first-child would do the trick, but that isn't working.
I've also tried using :nth-child(1), but that's not working either.
Any suggestions is greatly appreciated.
My fiddle: http://jsfiddle.net/MNQar/
CSS
.offer:first-child { background-color: indianred; }
.special-offers .title,
.special-offers .offer,
.special-offers .more {
height: 200px;
}
[class*="column"] {
display: inline;
float: left;
margin: 0;
}
.column2 { width: 190px;}
.column3 { width: 285px;}
HTML
<div class="row row-spacer special-offers">
<div class="column2 title">
<h2>Offers</h2>
</div>
<div class="column3 offer padding">
<div class="date">10. June</div>
<h3>Høyer tømmer lageret!</h3>
</div>
<div class="column3 offer padding">
<div class="date">10. June</div>
<h3>Super salg hos Vivikes</h3>
</div>
<div class="column1 more">
<div class="caret"></div>
More offers
</div>
</div>
.offer:first-child means "An element With the class 'offer' that is the first child beneath its parent", not "the first child with class 'offer'".
I believe you have to re-think how you do this. For example, stick a separate class to the first child or something, then use a selector like .offer.highlight.
CSS Only
This should work:
.offer { background-color: #ccc; }
.offer ~ .offer {background-color: transparent; }
It first sets all .offer elements to have a background color, then uses the sibling selector (~) to undo it for all subsequent .offer elements. Kind of a hack but it should be okay if you're not willing to use javascript. See here for a much more complete explanation: CSS selector for first element with class
And here's a fiddle: http://jsfiddle.net/MNQar/4/
JS
Alternatively, this is really easy to do with Javascript: $(".offer").eq(0).css("background-color","#ccc");
Fiddle: http://jsfiddle.net/MNQar/6/
The problem is that there is a div that precedes the first offer, making it the second element, not the first. The best solution is to give the first offer a different class, offer-first and use that. If that's not possible and the first offer is always the second child, you can use :nth-child(2)
Using :nth-child(2)
http://jsfiddle.net/MNQar/3/