Making use of CSS vs Sass (SCSS) - base class issues and redundency - css

I'm trying to clean up my CSS to be cleaner by using SCSS.
Standard CSS:
.dark-hr,
.light-hr {
width: 100%;
height: 1px;
margin: 15px 0px;
}
.dark-hr {
background-color: #595959;
}
.light-hr {
background-color: #cccccc;
}
vs SCSS:
.generic-hr {
width: 100%;
height: 1px;
margin: 15px 0px;
}
.dark-hr {
#extend .generic-hr;
background-color: #595959;
}
.light-hr {
#extend .generic-hr;
background-color: #cccccc;
}
Is there any way to avoid creating the 'generic-hr' class that won't be used? I was hoping that some kind of nest would work well.
In this scenario the CSS is definitely way cleaner and more readable than SCSS.
Ideally I would need this to work in SCSS:
.## {
// base class that is not outputted
.dark-hr {
//attributes the extend the base class '.##'
}
.light-hr {
//attributes the extend the base class '.##'
}
}
OUTPUT:
.dark-hr, .light-hr {
//shared attributes defined by '.##'
}
.dark-hr {
// overrides
}
.light-hr {
// overrides
}

What you're wanting to use is an extend class (I call them "silent classes"), which is signified by using a % instead of a ..
hr%base {
width: 100%;
height: 1px;
margin: 15px 0px;
}
.dark-hr {
#extend hr%base;
background-color: #595959;
}
.light-hr {
#extend hr%base;
background-color: #cccccc;
}

Wouldn't you normally do something like this:
.generic-hr {
width: 100%;
height: 1px;
margin: 15px 0px;
&.dark {
background-color: #595959;
}
&.light {
background-color: #cccccc;
}
}

My pattern for this kind of thing is a mixin:
#mixin generic-hr {
width: 100%;
height: 1px;
margin: 15px 0px;
}
.dark-hr {
#include generic-hr;
background-color: #595959;
}
.light-hr {
#include generic-hr;
background-color: #cccccc;
}
This has the added advantage of being extensible, so if you find yourself needing several selectors with really similar properties you can add in variables:
#mixin generic-hr($background-color: transparent) {
width: 100%;
height: 1px;
margin: 15px 0px;
background-color: $background-color;
}
.dark-hr {
#include generic-hr(#595959);
}
.light-hr {
#include generic-hr(#cccccc);
}
.medium-hr {
#include generic-hr(#818181);
}

Related

How to nest SCSS with "&" properly to re-use immediate parent (partial) class name?

I want to re-use the class name of the parent and use it on a child element, but it is not working as expected when nesting more than one level.
I want to concatenate the child class name only with the immediate parent string and not the whole concatenated parent.
I am starting to believe this is not possible.
The SCSS:
.block {
margin: 2px;
& &__element {
margin: 3px;
&-nested {
margin: 4px;
}
}
}
The output:
.block {
margin: 2px;
}
.block .block__element {
margin: 3px;
}
.block .block__element-nested {
margin: 4px;
}
The desired output:
.block {
margin: 2px;
}
.block .block__element {
margin: 3px;
}
.block .block__element .block__element-nested {
margin: 4px;
}
Bro, currently nested-& is not supported in Sass. Hopefully, that's the only solution:
.block {
margin: 2px;
& &__element {
margin: 3px;
}
& &__element &-nested {
margin: 4px;
}
}
EDIT
To achieve your desired output you may do this.
.block {
margin: 2px;
& &__element {
margin: 3px;
}
& &__element &__element-nested {
margin: 4px;
}
}
EDIT 2
.block {
margin: 2px;
& &__element {
margin: 3px;
& .block__element-nested {
margin: 4px;
}
}
}
Output:
.block {
margin: 2px;
}
.block .block__element {
margin: 3px;
}
.block .block__element .block__element-nested {
margin: 4px;
}
In my opinion, your desired output doesn't make sense because it's very confusing on a larger scale. The bottom example is from the docs. The point is not to go deeper than the third level I think...
.block {
background: red;
&__element {
background: red;
&--nested {
background: red;
}
}
}
.block {
background: red;
}
.block__element {
background: red;
}
.block__element--nested {
background: red;
}
Here 2 solution that are working fine with the use of selector-nest.
You will find more information: https://sass-lang.com/documentation/modules/selector#nest
You can test solution here: https://www.sassmeister.com
Method 1:
.block {
margin: 2px;
& &__element {
margin: 3px;
#{selector-nest('.block__element', '&-nested')} {
margin: 4px;
}
}
}
Method 2:
.block {
margin: 2px;
#{selector-nest('.block', '&__element')}{
margin: 3px;
#{selector-nest('.block__element', '&-nested')} {
margin: 4px;
}
}
}
Apparently this can not be done. As described here as well:
https://css-tricks.com/the-sass-ampersand/#what-the-isnt
My intention was for the & to only get replaced with .parent in hopes of compiling to this:
.parent .child {}
But that doesn’t work.
The & is always the fully compiled parent selector.

merge #extend with parent style and make one class name

I'm trying to merge the style into one class but its showing an error. Look at the example below.
%banner-style{
banner {
padding: 140px 0 210px;
background: url(https://im2.ezgif.com/tmp/ezgif-2-92c6382d82ba.jpg) top center/cover no-repeat;
&.row {
margin: 0;
}
.main-heading {
font-size: 40px;
letter-spacing: -1px;
font-weight: 600;
padding-right: 20px;
sup {
font-size: 10px;
vertical-align: super;
}
}
}
}
And I want it to merge with the parent class .parent
.parent{
color: red;
&_#extend %banner-style;
}
using & to merge into one class name. but showing error unless i do this
.parent{
color: red;
&_{#extend %banner-style};
}
Which is same as if I remove &_.
I wanted .parent_banner {...} but instead got .parent_ banner{...};
Does anyone know how I can accomplish this?
You are getting exactly what is supposed to happen. Extend does not "merge" classes, it extends another class/placeholder into a new selector's styles.
What that means is if I write:
%banner-style {
background: black;
}
.parent {
#extend %banner-style;
}
.other-selector {
#extend %banner-style;
color: red;
}
The css I get will be
.parent {
background: black;
}
.other-selector {
color: red;
background: black;
}
So you are getting expected results. If you'd like to make this "work" the way you want, you can just change your code to:
%banner-style {
padding: 140px 0 210px;
background: url(https://im2.ezgif.com/tmp/ezgif-2-92c6382d82ba.jpg) top center/cover no-repeat;
&.row {
margin: 0;
}
.main-heading {
font-size: 40px;
letter-spacing: -1px;
font-weight: 600;
padding-right: 20px;
sup {
font-size: 10px;
vertical-align: super;
}
}
}
.parent{
color: red;
&_banner {
#extend %banner-style;
};
}
Note: I took out the banner block because it seems you don't want that (and banner isn't a normal html element).

LESS puts spaces in wrong places

So... I'am creating a small bootstrap and i want it efficiently done, so i've chose the LESS to do some job for me. And i found that LESS compiler puts spaces between classes when it is written like this:
div.cb {
input[type="text"] {
border: 1px #d9d9d9 solid;
height: 15px;
padding: 5px;
.large {
width: 250px;
}
.medium {
width: 150px;
}
.small {
width: 50px;
}
.fill {
width: 100%;
}
}
}
results in:
div.cb input[type="text"] {
border: 1px #d9d9d9 solid;
height: 15px;
padding: 5px;
}
div.cb input[type="text"] .large {
width: 250px;
}
div.cb input[type="text"] .medium {
width: 150px;
}
div.cb input[type="text"] .small {
width: 50px;
}
div.cb input[type="text"] .fill {
width: 100%;
}
and the gaps between the element and classes prevents in my browser (chrome) in the correct processing. Is there a way to have same or similar code in LESS and have right outputting CSS? Without those gaps...
With less you can reference the parent of a code block by using &
So this:
.class
{
.anotherClass
{
background: red;
}
}
Compiles to:
.class .anotherClass { background: red; }
Whereas this:
.class
{
&.anotherClass
{
background: red;
}
}
Compiles to this:
.class.anotherClass { background: red; }
I hope that makes the difference obvious

how to write set of styles as a function in compass sass

I've set of styles which I want to use in multiple places in my CSS.
Here is my function:
#function form-element-dimension{
height: 34px;
padding: 3px 10px;
line-height: 18px;
border: solid 1px #e2e7eb;
}
I will use this function anywhere in my .scss page like below:
.dataTables_length{
select{
form-element-dimension();
}
}
---
---
.contact-form-style{
input{
form-element-dimension();
}
}
How to do this in COMPASS SASS framework?
Although it's really not the best way to do what you're doing, this is how you'd achieve it with sass;
#mixin form-element-dimension {
height: 34px;
padding: 3px 10px;
line-height: 18px;
border: solid 1px #e2e7eb;
}
.dataTables_length {
select {
#include form-element-dimension();
}
}
.contact-form-style {
input {
#include form-element-dimension();
}
}

How to make Sass mixin that extends parent?

You could hard-code extending a selector in Sass like:
.box {
width: 100px;
height: 100px;
color: red;
}
.box-green {
#extend .box;
color: green;
}
And then .box-green has all the properties of .box, with its own additional ones. What I want to do is write a generic mixin that does that - takes a class, adds all its properties with its own and adds a modifier to the class name. If something like this pseudo-code worked (which it doesn't), it would be ideal.
.box {
width: 100px;
height: 100px;
color: red;
#include make-modifier(&, green) {
color: green;
}
}
#mixin make-modifier(parent, modifier-name) {
.#{$parent}-#{$modifier-name} {
#content;
}
}
Is there a way to do it? Even if only in the latest version it's fine.
I would suggest a simpler solution like this
#mixin box($color:"") {
width: 100px;
height: 100px;
color: red;
#if $color !="" {
&-#{$color} {
color: $color;
}
}
}
.box {
#include box(green);
}
The output will be:
.box {
width: 100px;
height: 100px;
color: red;
}
.box-green {
color: green;
}
An example: http://sassmeister.com/gist/04cb6a6fe14972c3ffe4

Resources