CSS Select more span at once inside a class - css

How can i select more span of the same class in CSS? I'd need it for hover specifically.
I tried with span.classname:hover
and .classname span:hover
where the first doesn't work at all, and the second one works only for one span at a time.
This is how the html looks:

The :hover selector would apply to the span when it is being hovered over.
If you want to highlight all spans within an element when you hover on the element, you need to shift the :hover selector left:
div.special:hover span {
color: red;
}
<div class="special">
<span>Span</span> and another <span>Span</span>
</div>
This will apply to all spans inside the special div, when you hover over the special div.
If you want the other spans to activate when one span is hovered, you are going to have to script it... the closest you can get in CSS is the general sibling selector, which works on the span and other spans that follow it within the same parent. I would imagine you'd want it to work backwards too, which it doesn't in this case.
span:hover, span:hover ~ span {
color: red;
}
<div>
<span>Span</span> and another <span>Span</span>
</div>

Related

CSS: Does the plus sign work with pseudo elements?

For markup similar to this:
<div>
<p>hello world</p>
</div>
<div>
<h4>hello world</h4>
</div>
Can you do something like this in CSS:
div:after {
content: "";
display: block;
border-bottom: 2px solid red;
}
p + div:after {
content: "";
display: block;
border-bottom: 2px solid blue;
}
...meaning to say "Give all :after pseudo elements immediately following a <p> a blue border. Give all others a red border".
This doesn't seem to work. I realize this is because the + sign is applying to the 'div' selector, not the 'div:after' selector as a whole. But is there another way to target these in CSS (without adding a new class specific to these instances and without manipulating the DOM)?
Basically, what Michael_B said:
You can't target a pseudo-element. A pseudo-element is added to a selector that has matched an element.
"Target" is a vague term, but the second sentence is on point here. Combinators only work with elements, because selectors match elements, not pseudo-elements. What you're really trying to do in selector nomenclature is to style the ::after pseudo-element of a div whose last child is a p element (in which case the ::after box immediately follows the p box in the formatting tree):
<div>
<p>hello world</p>
div::after <!-- Blue border -->
</div>
<div>
<h4>hello world</h4>
div::after <!-- Red border -->
</div>
And you can't do that, because there is no parent selector.
I imagine something like div:has(> p:last-child)::after from Selectors 4 will work, but it depends on whether :has() makes it into CSS in the first place. The only other good option is to figure out which of these div elements has a p as their last child and assign them a special class name.
See also:
Can I target a :before or :after pseudo-element with a sibling combinator?
Is there a CSS parent selector?

:first-child not being applied

On this page, I want to hide the incorrect HTML displayed above the logo. It is generated by an old plugin we are replacing soon.
To start with, I tried the CSS:
.vine-home-block-grapes:first-child {display: none;}
but this does not remove the highlighted block below:
Can you help me determine why please?
Use css :first-of-type selector
.vine-home-block-grapes:first-of-type{
display:none;
}
That selector won't work as the element you are attempting to select is not the :first-child of its parent.
One way to do what you want is select all elements with that class name, set their styles as you wish and then, using a new rule with the sibling selector, override those styles for any element of that class appearing later in the parent.
.vine-home-block-grapes{
display:none;
}
.vine-home-block-grapes~.vine-home-block-grapes{
display:block;
}
Add this script. It would work fine without any problem:
<script>
var fourthChild = document.body.getElementsByTagName("div")[0];
document.body.removeChild(fourthChild);
</script>
Thanks to #FelixKling
Try wrapping the child elements in a <div> so the element can BE the first child of its wrapping element. Right now, your element is not the first child of <body> See the experiment here to show how :first-child doesn't work as expected, because really it's not the first child of its parent.
p:first-child {
background-color: aqua;
}
.vino:first-child {
background-color: lightgreen;
}
WORKS
<p>First</p>
<p>Second</p>
<p>Third</p>
DOESN'T WORK (because none of these are the first child of its parent, in this case, <body>
<p class="vino">First</p>
<p class="vino">Second</p>
<p class="vino">Third</p>
Adding a wrapping div works.
<div>
<p class="vino">First</p>
<p class="vino">Second</p>
<p class="vino">Third</p>
</div>

Class names concatenated or separated by a space

When do you separate style classes with a space? So for example: what is the difference between the following two blocks of css?
Block 1:
div {
color: brown;
}
div.special {
font-size: 18px;
}
Block 2:
div {
color: brown;
}
div .special {
font-size: 18px;
}
This is the HTML:
<div class="special">The quick brown fox jumps over the lazy dog.</div>
I tried both versions. Only with block 1 the text wil be in font size 18.
You separate classes by a space when you want to refer to descendant element and you concatenate them when you want to refer to a single element with multiple classes.
For example, to refer to a div with two classes, e.g. <div class="foo bar"> you could use:
div.foo.bar {...}
To refer to the child span element <div class="foo"><span class="bar">stuff</span></div> you could use:
div.foo .bar {...}
A space indicates nesting:
div .foo /* .foo is inside div */
No space indicates further specificity:
div.foo /* any div that is also .foo */
div.special refers to
<div class="special"> <- this
div .special refers to
<div>
<p class="special"> <- this
</div>
Not neccassily a p BTW
The space notes that this is a child item.
IE
div.special
targets a div that has the class special while
div .special
targets an element with class special inside a div element
div.special will select the div element which has class .special and it wont select any other element with class .special so if you have something like <ul class="special"> will be excluded, where as this div .special will select all the elements having class .special which are nested inside div so this will select <ul class="special"> so it concludes that the 1st one is stricter than the second one
So in your case either you can simply use .special or you can use div.special

Show/hide an html element with hover selector

I want to hide a div element on mouse over only using css.
<div>Stuff shown on hover</div>
div {
display: block;
width:100px;
height:100px;
border: solid black;
}
div:hover {
display: none;
}
Why that doesn't work?
if I want to change -for example- the background instead it works just fine:
div:hover {
background-color: red;
}
Is not possible to hide/show the same element which I'm applying the hover selector?
http://jsfiddle.net/link01/TknA8/
Why that doesn't work?
Isn't that obvious ...?
The Div element is displayed.
You move your mouse over it - which puts it in its :hover state.
You say that for its :hover state, the element is to be removed completely from the rendered output.
Since it is now "not there any more", the mouse can't still be over it.
Mouse not over it any more means, element is no more in :hover state.
What does your CSS say again for the element when it is not in its :hover state?
Ah yes, display:block.
OK, browser renders the element again.
Hey, what's that, that freaking mouse is over it?
Let's see, that means it has to be removed again ...
When an element has its display set to none it doesn't exist in the layout and therefore can't be interacted with with the mouse.
Just add a wrapper around it:
<div class="wrapper">
<div class="hidden">Stuff shown on hover</div>
</div>
http://jsfiddle.net/cecAn/

:first-letter selector doesn't work for link

The :first-letter pseudo-element selector works perfectly for a <p> element but not for links. This, for instance, has no effect:
a:first-letter
{
font-size:200%;
text-transform:uppercase;
color:#8A2BE2;
}
Why? How can I make the first-letter style different for an <a> element
According to the W3 spec, the :first-letter pseudo-element only work for a block element, which a is not.
Oddly, *:first-letter caused the first letter to transform, at Chrome 14 and Firefox 3.6.23. Fiddle: http://jsfiddle.net/8W7FF/3/
Check the specification. As of now, inline elements are not supported by ::first-letter:
In CSS, the ::first-letter pseudo-element applies to block-like containers such as block, list-item, table-cell, table-caption, and inline-block elements.
Note: A future version of this specification may allow this pseudo-element to apply to more display types.
https://www.w3.org/TR/selectors-3/#application-in-css
Thus, if you try to style the ::first-letter of something that isn't a "block-like container", like an inline element, it won't work. This doesn't just apply to links; you'll also find that, by default, you can't style the ::first-letter of a span either, as shown below:
div::first-letter, span::first-letter, a::first-letter {
font-size:200%;
text-transform:uppercase;
color:#8A2BE2;
}
<div>I'm a div</div>
<span>I'm a span</span>
I'm an anchor
A possible fix to this is to turn the element into a block container by, for instance, setting it to display: block or display: inline-block. Below is an example, using the former for the span and the latter for the a:
div::first-letter, span::first-letter, a::first-letter {
font-size:200%;
text-transform:uppercase;
color:#8A2BE2;
}
span {
display: block;
}
a {
display: inline-block;
}
<div>I'm a div</div>
<span>I'm a span</span>
I'm an anchor

Resources