DEV Community

Davide Marchet
Davide Marchet

Posted on • Edited on

scss-utopia: save time, build fast (almost everything)

(Original repo and files https://github.com/DidoMarchet/scss-utopia)

📖 From https://en.wiktionary.org/wiki/utopia

utopia

A world in which everything and everyone works in perfect harmony.

🌘 Css is not an exact science and managing easily fluid and responsive styles in perfect harmony with designer's vision (IMHO) is utopia.

🌖 For that purpose scss-utopia was created: covering most developer needs in terms of typography, spacing and sizes ([...]) in the simplest and automated possible way!

Table of content:

You install the package via npm:

npm i scss-utopia
Enter fullscreen mode Exit fullscreen mode

and include it using an @import statement:

@import '~scss-utopia';

/// @import 'node_modules/scss-utopia/dist/index.scss';
/// [...]
Enter fullscreen mode Exit fullscreen mode

Queries

First of all we set up the media queries and features we'll use along all the application.

The library comes with a list of default queries and features:

$defaults: (
  "small": (min-width: 320px), 
  "medium": (min-width: 750px),
  "large": (min-width: 1000px),
  "xlarge": (min-width: 1300px),
  "pointer": (pointer: fine) and (hover: hover),
  "touch": (pointer: coarse) and (hover: none)
);
Enter fullscreen mode Exit fullscreen mode

Using $queries variable in your scss stylesheet you can easily extend and override the default values adopting consistent naming convention:

$queries: (
  "tablet": (min-width: 768px) and (max-width: 1024px),
  "xlarge": (min-width: 1600px),
  "xlarge-retina": (-webkit-min-device-pixel-ratio: 2) and (min-width: 1300px)
  /// [ ...other rules ]
);
Enter fullscreen mode Exit fullscreen mode

The resulting set of values will be the merge of $defaults and $queries variables:

/*
  "small": (min-width: 320px), 
  "medium": (min-width: 750px),
  "large": (min-width: 1000px),
  "xlarge": (min-width: 1600px), // overrited 
  "pointer": (pointer: fine) and (hover: hover),
  "touch": (pointer: coarse) and (hover: none),
  "tablet": (min-width: 768px) and (max-width: 1024px), // added
  "large-retina": (-webkit-min-device-pixel-ratio: 2)  and (min-width: 1300px) // added
*/
Enter fullscreen mode Exit fullscreen mode

Use Queries

Once we have declared all the queries we need, we can deliver tailored style to each them using the react mixin:

@include react('medium'){
  body{
    background: black;
  }
}
a{
  @include react('pointer'){
    &:hover{
      color: red;
    }
  }
}

/*
  Will generate 

  @media (min-width: 750px)
    body {
      background: black;
    }
  }
  @media (hover: hover)
    a:hover {
      color: red;
    }
  }
*/
Enter fullscreen mode Exit fullscreen mode

😰 Self guard: the mixin is called react because it has a reaction when a rule comes true, nothing in common with the js framework

Automate responsive rules

At this point we have all the instruments to handle the style if a certain condition is true.
With resp mixin we can automate this process and quickly generate responsive rules.

The mixin:

@mixin resp($properties...){ /* code */ }
Enter fullscreen mode Exit fullscreen mode

takes as parameters:

  • $properties... a list that contains key/values pair.

⚠️ Key name is the name of css rule and it's required for each element.

Other key/values pair have a query as key and a size as value.

p{
  font-size: 1rem;
  @include resp(
    (
      'name': 'font-size',
      'medium': 1.15rem,
      'large': 1.35rem,
      'xlarge': 1.5rem
    ),
    (
      'name': 'margin',
      'medium': 25px 50px,
      'xlarge': 50px 100px
    )
  );
}

/* 
  Will generate:

  p {
    font-size: 1rem;
  }
  @media (min-width: 750px) {
    p {
      font-size: 1.15rem;
      margin: 25px 50px;
    }
  }
  @media (min-width: 1000px) {
    p {
      font-size: 1.35rem;
    }
  }
  @media (min-width: 1300px) {
    p {
      font-size: 1.5rem;
      margin: 50px 100px;
    }
  }
*/
Enter fullscreen mode Exit fullscreen mode

Automate fluid rules

Now it's time to leave responsive behaviour and linearly scale rules between an upper and lower bound.

The fluid mixin uses clamp css function and also provides a fallback for browsers that don't support modern css solutions.

The mixin:

@mixin fluid($property, $sizes...) { /* code */ }
Enter fullscreen mode Exit fullscreen mode

takes as parameters:

  • $property the name of the css rule;
  • $sizes... a list of clamp parameters (min scaler max, min scaler max, [...]).
p{
  @include fluid('font-size', 1rem 5vw 3rem);
  @include fluid('margin', 100px 10vw 200px, 150px 25vw 300px);
  @include fluid('padding', 100px 10vw 200px, 20px, 100px 10vw 200px);
}

/*
  Will generate:

  p {
    font-size: 3rem;
    font-size: min(max(1rem, 5vw), 3rem);
    font-size: clamp(1rem, 5vw, 3rem);
    margin: 200px 300px;
    margin: min(max(100px, 10vw), 200px) min(max(150px, 25vw), 300px);
    margin: clamp(100px, 10vw, 200px) clamp(150px, 25vw, 300px);
    padding: 200px 20px 200px;
    padding: min(max(100px, 10vw), 200px) 20px min(max(100px, 10vw), 200px);
    padding: clamp(100px, 10vw, 200px) 20px clamp(100px, 10vw, 200px);
  }
*/
Enter fullscreen mode Exit fullscreen mode

🚜 Boosted allowing the use of fluid and static values together:

p{
  // rules: static static
  @include fluid('padding', 20px, 20px);
  // rules: fluid static
  @include fluid('padding', 100px 10vw 200px, 20px);
  // rules: fluid static fluid
  @include fluid('padding', 100px 10vw 200px, 20px, 100px 10vw 200px);
  // rules: static fluid static
  @include fluid('padding', 20px, 100px 10vw 200px, 20px);
  /// [ ...other rules ]
}

/*
  Will generate:

  p {
    // rules: static static
    padding: 20px 20px;
    padding: 20px 20px;
    padding: 20px 20px;

    // rules: fluid static
    padding: 200px 20px;
    padding: min(max(100px, 10vw), 200px) 20px;
    padding: clamp(100px, 10vw, 200px) 20px;

    // rules: fluid static fluid
    padding: 200px 20px 200px;
    padding: min(max(100px, 10vw), 200px) 20px min(max(100px, 10vw), 200px);
    padding: clamp(100px, 10vw, 200px) 20px clamp(100px, 10vw, 200px);

    // rules: static fluid static
    padding: 20px 200px 20px;
    padding: 20px min(max(100px, 10vw), 200px) 20px;
    padding: 20px clamp(100px, 10vw, 200px) 20px;
  }
*/
Enter fullscreen mode Exit fullscreen mode

Disclaimer

scss-utopia covers the majority of your needs in terms of sizing, positioning and in general aspect.

However the mixins are not ideal to handle rules concerning layout (grid properties in particular) or adaptive design.

As mentioned the perfect harmony is utopia.

Awesome

🚀 Type npm i scss-utopia is damned cool.

⏳ It saves time.

Thanks

Special thanks for the inspiration and snippets to:

Contribute

Feel free to fork and increase this repo!

And let me know if you find it useful!

Enjoy 👊

Top comments (0)