Override span-columns() at-breakpoint in SUSY - grid

The question has already been asked, but the solution doesn't help me any further.
How to override span-columns at different breakpoint in SUSY
screen.css.scss
// Settings
$total-columns : 6;
$column-width : 4em;
$gutter-width : 1em;
$grid-padding : $gutter-width;
$tablet : 8;
$desktop : 12;
// Layout
body {
#include container($total-columns, $tablet, $desktop);
.logo {
#include span-columns(4);
}
nav {
#include span-columns(2 omega);
}
}
#include at-breakpoint($tablet) {
.logo {
#include span-columns(5, $tablet);
}
nav {
#include span-columns(3 omega, $tablet);
}
}
#include at-breakpoint($desktop) {
.logo {
#include span-columns(1, $desktop);
}
nav {
#include span-columns(11 omega, $desktop);
}
}
This is the result: http://jsfiddle.net/jmdcp/1/
When changing the browser width, the columns don't resize. They keep the default ratio (span-columns(4) and span-columns(2 omega), even at the tablet and desktop breakpoint.
I really don't see what I'm doing wrong.

Looks like a cascade specificity issue. Your initial span settings are nested under the body selector. Your breakpoint overrides are not. If you nest it all under body, or un-nest the initial settings it works:
body {
#include container($total-columns, $tablet, $desktop);
}
.logo {
#include span-columns(4);
#include at-breakpoint($tablet) {
#include span-columns(5);
}
#include at-breakpoint($desktop) {
#include span-columns(1);
}
}
nav {
#include span-columns(2 omega);
#include at-breakpoint($tablet) {
#include span-columns(3 omega);
}
#include at-breakpoint($desktop) {
#include span-columns(11 omega);
}
}

Related

scss for loop is not cascading correctly

I have this for loop created like this:
.hero {
#for $i from 1 through 100 {
&.aspect-ratio--#{$i} {
#include aspect-ratio(16, $i);
}
&.aspect-ratio-sm--#{$i} {
#include media-breakpoint-up(sm) {
#include aspect-ratio(16, $i);
}
}
&.aspect-ratio-md--#{$i} {
#include media-breakpoint-up(md) {
#include aspect-ratio(16, $i);
}
}
&.aspect-ratio-lg--#{$i} {
#include media-breakpoint-up(lg) {
#include aspect-ratio(16, $i);
}
}
&.aspect-ratio-xl--#{$i} {
#include media-breakpoint-up(xl) {
#include aspect-ratio(16, $i);
}
}
}
}
When I create an element, like this:
<div class="hero aspect-ratio-md--6 aspect-ratio-sm--8 aspect-ratio--10"></div>
it's not respecting the order I declared my classes, so when I am in a md and above, instead of using aspect-ratio-md-6 it's actually using the aspect-ratio-10 instead.
like this:
Does anyone know what I am doing wrong?
Not sure why it voted down, but I figured this out.
It's because of how my loop was working, it was getting to 8 after 6, so that took precedence.
I changed my loop to this:
$breakpoints: sm, md, lg, xl, xxl;
.hero {
#each $breakpoint in $breakpoints {
#for $i from 1 through 100 {
&.aspect-ratio-#{$breakpoint}-#{$i} {
#include media-breakpoint-up($breakpoint) {
#include aspect-ratio(16, $i);
}
}
}
}
}
And this worked. Why? Because it looks through the breakpoints first meaning the last breakpoint will always take precedence over the first, then it loops from 1 to 100 and creates the classes, again, the later numbers taking precedence over the earlier numbers (not needed, but good to know)

I have an issue with my logic in this SASS for loop using two lists.... the error I'm getting says "index out of bounds for `nth($list, $n)`"

Here's my code:
$responsive-adjust-amounts: (
2.5, //phone
2, //tablet
1.5, //laptop
1.25 //desktop
);
$responsive-devices: ("#{$phone}", "#{$tablet}", "#{$laptop}", "#{$desktop}");
#each $device in $responsive-devices {
#media #{$device} {
#for $i from 1 through length($responsive-adjust-amounts) {
#media #{$device} {
#{nth($responsive-adjust-amounts, $i)} {
#include font-adjustments(nth($responsive-adjust-amounts, $i));
}
}
$i: $i + 1;
}
}
}
Ultimately, I'm wanting it to create this end result:
#media #{$phone} {
#include font-adjustments(nth($responsive-adjust-amounts, 1));
}
#media #{$tablet} {
#include font-adjustments(nth($responsive-adjust-amounts, 2));
}
#media #{$laptop} {
#include font-adjustments(nth($responsive-adjust-amounts, 3));
}
#media #{$desktop} {
#include font-adjustments(nth($responsive-adjust-amounts, 4));
}
Could anyone provide any assistance where I'm getting stuck? Thank you in advance!
Excitedly, I've solved my own problem just now. Here's how:
#each $device in $responsive-devices {
$i: index($responsive-devices, #{$device});
#media #{$device} {
#include font-adjustments(nth($responsive-adjust-amounts, $i))
}
}
Additionally, I forgot to include the font-adjustments mixin in the original post. So here is that for anyone's review if needed in the future:
#mixin font-adjustments($amount) {
body {font-size: ($body-base * $amount)}
h4 {font-size: ($subhead-base * $amount)}
h1 {font-size: ($h1-base * $amount)}
}

Sass: alternative variable in less [duplicate]

I'm trying to loop through a list of values in Sass and use interpolation of the current key to dynamically output class names that utilize #include and #extend, respectively.
Here is a pen showing the problem, simplified. http://codepen.io/ghepting/pen/vBmLy
As you can see in the markup, I have tried including the "_" inside of the interpolated string as well as outside of it. Is there something I'm missing to work around this limitation of how Sass supports interpolation?
(Note: the OP's pen has disappeared. This is not the original code found in the pen, but a rough approximation of the problem)
$error-light: red;
$error-dark: darken(red, 10%);
$success-light: green;
$success-dark: darken(green, 10%);
$dialogs: error, success;
#each $d in $dialogs {
.#{$d} {
background: $#{$d}-light;
}
}
Interpolation doesn't work on mixins or variables at this point in time. You'll have to come up with a different way to achieve your goal.
As of Sass 3.3, you can use mappings for this purpose for variables:
$dialogs:
( error:
( light: red
, dark: darken(red, 10%)
)
, success:
( light: green
, dark: darken(green, 10%)
)
);
#each $name, $colors in $dialogs {
.#{$name} {
color: map-get($colors, dark);
}
}
And for functions:
#function green() {
#return lighten(green, 10%);
}
#function red() {
#return lighten(red, 10%);
}
#mixin my-bg($function-name) {
background: call($function-name);
}
.foo {
#include my-bg('red');
}
Alternative workaround (for a particular use case):
https://sass-lang.com/documentation/at-rules/mixin#passing-arbitrary-arguments
💡 Fun fact:
Because an argument list keeps track of both positional and keyword arguments, you use it to pass both at once to another mixin. That makes it super easy to define an alias for a mixin!
If you are interested in mixin interpolation because you have a group of mixins, like this:
//_mixins.scss
#mixin text-style-1($args...){ //sass here }
#mixin text-style-2($args...){ //sass here }
#mixin text-style-3($args...){ //sass here }
//_text.scss
.text-style-1 {
#include text-style-1;
}
.text-style-1-contrast {
#include text-style-1($contrast: true);
}
.text-style-2 {
#include text-style-2;
}
.text-style-2-contrast {
#include text-style-2($contrast: true);
}
We can take advantage of passing arbitrary arguments and use an alias for the group:
//_mixins.scss
#mixin text-style-1($args...){ //sass here }
#mixin text-style-2($args...){ //sass here }
#mixin text-style-3($args...){ //sass here }
#mixin text($mixin, $args...) {
#if $mixin == 'style-1' { #include text-style-1($args...); }
#else if $mixin == 'style-2' { #include text-style-2($args...); }
#else if $mixin == 'style-3' { #include text-style-3($args...); }
}
//_text.scss
$text-styles: 'style-1', 'style-2', 'style-3';
#each $style in $text-styles {
.text-#{$style} {
#include text($style);
}
.text-#{$style}-contrast {
#include text($style, $contrast: true);
}
}
Ran into this issue of trying to include an interpolated variable inside a mixin and was able to resolve it with placeholders:
%color-scheme-dark-bg-1 { background-color: #4e5163; }
%color-scheme-dark-color-1 { color: #4e5163 !important; }
%color-scheme-light-bg-1 { background-color: #c7c8ce; }
%color-scheme-dark-bg-2 { background-color: #fd6839; }
%color-scheme-dark-color-2 { color: #fd6839 !important; }
%color-scheme-light-bg-2 { background-color: #fecfc1; }
.card_color {
#mixin CardColorScheme($arg: 1) {
.borderPercent {
#extend %color-scheme-dark-bg-#{$arg};
}
.border {
#extend %color-scheme-light-bg-#{$arg};
}
ul li:before {
#extend %color-scheme-dark-color-#{$arg};
}
.percent {
#extend %color-scheme-dark-color-#{$arg};
}
.heading {
#extend %color-scheme-dark-color-#{$arg};
}
}
&--scheme {
&-1 {
#include CardColorScheme(1);
}
&-2 {
#include CardColorScheme(2);
}
}
}
Hat tip to: https://krasimirtsonev.com/blog/article/SASS-interpolation-in-a-name-of-variable-nest-variables-within-variables

How do I use Susy to produce different layouts on different pages?

I'm using Susy 2.1.3 as a grid system. I have a containing element which has a different gutter on different templates. I've declared two different layouts and think I'm invoking them correctly. However, the layout which is defined last is the one which applies everywhere. In the below code, the $onepx-gutters layout is applied even on the .home page.
My SCSS code is very much like:
$small-gutters : (
columns: 12,
gutters: 0.137254902,
output: float,
gutter-position: split,
global-box-sizing: border-box,
);
$onepx-gutters : (
columns: 12,
gutters: 1px/80px,
output: float,
gutter-position: before,
global-box-sizing: border-box,
);
.home .item-container {
#include layout($small-gutters);
#include container();
}
.products .item-container {
#include layout($onepx-gutters);
#include container();
}
.item-container .item-width-2 {
#include span(first 8 of 12);
&:nth-child(2n+3) {
clear: both;
}
}
.item-container .item-width-1 {
#include span(4 of 12);
}
The generated CSS code is similar to:
.item-width-2 {
width: 65.66092%;
float: left;
margin-left: 0.50287%;
margin-right: 0.50287%; }
.item-width-2:nth-child(2n+3) {
clear: both;
}
.item-width-1 {
width: 32.32759%;
float: left;
margin-left: 0.50287%;
margin-right: 0.50287%;
}
As you can see, it doesn't generate separate instances of .home .item-width-2 and .products .item-width-2 with different margins on each.
Your solution works because you changed the code order, not because of name-spacing. Anywhere you are using #include layout you are changing the global variable for all the code that follows (until you change it again). There are a few other options:
// with-layout
// - only change the settings for nested code
#include with-layout($onepx-gutters) {
#include span(3); // this will use $onepx-gutters
}
#include span(3); // this will not
// local context
// - change your settings for any one mixin!
#include span(3 $onepx-gutters); // this will use $onepx-gutters
#include span(3 $small-gutters); // this will use $small-gutters
It works properly if I namespace the elements manually declare the layouts in order, like so:
#mixin item-width-2() {
#include span(first 8 of 12);
&:nth-child(2n+3) {
clear: both;
}
}
#mixin item-width-1() {
#include span(4 of 12);
}
.products {
.item--holder {
#include layout($onepx-gutters);
#include container();
}
.item {
&.width-2 {
#include item-width-2();
}
&.width-1 {
#include item-width-1();
}
}
}
.home {
.item-holder {
#include layout($small-gutters);
#include container();
}
.item {
&.width-2 {
#include item-width-2();
}
&.width-1 {
#include item-width-1();
}
}
}

generate css classes with same content

I have the below sass. In it I am have several charx classes, where x is between 1...7. is it possible to define them in a more concise way instead of defining each one of them individually ?
$first-color: #666666;
$second-color: #0066CC;
#mixin letter($color){
color: $color;
}
.char1{
#include letter($first-color);
}
.char2{
#include letter($second-color);
}
.char3{
#include letter($first-color);
}
.char4{
#include letter($second-color);
}
.char5{
#include letter($first-color);
}
.char6{
#include letter($second-color);
}
.char7{
#include letter($first-color);
}
You could possibly achieve the same effect with plain CSS:
$first-color: red;
$second-color: salmon;
span:nth-of-type(2n-1) {
color: $first-color;
}
span:nth-of-type(2n) {
color: $second-color;
}
Alternatively, your could use the #while directive:
$i: 1;
#while $i <= 7 {
.char#{$i}{
#include letter($first-color);
}
.char#{$i+1}{
#include letter($second-color);
}
$i: $i + 2;
}
Why don't you just use even and odd rules?
Like so you will be able to add infinite elements without touching your css every time.
$first-color: #666666;
$second-color: #0066CC;
#mixin letter($color){
color: $color;
}
.chars div:nth-child(even){
#include letter($first-color);
}
.chars div:nth-child(odd){
#include letter($second-color);
}
Here's an example on my Codepen.

Resources