Sass with BEM, inherit selector - css

I'm using Sass 3.4.1 and BEM so my scss is:
.photo-of-the-day{
&--title{
font-size: 16px;
}
}
and I want every time hover over .photo-of-the-day something happen with title, that's pretty common so usually in css:
.photo-of-the-day:hover .photo-of-the-day--title{
font-size:12px
}
the thing is using BEM this is the only way I found and looks kinda ugly
.photo-of-the-day{
&--title{
font-size: 16px;
}
&:hover{
background: red;
/* this is ugly */
.photo-of-the-day--title{
text-decoration: underline;
}
}
}
so I was wondering if I can inherit .photo-of-the-day selector and use it inside the hover to avoid copy again the full selector.
Ideally would be something like:
.photo-of-the-day{
&--title{
font-size: 16px;
}
&:hover{
background: red;
&&--title{
text-decoration: underline;
}
}
}
Or something close to comeback to the parent selector for BEM. Is it possible?

If you insist on nesting everything, the best you can do is this:
.photo-of-the-day {
$root: &;
&--title{
font-size: 16px;
}
&:hover{
#{$root}--title {
text-decoration: underline;
}
}
}

You can use this syntax:
.photo-of-the-day {
&--title {
font-size: 16px;
}
&:hover &--title {
text-decoration: underline;
}
}

Related

Why does SASS compile unwanted / unused code

I am learning SASS and trying out some examples. I have some problem understanding Selector Sequence and why SASS merges them.
In a real world scenario the output can have unwanted css. For eg:-
a{
color: #0086B3;
&:hover{
text-decoration: none;
}
}
#footer a{
color: #a61717;
}
.head-links{
#extend a;
font-weight: bold;
}
This block of code complies to :-
a, .head-links {
color: #0086B3;
}
a:hover, .head-links:hover {
text-decoration: none;
}
#footer a, #footer .head-links {
color: #a61717;
}
.head-links {
font-weight: bold;
}
The problem is that
#footer .head-links
might never be used. So what is the point of merging selector sequence if it is not required.
How can I avoid this.How can I make it extend only :-
a{
color: #0086B3;
&:hover{
text-decoration: none;
}
}
Would that require me using a class instead...
because you are extending the element a here:
#extend a;
if you remove it, then the SASS won't "merge" them.
you have footer a and when extending the a in .head-links it will add #footer .head-links to the already existing rule #footer a
Which means it will extend to ANY a in the CSS, not just the selector a alone
UPDATE
How can I avoid this.How can I make it extend only :-
a{
color: #0086B3;
&:hover{
text-decoration: none;
}
}
Would that require me using a class instead...
yes you would need to use a class or an ID for that.
something like this:
.uniqueclass{
color: #0086B3;
&:hover{
text-decoration: none;
}
}
here is a SASS demo

LESS resusable nested classes

Lets say that I have the following:
.class-1 {
font-weight: bold;
p{
color: red;
}
}
And I want to define in LESS a class-2 that has the same styling with the p element in the class-1. Is there any way to do so other than writing the code?
if I understand you correctly, you want to style your p if it's the child of class-1 or class-2. but class-1 and class-2 should have different styling.
I'd recommend writing it out twice or a different approach, but you can use mixins if you don't want to write it out twice.
LESS
.p() {
color:red;
}
.class-1 {
font-weight: bold;
p{
.p;
}
}
.class-2{
p{
.p;
}
}
CSS output
.class-1 {
font-weight: bold;
}
.class-1 p {
color: red;
}
.class-2 p {
color: red;
}
.class-1, .class-2 {
font-weight: bold;
p{
color: red;
}
}

How to refer css style from another?

Here's the sample:
.my-class {
font-size: 12px;
}
.my-another-class {
/* here I want to include .my-class style */
.my-class;
border: 0;
}
Can I include one css class into another or not?
You can define multiple targets for the .my-class rule, then specify further rules just for .my-another-class:
.my-class,
.my-another-class {
font-size: 12px;
}
.my-another-class {
border: 0;
}
You can even then override certain properties, for example
.my-class,
.my-another-class {
color: red;
font-size: 12px;
}
.my-another-class {
border: 0;
color: blue; /* overrides color: red; on .my-another-class */
}
You can't use a construction like this in plain CSS.
Preprocessors such as Less and Sass support this behaviour with mixins.
You can't, but you can do something like this:
.my-class, .my-another-class{
font-size: 12px;
}
.my-another-class {
border: 0;
}

CSS comments in nested LESS rules

How can I add CSS comments in LESS nested rules? Ex:
div{
span{
font-size: 16px;
color: #fff;
}
/*This is my comment*/
em{
color: blue;
}
}
This is the output I expect to get:
div span {
font-size: 16px;
color: #fff;
}
/*This is my comment*/
div em {
color: blue;
}
But, unfortunatelly this is how it is processed:
div {
/*This is my comment*/
}
div span {
font-size: 16px;
color: #fff;
}
div em {
color: blue;
}
Is it possible to make this?
This isn't possible using /* */.
The reason being that it is still under the div scope, so it won't work using /* */ comments.
However, in LESS you can use // for single line comments which doesn't go through the compiler (so doesn't end up in the compiled CSS code but will be in the LESS code).
Here is the official documentation on comments.
Well, you can get your comment inside nested rules:
div {
em {
/* This is my comment */
color: blue;
}
}
output:
div em {
/* This is my comment */
color: blue;
}
I hope this would be useful for you.
/*This is my comment*/
div {
em {
color: blue;
}
span {
font-size: 16px;
color: #fff;
}
}
and the output will be,
/*This is my comment*/
div em {
color: blue;
}
div span {
font-size: 16px;
color: #fff;
}
More or less it would be like what you are expecting !!!

CSS styling links using id's and classes

Is there a way of styling links using a id or a class without having to create a new selector for each individual element? for example
something like this or close to this would be preferable
#logo {
a: link {color: black}
a: visited{color: black}
a: hover{color: black}
}
However, the above syntax does not work instead all i can find is
#logo a:hover {
color: black;
}
#logo a:visited {
color: white
}
I feel like there's an easier way than this.
Heres how to do it to all links
I believe it should work:
#logo a:link,
#logo a:visited,
#logo a:hover {
color: black;
}
Not all browser support the above methodology of separating the tag styles with class or ID when you are dealing with different style in CSS with tag in single page.
One can follow below method:
**If using ID with Field**
a:link#myID {
color: green;
background-color: transparent;
text-decoration: none;
}
a:visited#myID {
color: pink;
background-color: transparent;
text-decoration: none;
}
a:hover#myID {
color: red;
background-color: transparent;
text-decoration: underline;
}
a:active#myID {
color: yellow;
background-color: transparent;
text-decoration: underline;
}
Click Here
**If using Class with Field**
a:link.myClass {
color: green;
background-color: transparent;
text-decoration: none;
}
a:visited.myClass {
color: pink;
background-color: transparent;
text-decoration: none;
}
a:hover.myClass {
color: red;
background-color: transparent;
text-decoration: underline;
}
a:active.lx {
color: yellow;
background-color: transparent;
text-decoration: underline;
}
Click Here
Not directly in css, but there are some projects that extend css
Check out sass:
http://sass-lang.com
I also believe current CSS syntax is not all that optimal. My personal choice is to go with something like LESS where you get much more intuitive and compact syntax to style your work.
With pure CSS you must specify each pseudo-selector but you can group them to apply the same style attributes;
#logo a:link,
#logo a:visited,
#logo a:hover {
color: black;
}
Beware that The order of link pseudo-classes matters.

Resources