How to use :before and :nth-child selectors together - css

<ul class="points">
<li>sdsds</li>
<li>sdsds</li>
</ul>
I am changing the list style to font awesome icon i want every second list item to be of different color therefore I have used nth-child(even) but it is not working along with before selector.
.
points li:before {
content: "\f1b2";
font-family: FontAwesome;
display: inline-block;
margin-left: -1.3em;
width: 1.3em;
color: #ba2b9f;
}
.points li:before:nth-child(even) {
color: red !important;
}

I'm writing an answer, although I expect this question to get closed:
You have the selectors in the wrong order.
What it should be:
li:nth-child(even)::before
This translates to: every even li child, affect the before pseudo.
The original
li:before:nth-child(even)
This translates to: an even element of a before psuedo. This will never work as there can only be one before (and after pseudo element).

Related

How to change the CSS style of first-letter when hover over a parent element?

This is likely something I am just stupidly overlooking, but would you please tell me why hovering over the second division element doesn't cause the background color of the first letter to change to rgb(50,50,50) from rgb(150,150,150)?
Hovering over the first division, which starts out with no styling on the first letter, reacts to the style changes upon hover. But the second division, which starts out with the same styles that the first displays upon hover, does not change to the darker background upon hover.
I'm using the latest version of Firefox developer edition. I see now that it works in Chrome; so must be a Firefox issue.
Thank you.
div > p:before { content: 'This text.'; }
div:nth-child(2) > p::first-letter,
div:first-child:hover > p::first-letter
{
float: left;
padding: 0.5rem;
background-color: rgb(150,150,150);
}
div:nth-child(2):hover > p::first-letter
{
background-color: rgb(50,50,50);
}
<div><p></p></div>
<div><p></p></div>
This snippet works in Firefox. It seems that to get the ::first-letter to be styled both without and with :hover a letter has to be there apart from the content added by :before or :after.
div > p:after { content: 'his text.' }
div > p::first-letter
{
float: left;
padding: 0.5rem;
background-color: rgb(150,150,150);
}
div:hover > p::first-letter
{
background-color: rgb(70,70,70);
color: white;
}
<div><p>T</p></div>
I applied #Sydney Y's solution to the above snippet just to show that it works in Firefox. I don't think it is an isue of the :hover not being recognized because the snippet above recognizes it. It appears to be an issue of not including the text added through :before { content: ... } such that there is a first letter to which to apply the style. But adding no content on :hover using :after seems to alter that and works for variable content.
I realize that this of little interest to anyone who doesn't want to use drop caps and change their style based on hover.
div > p:before { content: 'This text.' }
div > p::first-letter
{
float: left;
padding: 0.5rem;
background-color: rgb(150,150,150);
}
div:hover > p::first-letter
{
background-color: rgb(70,70,70);
color: white;
}
div:hover > p:after { content: ''; }
<div><p></p></div>
Yep, just some mix-ups, your accessors are correct. Each block of CSS needs to apply to both divs:
div > p:before { content: 'This text.'; }
div> p::first-letter {
padding: 0.5rem;
background: red;
}
div:hover> p::first-letter{
background: black;
}
div:hover > p:after { content: ''; }
Thanks for the snippet, that's cool!
Edit: getting closer! Code is updated. Still attempting on Firefox.
Edit: Solved, kind of. It works, but it's kind of a hack. The
issue: In Firefox the hover doesn't trigger a repaint in this specific
instance, so I added an empty bit of content on hover because the
:after or content seem to have a kind of a hook. You may be able to
achieve the same thing with a different hack other than content.
But good news is: this works in both Chrome and Firefox.
Awesome problem. I can't imagine ever coming across this issue again, but it was super interesting to troubleshoot.
There is a bug in firefox that nth-child() is not going to work on syntax that's why it is not working. Anyway if not want the same functionality as first one with different color this can be done with you just need to put hover in front of this code
"div:nth-child(2) > p::first-letter,div:first-child:hover > p::first-letter ". I hope this will help. https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child

Which CSS selector to use to select the first letter of the element with id?

Which CSS selector to use to select the first letter of the element with id?
I want to make the first letter of the element with id 'special' green and 100px font size.
I tried :
#special:nth-of-type(1){
color: green;
font-size: 100px;
}
There's a ::first-letter pseudoselector
http://www.w3schools.com/cssref/sel_firstletter.asp
#special::first-letter {
color: green;
font-size: 100px;
}
<p id="special">This is a paragraph</p>
I've had the same issue. The answer above is correct. For further information, read the following on https://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048
"21. X::pseudoElement
p::first-line {
font-weight: bold;
font-size: 1.2em;
}
We can use pseudo elements (designated by ::) to style fragments of an element, such as the first line, or the first letter. Keep in mind that these must be applied to block level elements in order to take effect.
A pseudo-element is composed of two colons: ::
Target the First Letter of a Paragraph
p::first-letter {
float: left;
font-size: 2em;
font-weight: bold;
font-family: cursive;
padding-right: 2px;
}
This snippet is an abstraction that will find all paragraphs on the page, and then sub-target only the first letter of that element.
This is most often used to create newspaper-like styling for the first-letter of an article.
Target the First Line of a Paragraph
p::first-line {
font-weight: bold;
font-size: 1.2em;
}
Similarly, the ::first-line pseudo element will, as expected, style the first line of the element only."
If you want to select the first letter of the element with id, simply add a "#" in order to select it. It goes like this:
#insertnameofyouridhere::first-line {
color: blue;
font-size: 20px;
}

Can we stylize the number in an ordered list without changing the entire li?

Is it possible with CSS to change the style of the number in an ­<ol> without changing the entire text in the <li> without adding extra markup around the li content?
You can disable the original <ol> style, then use :before selector with counters to add whatever style you want. Like here:
ol {
counter-reset: i 0;
}
ol li:before {
content: counter(i);
counter-increment: i;
padding-right: 0.5em;
color: red;
}
If you wish, you can even override some styles for particular elements of the list with nth-child selector (JS Fiddle):
ol li:nth-child(3):before {
color: violet;
}
... as cascading rules are still applied here. Note, though, that nth-child is not supported by IE8.

Why does :before only seem to work once in my code?

I am using :before to display webfont icons before menu items. For some reason :before is only working on one class and is completely ignoring the other class. If I change both classes on the two li's that should have icons before them to the working class name, the icon shows up.
Ideas?
Here is an example:
http://jsfiddle.net/bigdmachine/erxjE/1/
I'd rather update the CSS to;
nav#al-top-menu .log-out a:before,
nav#al-top-menu .setting a:before {
content: "X";
margin-left: 15px;
margin-right: 5px;
font-family: 'WebSymbolsRegular';
font-size: 14px;
color: blue;
}
I don't think you can create "free" pseudo-elements inside of an <ul> like that, the list should only contain list items.

How do change <li> elements that are NOT active with pure CSS?

I understand how to change the description of an active <li> element
li:active {
...declarations...
}
But how can I change all the other elements that are NOT active?
For example, all my elements are in bold, but when I select one of them, all the others are changed back to normal.
Thanks!
I'd imagine li:not(:active) should at least theoretically work.
Apply a rule to ALL of them, then apply a different rule to the active.
li {
color: blue;
}
li:active {
color: red;
}
Result: the un-active ones are blue.
After rereading your question, I think the real answer is that you can't use CSS alone to control how the elements behave on user interaction.
I realize that this won't work because the styles are applied immediately, and elements in the DOM are typically not :active by default:
li {
font-weight: bold;
}
li:not(:active) {
font-weight: normal;
}
Plus, :not() is a CSS3 pseudo-class, so support for it is rather poor right now if you have to account for older browsers.
Maybe you can do this with JavaScript (I use jQuery here)...
$('li').click(function() {
$(this).siblings().css('font-weight', 'normal');
});
If I understand correctly this should do it,
li{ font-weight:bold; }
:active li{ font-weight: normal; }
:active li:active{ font-weight: bold; }
So basically you want an active state on the parent which switches everything to normal and then override that for the li that is also active.
To expand Brad's answer based on your example:
You want all <li>'s to be bold, until one is clicked, right? Start off with:
li {
font-weight: bold;
}
Then, if a list item is clicked keep that one bold but make the others regular:
li:active ~ li {
font-weight: normal;
}
The ~ selects all elements that are siblings of the active li, without selecting the active one itself.

Resources