Overriding previously set CSS - css

My css:
.pic img:hover {
border: 1px black solid;
}
My html:
<div class="pic">
<img src="hey.jpg">
<img class="overlay" src="overlay.jpg">
</div>
I have an "overlay.jpg" that is placed in the bottom corner of the first image.
Problem with the css is that the overlay gets the :hover effect too.
The actual code is very complicated, I know the best solution would be to add a class to the first image and hover only that, but that will take more time than what i currently have to get this fixed.
The code has a class for the overlay images though, so I'm asking if theres a way to override the hover by setting some other css for the overlay class.
However .overlay:hover { border: none; } does not do the trick, even if i put it after the css above.

Your rule is less specific than the previous one so it is getting overridden.
You have to change it to:
.pic .overlay:hover { border: none; }
The concept
Specificity is the means by which a browser decides which
property values are the most relevant to an element and gets to be
applied. Specificity is only based on the matching rules which are
composed of selectors of different sorts.
How is it calculated?
The specificity is calculated on the
concatenation of the count of each selectors type. It is not a weight
that is applied to the corresponding matching expression.
In case of specificity equality, the latest declaration found in the
CSS is applied to the element.
Reference: Specificity

As long as overlay always comes after the first image, you can use :first-child to pick only the first image:
.pic img:first-child:hover {
border: 1px black solid;
}
It's supported in everything (excluding IE6, but I don't count that as a thing.)

You can also use the :not selector:
.pic img:not(.overlay):hover {
border: 1px black solid;
}
This way you won't have to worry about the order of the images and also don't have to worry about specificity by including another reset style.

Related

Is there a reason as to why the HTML tag is sometimes a CSS selector? [duplicate]

How are these three rules different when applied to the same HTML document?
html {
color: black;
background-color: white;
}
body {
color: black;
background-color: white;
}
* {
color: black;
background-color: white;
}
html {
color: black;
background-color: white;
}
This rule applies the colors to the html element. All descendants of the html element inherit its color (but not background-color), including body. The body element has no default background color, meaning it's transparent, so html's background will show through until and unless you set a background for body.
Although the background of html is painted over the entire viewport, the html element itself does not span the entire height of the viewport automatically; the background is simply propagated to the viewport. See this answer for details.
body {
color: black;
background-color: white;
}
This rule applies the colors to the body element. All descendants of the body element inherit its color.
Similarly to how the background of html is propagated to the viewport automatically, the background of body will be propagated to html automatically, until and unless you set a background for html as well. See this answer for an explanation. Because of this, if you only need one background (in usual circumstances), whether you use the first rule or the second rule won't make any real difference.
You can, however, combine background styles for html and body with other tricks to get some nifty background effects, like I've done here. See the above linked answer for how.
* {
color: black;
background-color: white;
}
This rule applies the colors to every element, so neither of the two properties is implicitly inherited. But you can easily override this rule with anything else, including either of the above two rules, as * has literally no significance in selector specificity.
Because this breaks the inheritance chain completely for any property that is normally inherited such as color, setting those properties in a * rule is considered bad practice unless you have a very good reason to break inheritance this way (most use cases that involve breaking inheritance require you to do it for just one element, not all of them).

How to make sure color is overwritten on hover?

HTML:
<div class="hovertest" style="background-color: #fff">
Test 1
</div>
<div class="hovertest" style="background-color: #eee">
Test 2
</div>
CSS:
.hovertest:hover {
background-color: #000;
}
The hover color does not get applied due to the higher specificity of the inline color style. Same problem if I give an ID to the divs and apply their individual color in the ID styling. I want to share the hover color definition across both divs (or more), while displaying their unique color on non-hover. Is this possible without a lot of redundant css?
You can outweigh any specificity of other declarations in CSS by setting !important after the value. Overriding this is only possible with another declaration with !important.
.hovertest:hover {
background-color: black !important;
}
#hovertest:hover {
background-color: red; /* Even using an ID won't override `!important` */
}
But be careful! Using !important in your CSS can result in some really tricky issues. It's often more useful to write your CSS in a way where you avoid using it as much as possible.
Don't use !important reactive, use it preventive.

CSS style for parent instead of child?

I am using jquery to insert html I get from the server into a div. Based on the div contents i'd like to adjust the syle of the container. I wrote up a simple html test. How do I tell css to apply this site when it has X child? After googling I tried :has and :contains with neither working. I don't want to keep my styles in JS as css makes more sense.
Demo: http://jsfiddle.net/wd9fk/
html
<div id="a"><div id="b">B</div></div>
<div id="a"><div id="c">C</div></div>
css
#a { height: 400px; border: 1px solid red; }
#b { height: 200px; }
#a :has #b { height: 300px; border: 1px solid blue; }
You simply cannot traverse up the DOM in CSS. You will need to use JavaScript.
Here is an article explaining why: http://snook.ca/archives/html_and_css/css-parent-selectors
Long story short, it's due to the way CSS is read by the browser, and by introducing it, it would increase the performance hit by a factor of ten (at least!), because it would need to read every single node multiple times to see whether or not it fits the profile.
It's a nice thought, but it's simply not viable.
There is no parent selector for CSS yet, there are plans and it is being discussed though. In CSS Selectors level 4, a subject selector has been proposed, which would let you refer to elements this way:
ol! > li:only-child
Which then reads: “an ol element that contains a single li element” (this syntax is a proposal though), and would let you style the parent ol element.
If this proposal succeeds, subject selectors would be available in the next version of CSS selectors.
For now, Javascript is the way to go, until the subject selector becomes a standard.
You cannot traverse up the DOM to get the parent selector of current matching elements.
But you can do it with jQuery quite easy like this:
$('#Default a span.active').closest('.vehicle_details').css('background-color','#444');
Fiddle Demo
#a > #b { height: 300px; border: 1px solid blue; }
Not sure if this is what you wanted, but give it a try.
Regards.

Import CSS Selector Styles in Another Selector? (NOT #import)

Is there a way to import the styling of a single CSS selector into another CSS selector and add to it or rewrite properties from it.
Let's say:
.original_class{
background:black;
color:white;
}
.overwrite{
#import(.original_class); /* I know this doesn't work */
color:blue;
border:1px solid green;
}
I can accomplish this by just redeclaring the .original_class and assigning new values (since CSS styles are rewritten from top to bottom), but this will replace the attributes of the original CSS class. What I want is to inherit its properties into another class without having to write them again (duplicate).
Not directly, no.
You could do something like this in your HTML:
<div class="original_class overwrite">...</div>
This will have the same effect, but you will have to do this for every element you want styled that way.
There is also the option of using a CSS pre-processor, like SASS, which supports inheritance/mixins.
You can add the .overwrite selector to the first rule by separating it from the existing selector with a comma (grouping selectors), so the selector rule becomes .original_class, .overwrite:
.original_class,
.overwrite {
background: black;
color: white;
}
.overwrite {
color: blue;
border: 1px solid green;
}
Also, when you write:
this will replace the attributes of the original CSS class
there is no such thing as attributes and class in CSS, not with the intended meaning of OOP I guess. There are rules, selector rules (to select HTML id, classes, elements, attributes and other pseudos), declarations, properties and values.
Unfortunately not. At least not without one of those fancy CSS plugin thingies that I wouldn't touch with a mile-long pole...
Of course, there's nothing stopping you having multiple classes on a single element.

Find if class has border in css

Find if class has border in css only, by using attribute selector or by any other means.If it is not having then apply the border.Intention is Not to fall back on to either jquery. Is this possible to acheive?
Edited to include response from #nag (OP):
In IE8 there is no border for select. So I'm trying to do a css reset like this:
select, input[type="file"], textarea {
border: solid 1px #7F9DB9;
}
The problem is it is overriding any preexisiting style because of specificity. I tried to use expression filter but with DocType in IE8 it does not seem to work.
CSS has no concept, or implementation, of if/else statements, so this is not possible in CSS only.
However, if you define the border for an element, and then later redefine that border the second statement will override the first (assuming an equally specific selector), so I'm unsure as to why you need to apply a border only if the element doesn't already have a border defined:
div {
border: none; /* removes the border */
}
/* other stuff */
div {
border: 1px solid #f90; /* defines the border */
}
Similarly:
div {
border: 5px solid #0f0; /* defines the border */
}
/* other stuff */
div {
border: 1px solid #f90; /* re-defines the border */
}
If you can define your use-case it might be possible to help you further.
Edited to address the further information in the question:
In IE8 there is no border for select. So I'm trying to do a css reset like this:
select, input[type="file"], textarea {
border: solid 1px #7F9DB9;
}
The problem is it is overriding any preexisiting style because of specificity. I tried to use expression filter but with DocType in IE8 it does not seem to work.
If the problem is specificity, then the only options you have are to either increase the specificity of the selector you want to apply, ideally use an id, or multiple ids, in your selector (the id of an ancestor element is fine) since that's the most specific selector available.
Or, you can decrease the specificity of the selector you want to override.
It's worth noting that the select element is difficult to style reliably since it's often rendered by the underlying OS, rather than the browser itself, for a consistent look within that operating system.
You have three alternatives:
Use JavaScript - that has logic, so you can check whether it has a border or not and then do something with the result. You can use a library like jQuery or MooTools to make it easier.
Make this selector more specific, so that it only applies to elements that you want it to.
Make your other selectors more specific with classes, IDs, or nested selectors (like form textarea).

Resources