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

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

Related

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

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 😉.

Convert & symbol in scss to less

I have to convert some SCSS files to LESS. For most part it is just case of changing $ with # but there are style that use the scss parent selector & that I don't know how to convert.
Here is example
// Sidebar
.sidebar {
.block {
&.newsletter {
.btn {
&:before {
background: transparent;
}
}
}
&.filter {
ol {
li {
a {
color: #blue;
&:before {
display: none;
}
}
}
}
}
.filter-options-title, .block-title {
color: #444;
padding-bottom: 10px;
font-size: 12px;
&:after {
color: #666;
}
}
}
}
How would I replace out those parent selectors to make it the same generated CSS?
The & parent selector is actually the same syntax in Less and SCSS!
From the Less Documentation on Parent Selectors:
The & operator
represents the parent selectors of a nested rule and is most commonly
used when applying a modifying class or pseudo-class to an existing
selector
In comparison, here's the SASS/ SCSS documentation on parent selectors for pseudo classes: http://sass-lang.com/documentation/Sass/Selector/Pseudo.html
So in the case of your code, it would be:
SCSS
$blue: blue;
.sidebar {
.block {
&.newsletter {
.btn {
&:before {
background: transparent;
}
}
}
&.filter {
ol li a {
color: $blue;
&:before {
display: none;
}
}
}
.filter-options-title, .block-title {
color: #444;
padding-bottom: 10px;
font-size: 12px;
&:after {
color: #666;
}
}
}
}
(try compiling/ validating here: https://www.sassmeister.com/)
LESS
#blue: blue;
.sidebar {
.block {
&.newsletter {
.btn {
&:before {
background: transparent;
}
}
}
&.filter {
ol li a {
color: #blue;
&:before {
display: none;
}
}
}
.filter-options-title, .block-title {
color: #444;
padding-bottom: 10px;
font-size: 12px;
&:after {
color: #666;
}
}
}
}
(try compiling/ validating here: http://winless.org/online-less-compiler)
As well as the official documentation, this article on CSS Tricks is helpful too: https://css-tricks.com/the-sass-ampersand
Hope that helps :)

Sass deduplicate #imports

I'm trying to create two themes for my project. I have following setup:
styles
globals
mixins
helper
themes
Now every theme has an index.scss:
#import "../../mixins/index";
#import "./colors";
#import "./breakpoints";
#import "./typography";
#import "core";
And every theme has a _core.scss:
#if import-once('core.scss') {
:global {
html, body {
background-color: $grey-page-background;
height: 100%;
}
body {
color: $grey-text-primary;
font-family: $font-family-standard;
}
body.page-body.modal-overflow-hidden {
overflow: hidden;
}
.container {
padding: 0;
max-width: 1200px;
margin-left: auto;
margin-right: auto;
width: 100%;
#include breakpoint(large down) {
padding: 0 10px;
}
}
.no-margin {
margin: 0 !important;
}
.text-center {
text-align: center;
}
.green {
color: $green-smava-primary;
}
a:focus, a:hover, a:active {
color: inherit;
}
/* vb = vertical align block, for supporting browser dont support flex-box well */
.vb {
text-align: left;
}
.vb:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
/* vc = vertical align center child, for supporting browser dont support flex-box well */
.vc {
display: inline-block;
vertical-align: middle;
}
.ui.list {
list-style-type: none;
margin: 1em 0;
padding: 0;
.item {
table-layout: fixed;
list-style-type: none;
list-style-position: outside;
padding: .21428571em 0;
line-height: 1.14285714em;
}
}
.ui.list.large {
font-size: 1.14285714em;
}
}
}
As you can see -> index imports core -> and now the theme is imported to the according component (we have a versioning system for components - so this approach is good here).
So a component scss can look like this then:
#import '~styles/theme/smava/index';
.dialog {
&-input {
margin: 0 0 10px 0;
}
&-action {
border-top: 1px solid $grey-shadow-block;
float: right;
}
&-button {
&-pass {
margin-right: 30px;
}
&-login {
margin: 0;
}
}
}
Since I have multiple components core.scss gets imported multiple times.
The problem is, that I need to set a color for the body - this is the reason I have this core.scss.
So how can i deduplicate this? The approach with importing the theme has to stay the same unfortunately.
My stack:
React/Webpack/Redux/Node-sass

Sass to css output

I think this is the way to do it but my css output is not what I was expecting:
SOURCE CODE
This is my scss file:
footer.page-footer
{
margin-top: 0;
&,
nav
{
background-color: $blue;
}
}
This is the css output:
footer.page-footer
{
margin-top: 0;
}
footer.page-footer,
footer.page-footer nav
{
background-color: #50a4b1;
}
How can I make the second outputted css's selector be simply footer.page-footer, nav instead of footer.page-footer, footer.page-footer nav?
You can use the #at-root directive to produce a rule that is generated outside its definition scope but that retains the value of its parent (&)
footer.page-footer {
margin-top: 0;
#at-root {
#{&},
nav {
background-color: blue;
}
}
}
Output:
footer.page-footer {
margin-top: 0;
}
footer.page-footer,
nav {
background-color: blue;
}
<p class="sassmeister" data-gist-id="93b3b22a2888f2f5f86b" data-height="480" data-theme="tomorrow">Play with this gist on SassMeister.</p><script src="http://cdn.sassmeister.com/js/embed.js" async></script>
Sassmeister

LESS CSS - Different elements in a function

I use LESS CSS. My code looks like this.
Repeatable pattern
Do you see the pattern in my code? The only thing that differs the two is the padding value and the class name.
Question
Is it possible in LESS CSS to make a function / mixin of a block like this with many different elements?
LESS CSS
&.pad-10 > [class*='cols-'] {
background: #ccc;
padding: 10px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
&.pad-20 > [class*='cols-'] {
background: #ccc;
padding: 20px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
Mixin suggestion
do_padding( $value ) {
&.pad-#value > [class*='cols-'] {
background: #ccc;
padding: #valuepx;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
do_padding( 10 );
do_padding( 20 );
I know that my exact problem can be solved in other ways without LESS CSS, but I have this problem from time to time.
Yes, you just need to set up a proper counting and looping structure in LESS. Here's how:
LESS
.do_padding(#startValue, #increment) {
.loop(#value) when (#value > 0) {
//set top amount
&.pad-#{value} > [class*='cols-'] {
background: #ccc;
padding: #value * 1px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
// next iteration
.loop(#value - #increment);
}
// end the loop when index is 0 or less
.loop(#value) when not (#value > 0) {}
//start the loop
.loop(#startValue);
}
Use it
.myClass {
.do_padding(30, 10);
}
CSS Output
.myClass.pad-30 > [class*='cols-'] {
background: #ccc;
padding: 30px;
}
.myClass.pad-30 > [class*='cols-']:first-child {
padding-left: 0;
}
.myClass.pad-30 > [class*='cols-']:last-child {
padding-right: 0;
}
.myClass.pad-20 > [class*='cols-'] {
background: #ccc;
padding: 20px;
}
.myClass.pad-20 > [class*='cols-']:first-child {
padding-left: 0;
}
.myClass.pad-20 > [class*='cols-']:last-child {
padding-right: 0;
}
.myClass.pad-10 > [class*='cols-'] {
background: #ccc;
padding: 10px;
}
.myClass.pad-10 > [class*='cols-']:first-child {
padding-left: 0;
}
.myClass.pad-10 > [class*='cols-']:last-child {
padding-right: 0;
}

Resources