unset compass single-text-shadow() - sass

Is there a way to unset or remove the text-shadow effect of the compass function ?
e.g. i want to set the text shadow globally for all header elements and then eliminate it for certain cases.
h2 { #include single-text-shadow($blue, 1px, 1px, 0); }

As in CSS, simply declare none:
.specific h2 { #include single-text-shadow(none); }

Related

Sass: rgba function is not working as per documentation

I have two examples that I'm trying to solve:
Example 1
$test: #101E41
body
--colors-dim: rgba(#{$test}, 0.64)
Output: rgba(#101E41, 0.64)
Example 2
body
--colors-active: #101E41
--colors-dim: rgba(var(--colors-active), 0.64)
Output: rgba(var(--colors-active), 0.64)
Both of these look like are examples that should be valid as shown here: https://sass-lang.com/documentation/modules#rgb
Is there something I'm missing?
You need to make use of interpolation to use Sass inside CSS Custom Properties
CSS custom properties, also known as CSS variables, have an unusual declaration syntax: they allow almost any text at all in their declaration values. What’s more, those values are accessible to JavaScript, so any value might potentially be relevant to the user. This includes values that would normally be parsed as SassScript.
Because of this, Sass parses custom property declarations differently than other property declarations. All tokens, including those that look like SassScript, are passed through to CSS as-is. The only exception is interpolation, which is the only way to inject dynamic values into a custom property.
$bar: #900;
:root {
--foo: #{rgba($bar, 0.5)};
}
Results in:
:root {
--foo: rgba(153, 0, 0, 0.5);
}
For your second example, you're going to have to get a little... creative... since Sass will bail and ignore any CSS Custom Property syntax it sees, you can't make use of Sass's rgba function with Custom Properties - the Sass compiler won't resolve the values for you.
Thankfully, you can still use the native CSS rgba function with Custom Properties, the only downside is that you'll need to break your hexadecimal value into its R, G, and B values.
#function toRGB($color)
#return red($color), green($color), blue($color)
$bar: #900
:root
--foo: #{$bar}
--foo-rgb: #{toRGB($bar)}
--foo-dim: #{rgba($bar, 0.5)}
--foo-dim: rgba(var(--foo-rgb), 0.5)
.button
background-color: var(--foo-dim)
Compiles to:
:root {
--foo: #900;
--foo-rgb: 153, 0, 0;
--foo-dim: rgba(153, 0, 0, 0.5);
--foo-dim: rgba(var(--foo-rgb), 0.5);
}
.button {
background-color: var(--foo-dim);
}
https://www.sassmeister.com/gist/39ffc57c492de73066831afe5a9696f6

How can i use Singularity GS with only 1 master grid?

How can i use SGS without every nested div spawning it’s own smaller grid? I get that it’s more powerful than that but for this case, specifically I’d like to set the width of deeply buried paragraph container to span 5 columns of the original .main-wrap div container’s grid.
for example if i do this to my paragraph which is nested 4 containers deep,
p.mynested_para {
#include grid-span(5, 1) /* i want this to refer to the .main container’s grid */
}
it comes out tiny! i’ve been looking through documentation but haven’t found how to do this yet.
You have to provide a context: how many columns are available for this element.
There are two ways:
1. In the grid-span mixin
The grid-span mixin accepts up to four arguments:
Number of columns to occupy.
Index of the column to start with.
Number of columns in the context.
Gutter ratio of the context.
So what you need to do is:
#include grid-span(5, 1, 8)
...where 8 is the number of columns available in the current context.
2. Using the layout mixin
If you have multiple elements to span in one context, it is tedious to mention the context for every of them.
So instead of this:
.foo { #include grid-span(5, 1, 8); }
.bar { #include grid-span(1, 6, 8); }
.baz { #include grid-span(2, 7, 8); }
You can do this:
#include layout(8) {
.foo { #include grid-span(5, 1); }
.bar { #include grid-span(1, 6); }
.baz { #include grid-span(2, 7); }
}
Documentation
Read about these features in more detail here:
https://github.com/at-import/Singularity/wiki/Spanning-The-Grid#context-overrides

Shortening code by using a variable for including mixin

I'd like to know if there is a way to include a mixin (compass or my own) by a value of a specific variable.
Currently I have the following mixin (which works)
#mixin aligned-top-bottom-border($size, $side){
#if $side == "left"{
#include border-top-left-radius($size);
#include border-bottom-left-radius($size);
}
#else{
#include border-top-right-radius($size);
#include border-bottom-right-radius($size);
}
}
I'd like to turn it to something like the code below (or any other alternative that is shorter and more readable)
#mixin aligned-top-bottom-border($size, $side){
#include border-top-#{side}left-radius($size);
#include border-bottom-#{side}-radius($size);
}
I'm using Sass 3.4.5 (Selective Steve)
Sass documentation has this to say about interpolation:
You can also use SassScript variables in selectors and property names
using #{} interpolation syntax
Nothing about using them in mixins or functions. But there is nothing stopping you from adding your own vendor loop to the mixin instead of using the compass mixin. Like this:
#mixin aligned-top-bottom-border($size, $side){
#each $vendor in ('-webkit-', '-moz-', '-ms-', '-o-', ''){
#{$vendor}border-top-#{$side}-radius: $size;
#{$vendor}border-bottom-#{$side}-radius: $size;
}
}
It gets a bit DRYer but a lot bigger in final output. But it possible.

Breaking out of a Sass mixin

Is it possible to break out/return early of a Sass mixin? I'd like to do something like this:
#mixin foo($bar: false) {
#if $bar {
// return early without applying any of the styles below
}
color: red;
}
Edit: Please keep in mind that this example is the simplest thing I could come up with that illustrates my problem. In the real world, my code is much more complex and the use case for this is clear.
Sass doesn't really have the concept of "break", but an #if/#else will get you pretty close:
#mixin foo($bar: false) {
#if $bar {
color: green;
}
#else {
color: red;
}
}
From the Lead Sass developer at https://github.com/nex3/sass/issues/378:
The issue is that the more seldom-used control structures exist in
Sass, the harder it is for something with only passing familiarity
with the language to read stylesheets that use those control
structures. That's why it started out with the bare minimum set of
structures needed to do anything: because in many cases it makes sense
to skew towards a smaller surface area of the language rather than
optimal semantics for writing complex code.
I still thinking that #if/#else statements is the easiest and best solution to deal with your problem in Sass but I've created two different breakout mixins to help you and as a challenge:
Play with this mixin first
Breakout mixin without #includes (link)
#include breakout($styles)
$style should be a list of styles separated by spaces, here are the allowed values:
Styles
Common CSS styles separated by spaces and without colon or semicolons, lists of values should be wrapped by brackets:
#include breakout(
color blue // <property> <value>
width (100 * 20px) // <property> <operation with values>
border (1px solid #fff) // <property> <list of values>
box-shadow (0 0 10px 4px #0000FF , 0 0 20px 30px #008000) // <property> <nested list of values>
)
Breaks
Breaks are styles that are compiled if its condition is true, also when the condition is true the mixin ends without returns all styles after the break value
$foo: true;
#include breakout(
break (false color red) // break (<condition> <property> <value>
break ((3 < 2) border (1px solid #fff)) // breaks also support list and nested lists
break ($foo width 10px) // This breaks is compiled because condition is true
color blue // This style isn't compiled because the $foo break ends the mixin
)
Note that the order of the mixin argument list is important because it determines the compiled and not compiled styles if a break condition is true
Breakout mixin with #includes (link)
This mixin is similar to the above but it introduces mixin values for $styles, break-mixin mixin and #content into the breakout mixin to allow use of #includes.
Mixins
If you want to use other mixins into breakout mixin you need to add some code into $styles and add each mixin into a break-mixin mixin.
#include breakout(
mixin foo // mixin <name of the mixin declared into break-mixin arguments>
mixin bar // mixin name should match break-mixin argument
mixin foobar
) {
#include break-mixin(foo) { // Here your mixin or mixins for mixin foo }
#include break-mixin(bar) { #include mixin1; #include mixin2; #include mixin3}
#include break-mixin(foobar) { #include foobar}
}
Mixin breaks
Now you can also use mixin into breaks. Here the order is still important:
$foo: true
#include breakout(
mixin foobar
mixin bar
break ($foo mixin foo) // This breaks is compiled because condition is true
color blue // This style isn't compiled because the $foo break ends the mixin
) {
#include break-mixin(foo) { // Here your mixin or mixins for mixin foo }
#include break-mixin(bar) { #include mixin1; #include mixin2; #include mixin3}
#include break-mixin(foobar) { #include foobar}
}
So for your specific case copy the Breakout mixin without #includes (link) to your scss file or use it as a partial and then add this to your code;
#include breakout(
break ($bar property value) // The break out statement
color red // If $bar != false this will be compiled if not it won't
);
I'm surprised that the #error statement has not been mentioned yet. According to the documentation (emphasis mine):
When writing mixins and functions that take arguments, you usually want to ensure that those arguments have the types and formats your API expects. If they aren't, the user needs to be notified and your mixin/function needs to stop running.
That said, #error may not be suitable for every situation, because it will stop the Sass compilation completely. This makes it unfit for mixins where breaking out is an expected end intended scenario.
Example from the Sass documentation:
#mixin reflexive-position($property, $value) {
#if $property != left and $property != right {
#error "Property #{$property} must be either left or right.";
}
$left-value: if($property == right, initial, $value);
$right-value: if($property == right, $value, initial);
left: $left-value;
right: $right-value;
[dir=rtl] & {
left: $right-value;
right: $left-value;
}
}
.sidebar {
#include reflexive-position(top, 12px);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Error: Property top must be either left or right.
}

Using variables for CSS properties in Sass

I am writing a #mixin with some math in it that calculates the percentage width of an element, but since it is very useful I would like to use the same function for other properties too, like margins and paddings.
Is there a way to pass the property name as an argument to a mixin?
#mixin w_fluid($property_name, $w_element,$w_parent:16) {
$property_name: percentage(($w_element/$w_parent));
}
You need to use interpolation (eg. #{$var}) on your variable in order for Sass to treat it as a CSS property. Without it, you're just performing variable assignment.
#mixin w_fluid($property_name, $w_element, $w_parent:16) {
#{$property_name}: percentage(($w_element / $w_parent));
}
In addition to the #rcorbellini response
You can use string and variable together
#mixin margin($direction) { // element spacing
margin-#{$direction}: 10px;
}

Resources