Sass with compas, selecting all divs with x class before hyphen - sass

I am using Sass and currently selecting my divs via:
[class*='inner-']{
padding: $pad;
}
But i have two variants of this div which are: -left, -right but i wanted to see if there was a better way rather than doing individual style blocks for each one, if i could merge it into one block.
My variants have a slight variation on the padding.
So something like:
[class*='inner-']{
padding: $pad;
-left{
atttribute
}
-right{
attribute
}
}
I might be over thinking this and making it pointlessly complex, but it's helping me learn lots so if anyone can shed some light on the best solution I'd appreciate it.

Not sure I've understood what you need properly, but I think you making it too complex.
Nice and simple solution:
%inner {
padding: somepadding;
}
.inner-left {
#extend %inner;
some other: attributes for left;
}
.inner-right {
#extend %inner;
some other: attributes for right;
}
We use placeholder (%inner), it's like a silent class, won't be outputed until called. Then extend it to those two classes. Nice, clean and maintainable solution.

Related

SASS/SCSS: Define variables based on other variables

How does one define variables with the use of other variables in SASS?
This is how one could do it with LESS:
// import Google Material Colors
// returns variables ie #blue-500, #blue-400 etc
#import 'material.colors.less';
// base
#_color: 'blue';
#_secondary: 'amber';
// primary colors
#color-primary: ~"#{#{_color}-500}";
#color-primary-bright: ~"#{#{_color}-300}";
#color-primary-brighter: ~"#{#{_color}-200}";
#color-primary-brightest: ~"#{#{_color}-50}";
// secondary colors
#color-secondary: ~"#{#{_secondary}-500}";
#color-secondary-bright: ~"#{#{_secondary}-300}";
#color-secondary-brighter: ~"#{#{_secondary}-200}";
#color-secondary-brightest: ~"#{#{_secondary}-50}";
The LESS-way certainly isn't clean and dandy, but -- it works™
The idea is to set a base primary and then just set the other color(s) dynamically based on that.
I can't imagine that one would have to loop/map etc just to do this with SASS?(!)
Sass does not support dynamic variables, period.
You will need to use maps, but I'm not sure this will help you in this specific case (as you are already using external colors):
#import 'material.colors';
$colors: (
primary: (
default: $blue-500,
bright: $blue-300,
brighter: $blue-200,
brightest: $blue-50
),
secondary: (
default: $amber-500,
bright: $amber-300,
brighter: $amber-200,
brightest: $amber-50
)
);
#function color($color, $brightness: default) {
#return map-get(map-get($colors, $color), $brightness);
}
h1 {
color: color(primary, bright);
background-color: color(secondary);
}
Of course you can do it. You can use neat sass color functions and do what you need in a nice and clean way. Take a look at lighten function and even darken function, or at other color functions in general.
Basically, you do it like this:
$primary-color: #08f;
$primary-light-color: lighten($primary-color, 20%);
$primary-lighter-color: lighten($primary-color, 30%);
$primary-dark-color: darken($primary-color, 20%);
$primary-darker-color: darken($primary-color, 30%);
You can see this in action here:
https://codepen.io/anon/pen/PjXRjM?editors=1100#0
Or if you feel like it's a good idea, you could automate it a little with lists and loops. Take a look at this article: https://www.sitepoint.com/managing-color-values-with-sass/, where its author gets through it. (To be honest, I'm not sure if that a good idea at all, as it easily may be hard to understand and maintain later. That's another topic, though.)

SASS / SCSS merge multi-values within single item [duplicate]

This question already has answers here:
Sass - Manipulate inherited property?
(4 answers)
Closed 7 years ago.
I have the following mixin:
#mixin rhombus() {
#include transform(rotate(45deg));
}
and another one:
#mixin centerVertically() {
#include transform(transform(0, -50%));
position: absolute;
top: -50%
}
Now I would like to use them both on the same element and of course it will fail because the last called will be a winner.
There is a similar question for LESS but I could not find any solution for SASS.
Don't stick to the code above, this is just an example. I don't ask how to center the element or how to rotate it; I also know the order of transformation can matter, but still, is there any way to make the transform property be merged?
EDIT
the question is marked as a duplicate, but the question is totally different (and answer is not covering my question as well). I am asking about sharing the properties within a single block:
div {
#mixin rhombus;
#mixin centerVertically;
}
The attached question is asked about accessing inherited properties and same level properties. My case is different and I believe the answer can be different as well. I don't search for manipulating the inherited property. I search for the way to merge the property values into one. And I already found an answer although the 'duplicate' question does not have the one which solves the problem.
I've made some research and found the following feature request on a SASS'es repo which describes exactly this case.
Yes, there is no nice solution for that SASS-wise. But there is a workaround by mahdaen which might be really helpful. The code below is fully belonging to this good guy
$tmp-box-shadow-value: none;
#mixin box-shadow($value, $append: false) {
#if ($tmp-box-shadow-value == none) {
$tmp-box-shadow-value: $value !global;
}
#else {
$tmp-box-shadow-value: ($tmp-box-shadow-value, $value) !global;
}
#if ($append == false) {
#include prefixer(box-shadow, $tmp-box-shadow-value, true);
$tmp-box-shadow-value: none !global;
}
}
with usage like
.shadow-elem {
// Appending values.
#include box-shadow(0 0 1px #ccc, true);
#include box-shadow(0 0 1px #ddd, true);
// Append and write the style.
#include box-shadow(0 0 1px #eee);
}
Although it may seem dirty in somebody's eyes, I really like it as after small adaptions it fully solves my problem.

last-child logic for columns in Bourbon Neat

I'm wondering how the 0 margin on the last child is supposed to come in.
I've got:
body {
#include outer-container;
.content-main.with-sidebar { #include span-columns(8);}
aside { #include span-columns(4); }
}
Body is centered with a max max width -- both .content-main and aside are getting the correct widths, but neither are getting the :last-child { margin-right: 0;} that they're supposed to. There's other stuff in body, but it's the only parent they've got.
Clearly I'm not doing something right -- but the fact that they're getting widths at all seems like it would indicate that everything is #importing correctly.
With thanks --
Without looking at your HTML I can only guess that those aren't actually the last-child. For cases like this there is the omega() mixin to use. Look here for the documentation: http://neat.bourbon.io/docs/#omega

Check if SASS parent selector exists. Is it possible

I have a question. So in a mixing I am making a reference to the parent selector "&". This works as long as the mixin is not nested. Is there a way to to detect if the mixing is being used in a non nested scenario, or to check if "&" is null?
This works when the mixin call is not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
#content
This works great when the mixin call is nested, but will not resolve '&' when not nested
=myresponsiveMixin($media)
#if $media == small {
#media only screen and (max-width: $break-small)
.classInHTMLToAllowMediaQueries &
#content
#else if $media == medium
#media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1)
.classInHTMLToAllowMediaQueries &
#content
So the question is, if there is a way to be able to check the value of parent selector "&", so I can cover all bases in a single mixin?
#mixin does-parent-exist {
#if & {
.exists & {
color: red;
}
} #else {
.doesnt-exist {
color: red;
}
}
}
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-script
You're trying a wrong solution to solve your issue.
Have a look at how this problem is addressed in powerful SASS frameworks. Let's take Susy by Eric Meyer as a great example.
Let's imagine you've got the following HTML:
<div class="container">
<div class="parent">
<div class="child">
Bla bla
</div>
</div>
</div>
When you call a mixin for the first time, you're doing it simply (the code is in the indented .sass syntax):
$total-columns: 8 // Declaring a varible that will be used by the mixin
.parent
+span-columns(4) // Span four of eight columns
But when you call that for a child element, the proportions would be crooked, because the parent is already proportioned:
.child
+span-columns(2) // This will fail. You want 2 of 8 columns,
// but due to nesting the math is crooked.
// It will be "2 of (4 of 8)".
To address the issue, you provide an optional argument: a context that is used to do the math:
.child
+span-columns(2, 4) // Now the mixin will take 2 parts of 4
// instead of 2 parts of four
The source code for this mixin is available on GitHub.
In short, it creates an optional argument like this (the code is in the CSS-like .scss syntax):
#mixin span-columns(
$columns,
$context: $total-columns
//...
) {
//...
width: columns($cols, $context /*...*/);
//...
}
See how $context has a default value? Thanks to the default value this argument can be omitted. In other words, $context is an optional argument.
When calling this mixin, if $context is not provided (e. g. span-columns(2)), then it is set equal to $total-columns. The $total-columns variable should be set prior to calling the mixin for the first time (see my example above).
Then the two arguments are used to calculate the width.
UPD 2013-03-30
I am not trying to figure out things in regards to columns... I have modifier my question to make it clearer.
First of all, my recommendation concerns not only grid columns. It's a universal technique you can adopt.
Secondly, now i see that you're trying to nest media queries.
Well, some media queries of different type can be combined in CSS3: e. g. print and width. But you can't put a min-width: 601px inside max-width: 600px, this just won't work!
There's an extensive answer here on StackOverflow describing why you should not nest media queries of the same type: https://stackoverflow.com/a/11747166/901944
Thirdly, you're trying to invent the wheel. There's already a fantastic mixin for crunching media queries: Respond To by Snugug. It's super easy to use and very effective.
Fourthly, the XY thing. Instead of asking about your crooked mixin, please describe the problem that you're trying to solve with it! Show us the actual HTML and explain what behavior you would like to achieve.
We will show you that it can be solved with a simple, elegant, semantic solution that does not require SASS hacking.

Using SASS Variables within nth-child?

I have a grid set up of thumbnail images, currently 4 thumbs per row. To make sure they line up i have this snippet of code:
li:nth-child(5) { margin-left: 0;}
What I have tried to do is this but I am getting a syntax error:
$galleryGrid: 5;
li:nth-child($galleryGrid) { margin-left: 0;}
If I wanted to alter the nth-child to use another value, such as 10 (so I can have 8 thumbs in a row), I assumed this would work.
Is this not possible or am I just doing incorrectly?!
Thanks in advance for you help.
You need to use variable interpolation to allow nth-child to be a variable.
$galleryGrid: 5;
li:nth-child(#{$galleryGrid}) { margin-left: 0;}
Generates
li:nth-child(5){margin-left:0}
This markup is fine if you have absolute control over the images and layout to ensure that your elements always wrap in such a way that every 5th one begins a new row. If you cannot make such guarantees, setting negative margins on the parent element is a better way to go.

Resources