How to simplify my less file without repeating statement with different value? - css

There are five less statements, and they're all the same except the value for padding-right.
Instead of repeating the statement five times, is there a way to simplify it into one statement?
h1 {
a[href^="http://"], a[href^="https://"] {
&:hover {
background: url(../../resources/icon/external-link-alt.svg) no-repeat
right;
padding-right: 100px;
}
}
}
h3 {
a[href^="http://"], a[href^="https://"] {
&:hover {
background: url(../../resources/icon/external-link-alt.svg) no-repeat
right;
padding-right: 50px;
}
}
}
h4 {
a[href^="http://"], a[href^="https://"] {
&:hover {
background: url(../../resources/icon/external-link-alt.svg) no-repeat
right;
padding-right: 50px;
}
}
}
h5 {
a[href^="http://"], a[href^="https://"] {
&:hover {
background: url(../../resources/icon/external-link-alt.svg) no-repeat
right;
padding-right: 25px;
}
}
}

Use mixins to reuse and not repeat the line of code.
Mixins are a way of including ("mixing in") a bunch of properties from one rule-set into another rule-set.
Exemple:
item {
a[href^="http://"], a[href^="https://"] {
&:hover {
background:
url(../../resources/icon/external-link-alt.svg)
no-repeat
right;
}
}
}
And we want to use these properties inside other rule-sets. Well, we just have to drop in the name of the class where we want the properties, like so:
h1 {
item();
padding-right: 100px;
}
h3 {
item();
padding-right: 75px;
}
h4 {
item();
padding-right: 50px;
}
h5 {
item();
padding-right: 25px;
}
This is very helpful if you want to change something in the future, as you only need to modify the mixins in one place 😉.

Related

Is it possible to put duplicate style in a .less component

Is it possible to put certain css style in a component and reuse it in different locations? In the example below, I am repeating the same style for .navigation class:
.container-1 {
.navigation {
width: 100%;
}
}
#media (max-width:991px) {
.container-1 {
.navigation {
margin-top: 0px; // <-- repeated
background-color: #252525; // <-- repeated
width: 250px; // <-- repeated
}
}
}
.container-2 {
.navigation {
margin-top: 0px; // <-- repeated
background-color: #252525; // <-- repeated
width: 250px; // <-- repeated
}
}
In less you can use Mixins for this:
.navigation-styles {
margin: 0;
padding: 0;
list-style: none;
}
#media (max-width:991px) {
.container-1 {
.navigation {
.navigation-styles();
}
}
}
.container-2 {
.navigation {
.navigation-styles();
}
}
Please take a look at the doc here

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

:extend() in nested block

This code:
.first {
margin: 19px;
.nested {
color: white;
}
}
.second:extend(.first) {
}
outputs:
.first,
.second {
margin: 19px;
}
.first .nested {
color: white;
}
But if you wrap it in another block:
div {
.first {
margin: 19px;
.nested {
color: white;
}
}
.second:extend(.first) {
}
}
Outputs:
div .first {
margin: 19px;
}
div .first .nested {
color: white;
}
disregards extend? Is this a bug?
From the comment above by #seven-phases-max
No, it's not a bug. :extend is not relative to the selector it's used with; it always requires a complete ("absolute") selector "path". I.e. it should be .second:extend(div .first) no matter where the .second itself is located.
div {
.first {
margin: 19px;
.nested {
color: white;
}
}
.second:extend(div .first) {}
}

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

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);
}

Resources