The Sass ampersand and attribute selectors - css

I want to create a sass file that the selectors will be attribute selectors.
When I work with class selectors, in most of the cases I will do
.parent {
&-child {
}
}
which gives me the following css: .parent-child {}.
I want to achieve the same thing with attribute selectors:
[data-parent] {
&-child {
}
}
which I want to become: [data-parent-child] {}
someone knows how to achieve this? thanks.

You can use this mixin as a workaround to get the desired result.
#mixin child-attribute($child) {
$string: inspect(&);
$original: str-slice($string, 3, -4);
#at-root #{ selector-replace(&, &, "[#{$original}#{$child}]" ) } {
#content;
}
}
The code simply does the following
$string variable is responsible for turning the parent selector to a string using the inspect function
$original variable is responsible for getting the text content of the $string variable i.e the value 'data-parent' from '([data-parent])'
selector-replace function then replaces the parent selector with the concatenation of the $original variable and child variable
When used in the following ways
[data-parent] {
#include child-attribute('-child') {
color: green;
}
}
The css output
[data-parent-child] {
color: green;
}
Depending on what you want to achieve, it can also be used like this
[grandparent] {
#include child-attribute('-parent') {
color: white;
#include child-attribute('-child') {
color: blue;
}
}
}
Which generates the following css
[grandparent-parent] {
color: white;
}
[grandparent-parent-child] {
color: blue;
}
Hope this helps you

You can create mixin that will set styles for elements with data attribytes.
Scss:
#mixin data($name) {
[data-#{$name}] {
#content;
}
}
* {
#include data('lol') {
color: red;
};
}
Css output:
* [data-lol] {
color: red;
}
DEMO

I would go down a slightly different route of having a class on your elements that contain the data attributes.
<div class="data-obj" data-parent="true"></div>
<div class="data-obj" data-parent-child="true"></div>
then in your SASS do
.data-obj {
...
&[data-parent] { ... }
&[data-parent-child] { ... }
}

Related

Use mixin argument to create class name in LESS

I'm trying to create a simple mixin in LESS for different colors I'll use for a website.
What i want is use mixin argument as a part of class name as well.
#green: #5FBEAA; // my color variable
.text-color(#color) {
.text-{#color} {
color: #color;
}
}
.text-color(#green);
The output i'm getting is:
.text-#5FBEAA {
color:#5FBEAA
}
What I want is:
.text-green {
color:#5FBEAA
}
I think I have the solution using Variable Names.
Less
#green: #5FBEAA;
.text-color(#colorname) {
#color: ~"#{colorname}";
.text-#{color}{
color: ##color;
}
}
.text-color(green);
Output
.text-green {
color: #5FBEAA;
}
I don't think its possible. The closest solution for this will be using an additional variable.
#green: #5FBEAA;
.text-color(#name,#color) {
.text-#{name} {
color: #color;
}
}
.text-color(green,#green);
This will compile to
.text-green {
color: #5FBEAA;
}

SASS/SCSS does not accept &.&

Inside my component I'd like to add a modifier, which should have a higher specification so my output should look like this:
Wanted output:
.component {
// ...
}
.component.component--modifier {
// ...
}
SCSS Suggestion:
.component {
// ...
&.&--modifier {
// ...
}
}
But this does not work, I'm getting compile errors: Kind of "format errors" or "invalid CSS".
You could define a mixin:
#mixin mod($n) {
.#{$n} {
color: blue;
}
.#{$n}.#{$n}--modifier {
color: red;
}
}
#include mod(component);
Output:
.component {
color: blue;
}
.component.component--modifier {
color: red;
}
But there's probably a more raisonnable approach to your real problem, like having a modifier class.
You have a period next to the & (&.&). This would produce component..component--modifier, which is incorrect(two periods). What you really want is && but sass doesn't let you do this. What you want to do is escape the second & like this:
&#{&}--modifier
A simpler solution is to interpolate the second & by putting it into #{&}:
.component {
// ...
&#{&}--modifier {
// ...
}
}
Note: The dot between the two & is not needed, because & contains it already.
An equivalent mixin related to Densys would be:
#mixin modifier($modifier) {
&#{&}--#{$modifier} {
#content;
}
}
Usage:
.component {
#include modifier(breadcrumb) {
// ...
}
}

Sass and libraries for theming [duplicate]

I'm refactoring some of my Sass code and I came across a weird issue. My code currently looks like this:
// household
$household_Sector: 'household';
$household_BaseColor: #ffc933;
// sports
$sports_Sector: 'sports';
$sports_BaseColor: #f7633e;
// the mixin to output all sector specific css
#mixin sector-css($sector_Sector,$sector_BaseColor) {
.sector-#{$sector_Sector} {
&%baseColor {
background-color: $sector_BaseColor;
}
}
}
// execute the mixin for all sectors
#include sector-css($household_Sector, $household_BaseColor);
#include sector-css($sports_Sector, $sports_BaseColor);
.product-paging {
h2 {
#extend %baseColor;
}
}
DEMO
The compiled result looks like this:
.product-paging h2.sector-household {
background-color: #ffc933;
}
.product-paging h2.sector-sports {
background-color: #f7633e;
}
But what I need is this:
.sector-household.product-paging h2 {
background-color: #ffc933;
}
.sector-sports.product-paging h2 {
background-color: #f7633e;
}
What I don't understand is why my placeholder (&%baseColor) isn't attached to the parent selector (&%baseColor) as I added the ampersand right in front of it?
Is this maybe a bug when combining & and %? Is there another solution on how to achieve what I want?
EDIT
Alright I figured out why this isn't possible. Anyway is there a workaround for what I'd like to achieve?
Extends, as you've already discovered, can get rather messy. I would go about solving your problem by using an #content aware mixin in combination with global variables (this uses mappings, which are part of 3.3... you can do it with lists of lists, but it's a little less elegant):
$base-color: null; // don't touch
$accent-color: null; // don't touch
$sections:
( household:
( base-color: #ffc933
, accent-color: white
)
, sports:
( base-color: #f7633e
, accent-color: white
)
);
// the mixin to output all sector specific css
#mixin sector-css() {
#each $sector, $colors in $sections {
$base-color: map-get($colors, base-color) !global;
$accent-color: map-get($colors, accent-color) !global;
&.sector-#{$sector} {
#content;
}
}
}
.product-paging {
#include sector-css() {
h2 {
background-color: $base-color;
}
}
}
Output:
.product-paging.sector-household h2 {
background-color: #ffc933;
}
.product-paging.sector-sports h2 {
background-color: #f7633e;
}
Update: Since you want to guarantee that the sector class is always at the top, you just need to switch around a little.
#mixin sector-css() {
#each $sector, $colors in $sections {
$base-color: map-get($colors, base-color) !global;
$accent-color: map-get($colors, accent-color) !global;
.sector-#{$sector} {
#content;
}
}
}
#include sector-css() {
&.product-paging {
h2 {
background-color: $base-color;
}
h3 {
background-color: #CCC;
}
h2, h3 {
color: $accent-color;
}
}
}

how do add a dot to a variable to be used as selector in less

I'm currently getting this output:
.'teal-dark' { color: #xxx; }
What I want is this: {
.teal-dark { color; #xxx; }
Here is what I'm trying to do:
#teal-dark: #xxx;
.#{currentMember} div { background: ~"#{#{currentMember}}" };
See: http://lesscss.org/features/#variables-feature-variable-interpolation http://lesscss.org/features/#variables-feature-variable-names and
#current-member: teal-dark;
#teal-dark: red;
.#{current-member} {
color: ##current-member;
}
compiles into:
.teal-dark {
color: red;
}
Possible relevant questions:
Defining Variable Variables using LESS CSS
Dynamic class names in LESS
Here's the fix from another post:
#selector: ~'.#{currentMember}';
#{selector} div { background: ~"#{#{currentMember}}" };

How can I create a Sass mixin with a class as a variable

I am trying to write something like this :
#mixin variableChild($child:".theChild") {
//some css
$child {
//css specific to the child
}
}
#parent { #include variableChild(".specificChild"); };
So it would generate this CSS :
#parent {//some css}
#parent .specificChild {
//css specific to the child
}
You were almost right, you just missed the #{} around your child selector I think. There’s more information about it in the Sass documentation.
#mixin variableChild($child:".theChild") {
#{$child} {
color: red;
}
}
#parent {
#include variableChild(".specificChild");
};
http://jsfiddle.net/UrLdB/

Resources