CSS: Can't get multiple :nth-child selectors to work - css

I have a main menu and 4 colours and Id like each colour to cycle through 1-4 then start again if there are more than 4 items.
But each menu item only receives the first colour - this is my CSS (compiled from less):
.main-nav li a:nth-child(4n+1) {
background-color: #7ebdeb;
}
.main-nav li a:nth-child(4n+2) {
background-color: #abc081;
}
.main-nav li a:nth-child(4n+3) {
background-color: #f4d1a2;
}
.main-nav li a:nth-child(4n+4) {
background-color: #e96956;
}
I have no other background colours specified - I've been racking my brain and have tried several online nth-child testers to double check the specific selectors but can't work out what's going wrong sorry.

You are targeting the same element in each list item, the anchor, repeatedly. Each list item only has one child. You probably want:
.main-nav li:nth-child(4n+1) {
background-color: #7ebdeb;
}
.main-nav li:nth-child(4n+2) {
background-color: #abc081;
}
.main-nav li:nth-child(4n+3) {
background-color: #f4d1a2;
}
.main-nav li:nth-child(4n+4) {
background-color: #e96956;
}
jsFiddle example

I guess this is what you want:
JSFiddle
.main-nav li:nth-child(4n+1) a {
background-color: #7ebdeb;
}
.main-nav li:nth-child(4n+2) a {
background-color: #abc081;
}
.main-nav li:nth-child(4n+3) a {
background-color: #f4d1a2;
}
.main-nav li:nth-child(4n+4) a {
background-color: #e96956;
}

Related

When scrolling how can I change the TEXT color of a floating header menu?

I'm building this site www.shapeinthecity2.unicornrobots.com and I have a transparent floating header menu with white text on the homepage.
However, the text gets hidden as you scroll down. Is there a way to change the text color to black after you scroll past a certain point?
Below is the CSS script I've added so far,
Thanks
/*--- Menu Spacing & Color ---*/
.home #header-right-menu li a {
color: #ffffff;
}
.home #header-right-menu ul ul a {
color: #cccccc;
}
#header-right-menu ul ul a:hover {
color: #ffffff;
}
.top-navigation a, #header-right-menu a {
color: #000000;
margin-right: 80px;
}
#header-right-menu li a:hover {
color: #ff6600;
}
.top-navigation a, #header-right-menu ul ul a {
background: #000000;
}
.site-logo img {
margin-left: 80px;
}
.home.transparent-header .site-header {
position: fixed;
top:50px;
}
/*--- Menu Spacing & Color End ---*/
Hey I am not able to see your floating header, may be your script not working. As your site have one error. Check your source.
your code is visible on the site:
$('#whitediv').waypoint(function() {
alert('Change your background color of div');
$('.navbar').css('background-color', '#000000');
}, {
offset: '5%'
});
This code is visible. Please check and correct. Then we can check it properly. Thanks.

Edit CSS to apply for certain elements

I know it's a dumb question but I couldn't find a solution myself. I have two lists in my HTML page. First one is :
<ul id="menu">
<li><a href='#Url.Action("MainPage","Shirts")'>Main Page</a></li>
<li><a href='#Url.Action("OnSale","Shirts")'>On Sale</a></li>
<li><a href='#Url.Action("Recent","Shirts")'>Recent</a></li>
</ul>
The second one is a PagedListPager which generates an HTML list :
#Html.PagedListPager(Model, page => Url.Action("Mainpage",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
This is my CSS for this HTML :
ul {
list-style-type:none;
margin:0;
}
li {
display:inline-block;
float: left;
margin-right: 1px;
}
li a {
display:block;
min-width:140px;
}
li:hover a {
background: #19c589;
}
li:hover ul a {
background: #f3f3f3;
color: #2f3036;
}
li:hover ul a:hover {
background: #19c589;
color: #fff;
}
li ul li {
display: block;
float: none;
}
li ul li a {
width: auto;
min-width: 100px;
}
My problem is that, I want my CSS to work for only the first list, not the second one. I know I need to add a class for first list's elements and edit CSS for that class. But I couldn't do it. I don't know what to do for li ul li a in CSS. Can you tell me how to edit CSS and first list in this case? Thanks.
Try:
#menu > li {
display:inline-block;
float: left;
margin-right: 1px;
}
#menu > li a {
display:block;
min-width:140px;
}
You can use CSS3 child selectors to select specific properties:
ul li a { /* shared styles */ }
ul > li > a { /* parent list styles */ }
ul ul > li > a { /* child list styles */ }
https://css-tricks.com/child-and-sibling-selectors/
You say you have two lists on your page (so two ul elements). And you only want to apply certain css to the first list without using a class or id selector.
You can use the first-of-type pseudo selector, like so:
ul:first-of-type { }
And to apply the css to its children:
ul:first-of-type li { }
According to Can I use this is pretty well supported (unless you need IE8 support).

Selecting child element of grandparent in LessCSS

As I understand in LessCSS added feature which allows us to select parent element.
Here is an example of it.
.header {
.menu {
border-radius: 5px;
.no-borderradius & {
background-image: url('images/button-background.png');
}
}
}
The output will be.
.header .menu {
border-radius: 5px;
}
.no-borderradius .header .menu {
background-image: url('images/button-background.png');
}
But what if I want to be the output like this. Is it possible or no.
.header .no-borderradius .menu {
background-image: url('images/button-background.png');
}
Thanks for your attention.

Sass only selecting parent [duplicate]

I have the following SCSS for styling links in my menu:
nav {
ul {
li {
a {
color: red
}
}
}
ul.opened {
li {
a {
color: green
}
}
}
}
Which generates the following (correct) CSS:
nav ul li a {
color: red;
}
nav ul.opened li a {
color: green;
}
I tried modifying my JavaScript to apply the class to the nav element instead, and use selector-append() in Sass to append the class. But that seems to do the appending in the wrong order (and if the arguments are reversed, the class is appended to the last element!):
nav {
ul {
li {
a {
color: red;
#at-root #{selector-append('.opened', &)} {
color: green;
}
}
}
}
}
Output (incorrect!):
nav ul li a {
color: red;
}
.openednav ul li a {
color: green;
}
Is there a way the SCSS can be rewritten so that the class can be correctly appended without having to duplicate selectors (similar to the selector-append() method)?
The short answer
Since the element we want to replace has a unique name, what we're looking for is this:
nav {
ul {
li {
a {
color: red;
#at-root #{selector-replace(&, 'ul', 'ul.opened')} {
color: green;
}
}
}
}
}
The long answer
Manipulating selectors is extremely dirty, and I would advise against it unless you absolutely had to. If you're overqualifying your selectors by specifying things like table tr td or ul li, then start by simplifying: tr and ul are both redundant in these selectors (unless you're trying to avoid styling elements under an ordered list). Adjust your nesting to be simpler, etc.
Starting with Sass version 3.4, there are 2 important features that allow you to modify selectors.
Selector functions
The parent selector can be stored in a variable
Example:
.foo ul > li a, .bar {
$sel: &;
#debug $sel;
}
You'll always get a list of list of strings because selectors can be chained together with a comma, even when you have only one selector.
.foo ul > li a, .bar { ... }
(1 2 3 4 5), (1)
You'll note that the descendant selector is being counted here (lists in Sass can be either space or comma delimited). This is extremely important to remember.
When selector-replace() doesn't work
The selector-replace() function does not work in the following cases:
The selector you want to replace is not unique (eg. ul ul li)
You want to insert one or more selectors (eg. ul ul li -> ul ul ul li)
You want to remove a selector (eg. ul > li -> ul li)
In this case, you'll need to loop over the selectors and you'll need to know which position you want to modify. The following function will take a function and apply it to a specific position in your selector using the magic of the call() function.
#function selector-nth($sel, $n, $f, $args...) {
$collector: ();
#each $s in $sel {
$modified: call($f, nth($s, $n), $args...);
$collector: append($collector, set-nth($s, $n, $modified), comma);
}
#return $collector;
}
Append a class (when the selector isn't unique or you don't know its name)
The function we need here takes 2 arguments: the original selector and the selector you'd like to append to it. Uses simple interpolation to do the job.
#function append-class($a, $b) {
#return #{$a}#{$b};
}
.foo, .bar {
ul > li a {
color: red;
#at-root #{selector-nth(&, -2, append-class, '.baz')} {
color: blue;
}
}
}
Output:
.foo ul > li a, .bar ul > li a {
color: red;
}
.foo ul > li.baz a, .bar ul > li.baz a {
color: blue;
}
Insert a selector
This function also takes 2 arguments: the original selector and the selector you'd like to insert before it.
#function insert-selector($a, $b) {
#return $b $a;
}
.foo, .bar {
ul > li a {
color: red;
#at-root #{selector-nth(&, -2, insert-selector, '.baz')} {
color: blue;
}
}
}
Output:
.foo ul > li a, .bar ul > li a {
color: red;
}
.foo ul > .baz li a, .bar ul > .baz li a {
color: blue;
}
Remove a selector
Removing a selector is as simple as replacing your selector with an empty string.
#function remove-selector($sel) {
#return '';
}
.foo, .bar {
ul > li a {
color: red;
#at-root #{selector-nth(&, -2, remove-selector)} {
color: blue;
}
}
}
Output:
.foo ul > li a, .bar ul > li a {
color: red;
}
.foo ul > a, .bar ul > a {
color: blue;
}
TL;DR
Selectors are just a lists. Any list manipulation functions will work on it and you can loop over it to modify it as necessary.
So yeah, don't do it unless you really really really need to. If you've decided you still need it, I've packaged these functions up into the selector-nth library.
I made a mixin that solves this problem.
Github: https://github.com/imkremen/sass-parent-append
Example: https://codepen.io/imkremen/pen/RMVBvq
Usage (scss):
.ancestor {
display: inline-flex;
.grandparent {
padding: 32px;
background-color: lightgreen;
.parent {
padding: 32px;
background-color: blue;
.elem {
padding: 16px;
background-color: white;
#include parent-append(":focus", 3) {
box-shadow: inset 0 0 0 8px aqua;
}
#include parent-append(":hover") {
background-color: fuchsia;
}
#include parent-append("p", 0, true) {
background-color: green;
}
}
}
}
}
Result (css):
.ancestor {
display: inline-flex;
}
.ancestor .grandparent {
padding: 32px;
background-color: lightgreen;
}
.ancestor .grandparent .parent {
padding: 32px;
background-color: blue;
}
.ancestor .grandparent .parent .elem {
padding: 16px;
background-color: white;
}
.ancestor:focus .grandparent .parent .elem {
box-shadow: inset 0 0 0 8px aqua;
}
.ancestor .grandparent .parent:hover .elem {
background-color: fuchsia;
}
.ancestor .grandparent .parent p.elem {
background-color: green;
}

Rollover list with the first child already activated?

Sorry for my poor english, I'm french !
The first li is already in red, but I want classical rollover effect (only css)
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
</ul>
with
li:first-child { color: red; }
li:hover { color: red; }
ul:hover li:first-child { color: black; }
li:first-child:hover { color: red; }
The last line doesn't work : When my mouse is over 1111, he becomes black instead of stay red.
Look here please : http://jsfiddle.net/cP5rQ/3/
And thank you for advance.
You need to increase the specificity of your last rule enough so that it becomes at least equal to the specificity of the third rule; it will then override the third rule and the item will become red as it should.
Do this by writing the last rule as
ul:hover li:first-child:hover { color: red; }​
See it in action.
This does the trick. Is this what you wanted?
li:first-child { color: red; }
ul:hover li:first-child { color: black; }
li:hover { color: red; }
ul:hover li:first-child:hover { color: red; }​
http://jsfiddle.net/cP5rQ/6/

Resources