Dealing With Constants In Sass

Share this article

Sass, like JavaScript, does not have a native way to implement constants. But before going any further, let’s have a quick reminder for those of you who are not very aware of this programming jargon.

In computer programming, a constant is an identifier whose associated value cannot typically be altered by the program during its execution (though in some cases this can be circumvented, e.g. using self-modifying code). Many programming languages make an explicit syntactic distinction between constant and variable symbols. – Wikipedia

So a constant is basically an immutable variable. However since a variable is editable by its very own nature, we needed a new name to describe a variable that is not… you know, variable. Hence, constant.

So as I was saying, Sass has no way to define constants. And if you ask me, it’s probably for the best. In a declarative, styling related language such as CSS, needs for immutable values is very unlikely. But as you may know, I’m the guy who does crazy things with Sass so…

Let’s go.

How did it all started?

There is a convention in computer programming that wants authors to define constants name as snakerized uppercased strings, like this: LOOK_AT_ME_I_AM_A_CONSTANT.

So my first thought was to rely on naming convention in order to define constants in Sass. Basically, all snakerized uppercased variables should be considered as constants, thus should never ever be muted.

For instance:

$MAX_Z_INDEX: 2147483647;
$PI: 3.1415926535897932384626433832795028841971693993751;
$E: 2.71828182845904523536028747135266249775724709369995;

If you ask me, you should probably stop there in most cases. But if you like adding some extra fun/useful stuff to your code, you might want to keep reading.

Keeping it simple

So I thought (and obviously wasn’t alone) about gathering all constants in a $CONSTANTS map. This way, even for an inexperienced developer, it should be quite clear that those values should not be edited.

/// Constants map
/// @type Map
/// @prop {Number} MAX_Z_INDEX - 2147483647
/// @prop {Number} PI - 3.1415926535897932384626433832795028841971693993751
/// @prop {Number} E - 2.71828182845904523536028747135266249775724709369995

$CONSTANTS: (
  'MAX_Z_INDEX': 2147483647,
  'PI': 3.1415926535897932384626433832795028841971693993751,
  'E': 2.71828182845904523536028747135266249775724709369995
);

Although, since it is not very convenient to use map-get() to fetch a value in this map, let’s build a little function to get them, called const().

/// Constant getter
/// @param {String} $name - Name of constant to get
/// @return {*} Constant value
/// @require $CONSTANTS
/// @throw 'Unknown constant `#{$name}`.'

@function const($name) {
  @if not map-has-key($CONSTANTS, $name) {
    @error 'Unknown constant `#{$name}`.';
  }

  @return map-get($CONSTANTS, $name);
}

This function could hardly be any simpler: it only needs a constant name. If it doesn’t exist in $CONSTANTS map, it throws an error. Feel free to get rid of this statement if you feel like returning null (which is what map-get does if a key doesn’t exist) is okay. As far as I’m concerned, I feel like if you try to fetch an unknown constant, it should fail.

Then, you would use it like this:

.test {
  z-index: const('MAX_Z_INDEX');
}

It’s looking nice, isn’t it? I like how you can see right away from the name of the function that the value of z-index is a constant and not some magic number.

Pushing things further

You may have noticed that our current version only deals with reading constants, not creating them. If you want to add a new constant, you have to manually write it to the $CONSTANTS map.

So, what if we had a way to set constants dynamically? This would also allow us to throw an error if we try to override an existing constant. This is what we are going to do in this last section.

The idea is quite simple as well, don’t worry:

  • build a const mixin to set a constant;
  • build a const function to get a constant.

We’ll keep our $CONSTANTS map idea, but we’ll initialize it as an empty map. Then the const mixin will place new constants within it.

$CONSTANTS: () !global;

Let’s get started with our const mixin. It should be quite straightforward to understand: if the constant we are trying to create already exists, we blow up. That’s the whole point. If not, we will add it to the map.

/// Constant setter
/// @param   {String} $name  - Name of constant to get
/// @param   {*}      $value - Constant value
/// @return  {*}             - Constant value
/// @require $CONSTANTS
/// @throw   'Constant `#{$name}` already defined.'
/// @output  Nothing

@mixin const($name, $value) {
  @if map-has-key($CONSTANTS, $name) {
    @error 'Constant `#{$name}` already defined.';
  }

  $CONSTANTS: map-merge($CONSTANTS, ($name: $value)) !global;
}

Our const function should be quite similar in length:

/// Constant getter
/// @param   {String} $name - Name of constant to get
/// @return  {*}            - Constant value
/// @require $CONSTANTS
/// @throw   'Unknown constant `#{$name}`.'

@function const($name) {
  @if not map-has-key($CONSTANTS, $name) {
    @error 'Unknown constant `#{$name}`.';
  }

  @return map-get($CONSTANTS, $name);
}

So we have our ‘getter’ and our ‘setter’. We are now ready to use our little system:

// Initializing new constants

@include const('MAX_Z_INDEX', 2147483647);
@include const('PI', 3.1415926535897932384626433832795028841971693993751);
@include const('E', 2.71828182845904523536028747135266249775724709369995);

// Using a constant;
// same API as before

.test {
  z-index: const('MAX_Z_INDEX');
}

Final thoughts

So you have three solutions:

  1. Name your constants in a specific way to distinguish them from variables.
  2. Use a constants map to store them all and build a little function to get them.
  3. Build ‘getters’ and ‘setters’ to have a simple yet powerful system.

As far as I’m concerned, I’d probably go with the first option. Snakerized uppercased variables. But, whatever floats your boat right? Feel free to play with the code on SassMeister.

Play with the simple version on SassMeister. Then go ahead and check out the the complete version, also on Sassmeister.

Frequently Asked Questions (FAQs) about Dealing with Constants in SASS

What is the difference between SASS variables and constants?

SASS variables and constants are both used to store values that can be reused throughout your stylesheets. However, the main difference lies in their mutability. Variables in SASS can be changed or overridden in the stylesheet, while constants, as the name suggests, remain constant and their values cannot be changed once they are defined. This makes constants ideal for defining values that you want to remain consistent throughout your project, such as brand colors or standard margins and padding.

How can I use SASS constants across multiple files?

To use SASS constants across multiple files, you need to use the @import directive. This allows you to import the constants from one file into another. For example, if you have a file named _variables.scss where you have defined your constants, you can import it into another file using @import 'variables';. Now, you can use the constants defined in _variables.scss in this file.

Can I use SASS constants in calculations?

Yes, you can use SASS constants in calculations. SASS allows you to perform arithmetic operations with constants, just like you would with regular numbers. For example, if you have a constant $base-font-size: 16px;, you can use it in a calculation like font-size: $base-font-size * 1.5; to get a font size of 24px.

How can I define color constants in SASS?

Defining color constants in SASS is straightforward. You simply assign the color value to a constant. For example, $primary-color: #ff0000;. You can then use this constant wherever you need to use this color in your stylesheet. This is particularly useful for maintaining a consistent color scheme throughout your project.

Can I use SASS constants with CSS properties?

Yes, you can use SASS constants with CSS properties. You can assign any valid CSS value to a SASS constant. For example, you can define a constant for a border style like $border-style: solid 1px #000; and then use it in a CSS rule like border: $border-style;.

How can I override SASS constants?

Unlike variables, SASS constants cannot be overridden. Once a constant is defined, its value remains the same throughout the stylesheet. This is why they are called ‘constants’. If you need a value that can be changed or overridden, you should use a variable instead.

Can I use SASS constants in media queries?

Yes, you can use SASS constants in media queries. For example, you can define a constant for a breakpoint like $breakpoint: 768px; and then use it in a media query like @media (max-width: $breakpoint) { ... }.

How can I convert a SASS constant to a string?

To convert a SASS constant to a string, you can use the #{} interpolation syntax. For example, if you have a constant $width: 100;, you can convert it to a string like width: #{$width}px;.

Can I use SASS constants in functions and mixins?

Yes, you can use SASS constants in functions and mixins. They can be used as arguments or within the body of the function or mixin. This allows you to create reusable pieces of code with consistent values.

How can I use SASS constants with the @extend directive?

SASS constants can be used with the @extend directive in the same way as any other value. For example, if you have a placeholder selector %button and a constant $button-color: #ff0000;, you can use them together like .my-button { @extend %button; color: $button-color; }.

Kitty GiraudelKitty Giraudel
View Author

Non-binary trans accessibility & diversity advocate, frontend developer, author. Real life cat. She/her.

AdvancedCSSsasssass mapssass mixinsStuR
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week