Why does class not update ID? - html

I have an ID which shows an image at the top of my site
<div id="Introduction">
When I click the <div> it toggles the class active which works.
However the background image does not seem to change - can anybody tell me why?
I know the class is being added because I can see by inspecting the element.
#Introduction
{
width: 95%;
height: 280px;
padding-top: 85px;
padding-left: 5%;
background-image: url('background1.jpg');
background-size: cover;
background-position: center center;
transition: all 1s ease-in-out;
}
#Introduction .active
{
background-image: url('background2.jpg');
}

You have an error in your selector, you're checking for .active that is a descendant of #Introduction. It should be #Introduction.active, without a space.

Just remove the white space between #Introduction .active. Like #Introduction.active.
An space between two simple selectors A B is called descendant combinator, which would select all Bs that are descendants of As.
In this particular instance, .active class is added to the div having #Introduction ID as well, hence you should use those two selectors without any combinators (spaces, > greater-than sign, etc.).

Related

Specificity issue in CSS

So I have a list of items inside a div with the class book-select and one of the li's in my unordered list has the class selected. According to the CSS rules I've defined, the li's in the div has the background color skyblue and the one li with the class selected would be steelblue.
The problem is that the book-select class is overwriting the selected class, which I don't understand. Wouldn't the div class be less specific than the li with the class selected? The li is in a ul which is in the div.
Here's the relevant CSS and HTML:
.book-select li {
font-size: 0.75em;
text-align: center;
list-style: none;
background: skyblue;
width: 25%;
margin: auto;
}
.selected {
background: steelblue;
}
<div class="book-select">
<h2>Pick a book:</h2>
<ul>
<li>Set A Volume 1, Course Foundation</li>
<li>Set A Volume 2, Expeditionary Airman</li>
<li>Set A Volume 3, Professional Airman</li>
<li>Set B Volume 1, Supervisory Communicator</li>
<li>Set B Volume 2, Supervisor of Airmen</li>
<li class="selected">All</li>
</ul>
</div>
This is part of a quiz and the idea is that the user clicks on a book and jQuery will change the class of the selected item to whatever is clicked on, with the last li with the text "All" being the default selected book. I could use a different jQuery method to change the background color, but the fact that CSS is giving me this specificity error is bothering me.
I know .book-select li is overwriting .select because the console is showing the background: steelblue; as crossed off.
Shouldn't it be the other way around? Isn't .selected the more specific class, as it only contains one element, which is itself?
Use this selector to increase the specifity of that CSS rule:
.book-select li.selected {
background: steelblue;
}
About "specifity": Simply said, one class plus one tag (.book-select li) has more "weight" concerning specifity than just one class (.selected), so a rule with one class plus one tag will overwritea rule with just one class. And the selector shown above will overrule that again, since it consists of two classes and one tag.
Even Something as simple as
li.selected
{
background: steelblue;
}
Should overide the background for you :)
for a possible solution, you can do this:
.selected {
background: steelblue !important;
}
important will avoid this style from being override

Inline CSS works, external doesn't (JsFiddle included)

http://jsfiddle.net/xw0vvo9e/4/
I'm attempting to set a background color for my navBar. As you can see in the jsfiddle, I have:
div .navBar {
width: 100%;
height: 45px;
background-color: #FF0000;
top: 0px;
position: fixed;
}
and it doesn't work. However, if I remove it, and change the HTML to:
<div class="navBar" style="background-color:#FF0000;">
it works just fine. I've been scratching my head on this for quite some time now.
You should remove the space in your selector, i.e. it should be div.navBar. Your current selector which is a descendant combinator selector tries to find .navBar descendants of the div elements. As the .navBar element doesn't have any div parents/grandparents the selector fails to select the target element.

CSS alternative to li:has(+ .class) relational pseudo class and li:not(.class ~ li)

I have a script (JsFiddle here) that detects when an li block element is vertically centered on a page and assigns it a .centered class to make it bigger via CSS.
.centered {
height: 30vh;
background-color: #bbb;
-webkit-transition: height 0.6s;
}
Once the central element is identified I manage to select the next sibling to via this:
.centered + li {
height: 20vh;
background-color: #ccc;
-webkit-transition: height 0.6s;
}
The problem arises when I try to select the sibling element preceding the .centered element in pure CSS
After looking at this question from 2011 I tried playing with the :has() pseudo class suggested in one of the comments and other selectors, but with no luck.
This CSS4 relational pseudo class could have done the trick, but is not currently supported:
li:has(+ .centered) {
height: 20vh;
background-color: #Fcc;
-webkit-transition: height 0.6s;
}
I also tried to select the last-of-type of li elements that are not siblings of .centered, but either :not() supports only simple selectors or I'm just not getting how to chain the selectors properly.
Here's the non-working selector:
li:not(.centered ~ li):last-of-type {
height: 20vh;
background-color: #Fcc;
-webkit-transition: height 0.6s;
}
QUESTION: Is there any combination of pseudo classes and selectors that could do the trick in pure CSS?
My hope is that some progress has been made since those questions have been asked.
Is there any combination of pseudo classes and selectors that could do the trick in pure CSS?
There isn't; the reason :not(.centered ~ li) doesn't work is indeed that it only currently supports simple selectors — like :has(), :not() will only accept combinators in Selectors 4. Since there are no pseudo-classes that currently accept combinators, and the only available sibling combinators go forward, you are left with a very restricted domain language in this regard. This is why those additions to Selectors were made.
As for progress... progress on the :has() pseudo-class has been eh. Last I heard, the working group was still deciding between allowing a subset of :has() in CSS or separating that out into its own pseudo-class, and vendors were going to see how much of it they could implement in CSS for this to work. But I don't think there has been any data yet.
Following the confirmation that it is impossible by #BoltClock and the #torazaburo comment I changed my initial jQuery selection starting element
From this:
middleElement = this;
$(this).toggleClass("centered", true);
To this:
middleElement = this;
$(this).prev().toggleClass("top", true);
Without adding extra javascript code, I could then change my CSS selectors.
From:
.centered { /*selects the middle element */
height: 30vh;
background-color: #bbb;
-webkit-transition: height 0.6s;
}
.centered + li { /*selects the next sibling after middle element */
height: 20vh;
background-color: #ccc;
-webkit-transition: height 0.6s;
}
li:has(+ .centered){ /*not supported at time of writing*/
height: 20vh;
background-color: #Fcc;
-webkit-transition: height 0.6s;
}
To:
.top, .top + li + li { /* selects the siblings before and after the middle one*/
height: 20vh;
background-color: #ccc;
-webkit-transition: height 0.6s;
}
.top + li { /* This selects the middle element*/
height: 30vh;
background-color: #bbb;
-webkit-transition: height 0.6s;
}
>> JSFiddle

CSS3 Selectors: + vs ~ and the opposite of ~?

After seeing the different selectors available (as of CSS3), the difference between the + and ~ seem to be nearly the same. And it also appears there is no selector with opposite functionality to ~.
Taken from www.w3schools.com:
div + p: Selects all <p> elements that are placed immediately after <div> elements.
p ~ ul: Selects every <ul> element that are preceded by a <p> element.
The effect of p ~ ul can be rewritten as:
Selects all <ul> elements that are placed after a <p> element.
Because preceded by a <p> means the <p> is before the <ul>.
This leaves the only difference between these operators being that + only select elements immediately after (I assume all consecutive occurrences), whereas ~ selects elements anywhere after (but still with the same parent).
Is my understanding of the difference correct?
Originally I thought the two operators were opposites due to the somewhat confusing english.
So, my follow-up questions is this:
How can I select every element placed before (or immediately before) another element?
I'm working with this case scenario:
I have 2 div's side-by-side in the same parent div.
<div id="container">
<div id="column_left">
</div>
<div id="column_right">
</div>
</div>
When I hover either div, both should gradually become more opaque using CSS transitions. When I'm not hovering either, they should become more transparent.
So, to select the right column when the left is hovered I would using the selector:
#column_left:hover+column_right {
opacity: 0.9;
transition: opacity 300ms;
-webkit-transition: opacity 300ms;
}
Now, how can I select the left column when the right is hovered?
Here is my CSS so-far:
div {
border: 1px solid black;
background: #262626;
}
#left {
float: left;
width: 200px;
height: 200px;
margin: 0;
transition: background 300ms;
-webkit-transition: background 300ms;
}
#right {
display: inline-block;
width: 200px;
height: 200px;
transition: background 300ms;
-webkit-transition: background 300ms;
}
#left:hover,#left:hover~#right {
background: #909090;
transition: background 300ms;
-webkit-transition: background 300ms;
}
<div id=left>
</div>
<div id=right>
</div>
Is my understanding of the difference correct?
Yes. Selectors L3 defines those two types of sibling combinators (emphasis mine):
Adjacent sibling combinator
The adjacent sibling combinator is made of the "plus sign" (U+002B, +)
character that separates two sequences of simple selectors. The
elements represented by the two sequences share the same parent in the
document tree and the element represented by the first sequence
immediately precedes the element represented by the second one.
General sibling combinator
The general sibling combinator is made of the "tilde" (U+007E, ~)
character that separates two sequences of simple selectors. The
elements represented by the two sequences share the same parent in the
document tree and the element represented by the first sequence
precedes (not necessarily immediately) the element represented by the second one.
How can I select every element placed before (or immediately before) another element?
As explained in Is there a previous sibling selector?, it's not possible to do that with Selectors L3. Selectors L4 may introduce some way to do it, but probably it will only be available in JS (e.g. through querySelector) but not in CSS stylesheets because of performance reasons.
A solution for your specific use case
When I hover either div, both should gradually become more opaque using CSS transitions. When I'm not hovering either, they should become more transparent.
.wrap {
float:left;
overflow:hidden
}
div {
border: 1px solid black;
}
#left {
float: left;
width: 200px;
height: 200px;
margin: 0;
background-color: red;
transition: background 300ms;
-webkit-transition: background 300ms;
}
#right {
float:left;
width: 200px;
height: 200px;
background-color: blue;
transition: background 300ms;
-webkit-transition: background 300ms;
}
.wrap:hover > #right,
.wrap:hover > #left {
background: #909090;
transition: background 300ms;
-webkit-transition: background 300ms;
}
<div class="wrap">
<div id=left>
</div>
<div id=right>
</div>
</div>

Display button image outside bounds of link

Can I create button, use a background image that changes on hover and on active, and have the active state show an image that extends outside of the bounds of the anchor? Here's my sprite:
https://dl.dropbox.com/u/7737304/menu-sprite1.png
The top half of the sprite is 'hover', the bottom is 'active'. I don't anything below the solid bar to be a clickable link, and I don't want to set a width as the menu text will set on top and extend beyond the left and right edges of the image.
I've attempted to assign the background image to the parent li tag, which works for 'hover' but I can't make it work for 'active'.
Any ideas?
CSS
.navigation li:hover{
background: transparent url(../images/menu-sprite.png) center -86px no-repeat;
}
.navigation a{
color: #e8e8e8;
font-weight: bold;
text-transform: uppercase;
padding:0.5em 0.8em;
}
.navigation a:hover{
color: #fff;
}
.navigation a.active {
color: #fff;
}
Do you mean something like this ?
The anchor 'expands' when active, but doesn't change the flow, since it uses a negative margin to make it actually the same size as before.
So: add the amount of padding you want to expand the anchor, then add the same amount as a negative margin. (You do need the anchor to be a block or inline-block element, since otherwise it can't use margin)
No need for JavaScript with this method.
This is what I came up with: DEMO
It just puts the background image on the <li>. Not sure if this is exactly what you are looking for or not though.
This is a tough one to explain! What I did was to make the a tag clickable, extended the li with ::after to which I could apply the styles necessary to make it change, but not be click able.
Like I said, tough to explain but here is a demo: http://jsfiddle.net/cchana/SgH5C/
And here's some CSS that may help you:
.navigation li::after {
background: transparent url('https://dl.dropbox.com/u/7737304/menu-sprite1.png') center -49px no-repeat;
bottom: 0px;
content: '';
display: block;
height: 31px;
position: absolute;
width: 100%;
}
.navigation li:hover::after {
background: transparent url('https://dl.dropbox.com/u/7737304/menu-sprite1.png') center -130px no-repeat;
}