css odd and even selector not working - css

I'm creating a rating control made of half stars and I want to be able to select odd and even labels inside the .rating control. The selector shoudl look like this but it's not working here is my codepen check my html out while your there
.rating {
label:nth-child(odd)::before {} // not working
}
.rating {
label:nth-child(even)::before {} // not working
}
Full CSS:
#import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css);
html, body {
margin: 0;
height: 100%;
min-height: 100%;
}
body {
background: #272727;
}
.rating {
position: absolute;
display: inline-block;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
label {
font-size: 24px;
font-family: FontAwesome;
color: #afa302;
}
label.half_l::before {
content: '\f006';
display: inline-block;
width: 11px;
overflow: hidden;
}
label.half_r {
width: 12px;
position: relative;
overflow: hidden;
display: inline-block;
margin-right: 3px;
}
label.half_r::before {
content: '\f006';
display: inline-block;
left: -11px;
position: relative;
}
label {
float: right;
}
label:hover {
color: #fff239;
}
> input {
display: none;
}
label.half_l:hover:before,
label.half_l:hover ~ label.half_l:before {
content: '\f089';
color: #fff239;
}
label.half_l:hover ~ label.half_r::before {
content: '\f005';
color: #fff239;
}
label.half_r:hover:before {
content: '\f005';
color: #fff239;
}
label.half_r:hover ~ label.half_r::before,
label.half_r:hover ~ label.half_l:before {
content: '\f005';
color: #fff239;
}
input[type=radio]:checked ~ label.half_l:before,
input[type=radio]:checked ~ label.half_r:before{
content: '\f005';
}
}

Use nth-of-type instead of nth-child
label:nth-of-type(odd) {
background-color:red;
}
nth-child looks for all children, regardless their type, where nth-of-type looks for a certain type

If to use the nth-child selector you need to bypass the input's since it count all children no matter their type
The nth-child(4n+4) start from the 4:th element (your second label) and then counts to every 4:th and apply the rule, which in your case will be every even label
The nth-child(4n+2) start from the 2:nd element (your first label) and then counts to every 4:th and apply the rule, which in your case will be every odd label.
Note, one can also use nth-child(4n) instead of nth-child(4n+4), which will start from the 0:th element (which does not exists) and then counts to every 4:th.
.rating {
label:nth-child(4n+4)::before {
background: yellow;
}
}
.rating {
label:nth-child(4n+2)::before {
background: blue;
}
}
Updated codepen

Related

Add style to multiple element on hover - scss

I currently have this code which turns the footer titles and subtitle white when a footer cell is hovered over, and it works:
.footer-cell {
position: relative;
display: table;
height: 160px;
&:hover .footer-title { // footer-title line
color: white;
}
&:hover .footer-subtitle { // footer-subtitle line
color: white;
}
}
Is there any way that I can combine the footer-title line and the footer-subtitle line so I dont have duplicate code? I tried this but it doesn't work:
.footer-cell {
position: relative;
display: table;
height: 160px;
&:hover .footer-title, .footer-subtitle {
color: white;
}
}
Just wrap the selectors in the :hover class:
.footer-cell {
position: relative;
display: table;
height: 160px;
&:hover{
.footer-title, .footer-subtitle {
color: white;
}
}
}
Compiles to this

In LESS, is it possible to import one selector's content into another one?

My goal is to import the content: '\e826'; from an icon class into another selector in case that content property changes in the future.
.icon-hi:before {content: '\e826';}
.panel {
background: white;
.panel-title {
&:before {
#include .icon-hi;
text-align: center;
width: 20px;
height: 20px;
}
}
}
Of course #import doesn't work for that, but is there another way?
For the purpose of defining a value in one place, you should use variables:
#icon-hi: '\e826';
.icon-hi:before {content: #icon-hi;}
.panel {
background: white;
.panel-title {
&:before {
content: #icon-hi;
text-align: center;
width: 20px;
height: 20px;
}
}
}
You can actually 'import one selector into another'. This is basically what mixins do. These are the first two features in the less documentation - http://lesscss.org/features/
A third option is to use the extend feature: http://lesscss.org/features/#extend-feature
You can, here's the example:
.icon-hi{
&:before{
content: '\e826';
}
}
.panel {
background: white;
.panel-title {
.icon-hi;
&:before {
text-align: center;
width: 20px;
height: 20px;
}
}
}
You have to define .icon-hi class and define before with nesting so the preproccessor can know what to fetch.

Change display of multiple classes on psuedo class hover

This is my scss file
.image-container {
position: relative;
.delete-image {
display: none;
position: absolute;
top: 0px;
right: 0px;
}
.make-primary {
display: none;
position: absolute;
top: 0px;
right: 97px;
}
&:hover .delete-image {
display: block;
}
}
I want both .make-primary and .delete-image to have their display attribute be changed to block on hover.
I tried:
&:hover .delete-image .make-primary{
display: block;
}
and
&:hover .delete-image, .make-primary {
display: block;
}
The first one, shows neither element, and the second will show .delete-image on hover and the .make-primary is always shown. Neither of these are showing the .make-primary element on hover.
What is the correct syntax? Thanks
Either put both of the class selectors inside the &:hover:
&:hover{
.delete-image, .make-primary {
display: block;
}
}
That will compile to this
Or add &:hover in front of the second class:
&:hover .delete-image, &:hover .make-primary {
display: block;
}
With the same output.

How to Add flexibility to SASS for another color

I've got some Sass I've inherited that looks like below. I want to be able to specify a CSS tag to differentiate between green and another color (see anchor tag and comment).
Now, I have-
<div class="names"></div>
The link shows green. I want to be able do something like-
<div class="names myblue"></div>
And instead have it be a different color.
&.SpeakerCount3 {
.names {
text-align: center;
li {
text-align: center;
display: inline-block;
width: 82px;
margin-left: 5px;
&:first-child {
margin-left: 0;
}
}
img {
max-width: 100%;
}
h3 {
margin-top: 0;
a {
font-size: 10px;
}
}
}
}
.names {
min-height: 180px;
.photo {
margin-top: -21px;
}
img {
display: block;
border: 3px solid #282828;
margin: 0 auto;
}
h3 {
margin-top: 5px;
}
a {
font-size: 20px;
color: #5c5c5c; // this was green but I could not figure how to make it orange for css and green for kids
text-decoration: none;
}
}
.description {
margin-bottom: 15px;
min-height: 120px;
h3 {
margin: 5px 0 20px 0;
min-height: 40px;
}
}
Having seen the HTML code that was being hidden in your question, I should say that good class names generally should relate to state rather than properties - so the class name "myblue" should probably be replaced with something like "featured", "highlighted" etc. This is especially the case where you are asking for "myblue" to actually change the colour to Orange - something that may well confuse future maintainers. In the case that "myblue" is a company or feature name it may well be legitimate, but I would consider carefully if there is an alternative class name which does not include a colour name.
In Sass you could do something like-
a {
font-size: 20px;
color: #5c5c5c; // this was green but I could not figure how to make it orange for css and green for kids
text-decoration: none;
.myblue & {
color: orange;
}
}
As the "a" selector is contained within the ".names" selector though, this will result in a rendered rule of-
.myblue .names a {
color: orange;
}
As "names" is not a descendant of "myblue" in your DOM, the selector will not match - and this isn't what you want.
If you only want the rule to apply where both "names" and "myblue" are present I would write this-
.names {
min-height: 180px;
.photo {
margin-top: -21px;
}
img {
display: block;
border: 3px solid #282828;
margin: 0 auto;
}
h3 {
margin-top: 5px;
}
a {
font-size: 20px;
color: #5c5c5c; // this was green but I could not figure how to make it orange for css and green for kids
text-decoration: none;
}
&.myblue {
a {
color: orange;
}
}
}
The ampersand produces a combined selector, rather than the descendant selector you would get with a space (this is Sass only - not valid CSS).
Alternatively, if you want the "myblue" class selector to apply even without the "names" class, then simply do this-
.names {
min-height: 180px;
.photo {
margin-top: -21px;
}
img {
display: block;
border: 3px solid #282828;
margin: 0 auto;
}
h3 {
margin-top: 5px;
}
a {
font-size: 20px;
color: #5c5c5c; // this was green but I could not figure how to make it orange for css and green for kids
text-decoration: none;
}
}
.myblue {
a {
color: orange;
}
}
As the "myblue" selector appears after the "names" selector, the color property for the link will override the color set in "names" - leaving all other properties for the link and other elements intact. This solution simply utilises the CSS cascade to achieve the desired effect.

CSS - difficulty with custom check boxes between IE and Firefox

I have written some code to help "skin" checkboxes and radio buttons using only CSS. It works very, very well ...
.... in Chrome.
However in FireFox and IE, it just ...fails outright. And I have absolutely no earthly idea why. The basic gist of it is that it loads a block using :before before the content and then places it over the default element. Of course it will be replaced with a sprite, but I have to get the outlaying behavior to function first. The code works like this; The way it is laid out in HTML is because I am using Bootstrap, and I am just adhering to the way it lays form fields out. I also have a Fiddle to demonstrate the problem.
Samples
jsBin
Includes the original LESS content.
jsFiddle
Only compiled CSS
HTML
<div class="checkbox">
<label>
<input type="checkbox" value="">
<span style="font-size: 24px;">Option</span>
</label>
</div>
LESS/CSS
.checkbox, .radio {
position: relative;
& + .checkbox {
margin-top: 10px;
&.pull-left {
left: 6px;
}
}
& + .radio {
margin-top: 10px;
left: 20px;
}
input[type="checkbox"] {
&:active, &:hover, &:focus {
&:before,
&::before {
background: yellow;
}
}
&:checked,
&:active:checked,
&:hover:checked,
&:focus:checked {
&:before, &::before {
background: green;
}
}
}
input[type="radio"] {
&:active:before,
&:hover:before,
&:focus:before {
background: yellow;
}
&:checked:before,
&:active:checked:before,
&:hover:checked:before,
&:focus:checked:before {
background: green;
}
}
input[type="radio"] {
&:before, &::before {
opacity: 1;
position: absolute;
content: "";
display: block;
background: black;
height: 24px;
width: 24px;
top: 2px;
}
}
input[type="checkbox"] {
&:before, &::before {
opacity: 1;
position: absolute;
content: "";
display: block;
background: black;
height: 24px;
width: 24px;
top: 2px;
}
}
label {
line-height: 24px;
padding-left: 10px;
}
}
Old browsers unfortunately aren't able to style radio buttons. What you should do is to use a plugin like http://fronteed.com/iCheck/ which automatically creates div based checkboxes that you can style on your own and clicking on those sync with the actual checkboxes.

Resources