Prevent LESS mixins with duplicate pseudo classes from creating additional CSS definitions - css

I have created a number of mixins to speed up setting anchor properties for each state. In this example I have a mixin for text-decoration and another for background-color.
.link-text-decoration(#default, #hover, #active, #visited)
{
text-decoration: #default;
&:hover
{
text-decoration: #hover;
}
&:active
{
text-decoration: #active;
}
&:visited
{
text-decoration: #visited;
}
}
.link-background-color(#default, #hover, #active, #visited)
{
background-color: #default;
&:hover
{
background-color: #hover;
}
&:active
{
background-color: #active;
}
&:visited
{
background-color: #visited;
}
}
When rendering as CSS I find instead of merging the pseudo classes it redeclares another.
LESS CSS calling the Mixins
.link
{
.link-text-decoration(underline, none, none, underline);
.link-background-color(#fff, #ccc, #ddd, #fff);
}
The Result
There a 2 instances of hover, active and visited.
.link {
text-decoration: underline;
background-color: #ffffff;
}
.link:hover {
text-decoration: none;
}
.link:active {
text-decoration: none;
}
.link:visited {
text-decoration: underline;
}
.link:hover {
background-color: #cccccc;
}
.link:active {
background-color: #dddddd;
}
.link:visited {
background-color: #ffffff;
}
Desired Result
Ideally I would like the values to appear as below as this would be much more efficient.
.link {
text-decoration: underline;
background-color: #ffffff;
}
.link:hover {
text-decoration: none;
background-color: #cccccc;
}
.link:active {
text-decoration: none;
background-color: #dddddd;
}
.link:visited {
text-decoration: underline;
background-color: #ffffff;
}
I've played with the Extend function and the examples on CSS Tricks, but this does not seem to work for this scenario.
Any solution, guidance, or advice?
Thanks,

Related

CSS Selector :not is not overriding css from specified class

In my site I have a links with the target="_blank". On some of these links I want the cursor to be a pointer. On links with the class name "inline-link" I want it to be text. I updated the post with my entire CSS page.
However I cannot seem to override the css.
Here is my 'complete' css:
.grouped-link {
cursor: pointer;
}
.slideout-link {
span.show:hover {
color: $darkgrey;
}
}
.section-subtitle a, a.section-subtitle {
color: $darkgrey;
float: right;
text-transform: uppercase;
font-size: 16px;
font-weight: 400;
letter-spacing: 2px;
margin-top: 65px;
text-decoration: none;
border-bottom: 1px solid $darkgrey;
&:hover {
border-color: $midgrey;
color: $midgrey;
text-decoration: none;
}
}
.underline-link {
border-bottom: 1px solid $lightgrey;
cursor: pointer;
padding-bottom: 5px;
text-transform: uppercase;
width: 150px;
&.dark {
border-color: $grey;
color: $grey;
}
&:hover {
border-color: $midgrey;
color: $midgrey;
text-decoration: none;
}
&.light {
border-color: $upmidgrey;
color: $upmidgrey;
}
&.lightest {
color: $lightgrey;
}
}
.inline-link {
color: $grey;
cursor: text;
&:hover {
text-decoration: none;
cursor: text;
}
}
a[target="_blank"]:not(.inline-link):hover {
text-decoration: none;
cursor: pointer;
}
Here is my html:
<p> Text text text <a className="inline-link" href="http://www.link.com" target="_blank">text</a> text </p>
Unless you use React or some other system that require you to use className instead of class, basically this code works:
.inline-link {
color: grey;
cursor: text;
}
.inline-link:hover {
text-decoration: none;
cursor: text;
}
a[target="_blank"]:not(.inline-link):hover {
text-decoration: none;
cursor: pointer;
}
<p> Text text text <a class="inline-link" href="http://www.link.com" target="_blank">text</a> text </p>
<p> Text text text text text </p>

Does SASS support element specification as nested selector?

Let's say you have this SASS definition (unreal example):
.class {
margin: 1px;
background: black;
color: white;
&:hover {
color: red;
}
}
a.class {
margin: 1px;
background: black;
color: yellow;
&:hover {
color: blue;
}
}
Now, can we put the a specification of the same class as a nested selector? E.g. something like this (pseudo-code):
.class {
margin: 1px;
background: black;
color: white;
&:hover {
color: red;
}
// Some selector to show that the current class
// should be applied to this element (?)
a.& {
color: yellow;
&:hover {
color: blue;
}
}
}
I have a solution, it's a little bit tricky, but it works fine.
.class {
color: yellow;
&:hover {
color: blue;
}
&[href] {
color: white;
&:hover {
color: red;
}
}
}
You may consider to write a mixin
#mixin sample($color,$hovercolor) {
margin: 1px;
background: black;
color: $color;
&:hover {
color: $hovercolor;
}
}
.class{ #include sample(white,red)}
a{ #include sample(yello,yellow)}
Hope this helps

Use sass extended placeholder with additional classes

I made this sass placeholder for a default button and there should be additional buttons like a success or danger button.
This is my sass placeholder in short:
%button {
border: none;
background-color: $default-color;
cursor: pointer;
color: $default-color-text;
}
%button-danger {
#extend %button;
background-color: $default-color-danger;
color: $default-color-danger-text;
}
%button-success {
#extend %button;
background-color: $default-color-success;
color: $default-color-success-text;
}
Now i want to extend from these buttons and make an element with a class to a button and with additional classes to a danger/success button.
.button {
#extend %button;
&.danger {
#extend %button-danger;
}
&.success {
#extend %button-success;
}
}
The result is
.button.danger, .button.success, .button {
border: none;
background-color: #a0a0a0;
cursor: pointer;
color: #ffffff; }
.button.danger {
background-color: #d9534f;
color: #fff; }
.button.success {
background-color: #5cb85c;
color: #fff; }
Thats correct, but i think of a lot of different buttons and there could be a shorter way like that:
.button { /* only one class in this directive */
border: none;
background-color: #a0a0a0;
cursor: pointer;
color: #ffffff; }
.button.danger {
background-color: #d9534f;
color: #fff; }
.button.success {
background-color: #5cb85c;
color: #fff; }
Is there a way to compile this result, or is that not recommendable?
You can remove the extend from %button-danger and %button-success.
%button {
border: none;
background-color: white;
cursor: pointer;
color: white;
}
%button-danger {
background-color: red;
color: red;
}
%button-success {
background-color: green;
color: green;
}
.button {
#extend %button;
&.danger {
#extend %button-danger;
}
&.success {
#extend %button-success;
}
}

Is it possible to return selectors with a stylus mixin

Recently I have been trying out stylus after been using scss for quite some time. I have though not found a way to write the following scss with the stylus syntax. Does anyone have any solution to this. Any thoughts very appreciated.
#mixin attention() {
&:hover,
&:active,
&:focus {
#content;
}
}
a {
font-weight: bold;
text-decoration: none;
color: #c00;
#include attention() {
outline: none;
color: #09f;
}
}
This is possible: https://learnboost.github.io/stylus/docs/mixins.html#block-mixins
attention() {
&:hover,
&:active,
&:focus {
{block}
}
}
a {
font-weight: bold;
text-decoration: none;
color: #c00;
+attention() {
outline: none;
color: #09f;
}
}

is it possible to put more than one CSS rule in a lesscss forloop?

Is it possible to put the following in a lessCSS forloop so that just the number of each section variable will update from section1 through to section4 with each loop?
// loop starts
.section1 {
.color {
color: #section1;
}
.colorBG-medium{
background-color: #section1;
}
.colorBG, .tab.active a {
background-color: #section1;
&:hover{
background-color: #section1;
}
}
}
// loop ends
thanks!
According to the link indicated by Roddy of the Frozen Peas, yes it is possible to do a loop, but it only makes sense to use it for numeric values​​. For your case, I recommend using the mixins, including to improve code readability:
#foo {
.bar (#color) {
.color { color: #color; }
.colorBG-medium {
background-color: #color;
}
.colorBG, .tab.active a {
background-color: #color;
&:hover{
background-color: #color;
}
}
}
}
.section1 {
#foo > .bar(red);
}
.section2 {
#foo > .bar(blue);
}
The result:
.section1 .color {
color: #ff0000;
}
.section1 .colorBG-medium {
background-color: #ff0000;
}
.section1 .colorBG,
.section1 .tab.active a {
background-color: #ff0000;
}
.section1 .colorBG:hover,
.section1 .tab.active a:hover {
background-color: #ff0000;
}
.section2 .color {
color: #0000ff;
}
.section2 .colorBG-medium {
background-color: #0000ff;
}
.section2 .colorBG,
.section2 .tab.active a {
background-color: #0000ff;
}
.section2 .colorBG:hover,
.section2 .tab.active a:hover {
background-color: #0000ff;
}
A probably better way to achieve that result would make use of a mixin. Something like:
.section-color (#color) {
.color {
color: #color;
}
.colorBG-medium{
background-color: #color;
}
.colorBG, .tab.active a {
background-color: #color;
&:hover{
background-color: #color;
}
}
}
.section1 {
.section-color(red);
}
.section2 {
.section-color(#123456);
}
/* ... */

Resources