SASS compile with comments - sass

I am compiling a SCSS file and it seems to remove my comments. What command can I use to keep all the comments?
>SASS input.scss output.css
I see two types of comments in my SCSS.
// Comment
and
/* Comment */
What is the difference?

As #Roy said above, multi-line comments (/* */) are kept in resulted css, but it depends on format you are using to pre-process your SASS.
If you are using compact mode, or any other 'CSS minifier', you should better use
/*! important comment */
These comments are kept in the compact(minified) versions of your CSS as well.
Example:
html {
/*! important comment */
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
Result (compact, minified version):
html{/*! important comment */-webkit-box-sizing:border-box;box-sizing:border-box}

The difference between the two type of comments is pretty easy:
// Some comment for a single line
and
/* This is
a multiline comment
for large descriptions */
According to the officials docs of SASS, you can only use the multiline comment option to preserve it into a compiled output file.
Like Sass, SCSS supports both comments that are preserved in the CSS output and comments that aren't. However, SCSS's comments are significantly more flexible. It supports standard multiline CSS comments with /* */, which are preserved where possible in the output. These comments can have whatever formatting you like; Sass will do its best to format them nicely.
SCSS also uses // for comments that are thrown away, like Sass. Unlike Sass, though, // comments in SCSS may appear anywhere and last only until the end of the line.
So the following CSS:
/* This comment
should be kept
and not be thrown away */
.class {
margin: 0 auto;
}
// This comment will be thrown away
.extra-class {
color: blue;
}
will be compiled into:
/* This comment
should be kept
and not be thrown away */
.class {
margin: 0 auto;
}
.extra-class {
color: blue;
}
To fix your compilation problems, you need to convert the // to /* */ comments.

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

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.

#include outer-container not taking default defined in grid-settings

So I've got my _grid-settings.css.scss defined as per the docs and in it, among some of the other default overrides is $max-width: 1200px;.
Part of the contents of my override:
$visual-grid: true;
$visual-grid-color: green;
$visual-grid-index: front;
$visual-grid-opacity: 0.2;
$column: 90px;
$gutter: 30px;
$grid-columns: 8;
$max-width: 1200px;
I know this is working because I'm using the visual grid as well and when I change $max-width to 100% I see that change occur.
The problem I'm having is that my #include outer-container on my body is not being respectful of this value, contrary to the docs, it seems not to notice it.
body {
#include outer-container;
}
When I change this to #include outer-container(1200px); the content then falls into place alongside the rest of the grid.
The problem was that I was also using Bitters and did not know that it has its own grid settings as well. I had to make sure that I uncomment #import "grid-settings"; from base/_base.css.scss as per the docs' instructions.

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

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.

Resources