Multiple two-class selectors in Sass - css

Having multiple two-class selectors for a single declaration block, is it possible to simplify the following (i.e. not having to repeat the body tag):
body.shop, body.contact, body.about, body.faq {background-color:#fff;}

try this:
body{
&.shop, &.contact, &.about, &.faq {
background-color:#fff;
}
}

In this case we can use #each directive:
$pages: shop, contact, about, faq;
body {
#each $page in $pages {
&.#{$page} {
background-color:#FFF;
}
}
}
sassmeister.com

body {
&.shop, &.contact {
// Styles here...
}
}

If you are using sass compiled by the node, that may do.
body {
.shop, .contact, .about, .faq {
background-color:#FFFFFF;
}
}

Parent child relationship in sass
parent_tag {
.child {
// rules here
}
}

Related

The Sass ampersand and attribute selectors

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] { ... }
}

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) {
// ...
}
}

Is it possible to use Icons with css:before without hardcoding the code?

I am using the method answered here on StackOverflow to use custom police definition with other classes. This method is summarized below:
[class^="icon-"]:before,
[class*=" icon-"]:before {
font-family: FontAwesome;
}
.icon-custom:before {
content: "\f0c4";
}
When I'm using a custom class to use it, I have to use the code generated by the library:
i:after {
content: '\f0c4';
}
In case this code f0c4 change in the library, I would like to avoid reporting the change in every custom class one by one. I decided to use Sass or Less to be able to deal with this problem.
It would be like below but it does not work.
i:after {
.icon-custom
}
With Sass or Less, is it possible to avoid this magic number?
I know this will be possible:
i:after {
content: #custom-code-value
}
But I prefer to avoid changing the #custom-code-value: : "\f0c4";
Is it the only solution?
You can try to group all the content value in a map variable
I adapted for you an example
SCSS
// Map variable
$icons: (
facebook : "\f0c4",
twitter : "\f0c5",
googleplus : "\f0c6",
youtube : "\f0c7"
);
// Mixin doing the magic
#mixin icons-list($map) {
#each $icon-name, $icon in $map {
#if not map-has-key($map, $icon-name) {
#warn "'#{$icon-name}' is not a valid icon name";
}
#else {
&--#{$icon-name}::before {
content: $icon;
}
}
}
}
// How to use it
.social-link {
background-color: grey;
#include icons-list($icons);
}
CSS
// CSS Output
.social-link {
background-color: grey;
}
.social-link--facebook::before {
content: "";
}
.social-link--twitter::before {
content: "";
}
.social-link--googleplus::before {
content: "";
}
.social-link--youtube::before {
content: "";
}
So you only have to maintain that $icons variable in case some values change. hope you get the idea.

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