Question

Are there any useful techniques for reducing the repetition of constants in a CSS file?

(For example, a bunch of different selectors which should all apply the same colour, or the same font size)?

Was it helpful?

Solution

Recently, variables have been added to the official CSS specs.

Variables allow you to so something like this :

body, html {
    margin: 0;
    height: 100%;
}

.theme-default {
    --page-background-color: #cec;
    --page-color: #333;
    --button-border-width: 1px;
    --button-border-color: #333;
    --button-background-color: #f55;
    --button-color: #fff;
    --gutter-width: 1em;
    float: left;
    height: 100%;
    width: 100%;
    background-color: var(--page-background-color);
    color: var(--page-color);
}

button {
    background-color: var(--button-background-color);
    color: var(--button-color);
    border-color: var(--button-border-color);
    border-width: var(--button-border-width);
}

.pad-box {
    padding: var(--gutter-width);
}
<div class="theme-default">
    <div class="pad-box">
        <p>
            This is a test
        </p>
        <button>
           Themed button
        </button>
    </div>
</div>

Unfortunately, browser support is still very poor. According to CanIUse, the only browsers that support this feature today (march 9th, 2016), are Firefox 43+, Chrome 49+, Safari 9.1+ and iOS Safari 9.3+ :

enter image description here


Alternatives :

Until CSS variables are widely supported, you could consider using a CSS pre-processor language like Less or Sass.

CSS pre-processors wouldn't just allow you to use variables, but pretty much allow you to do anything you can do with a programming language.

For example, in Sass, you could create a function like this :

@function exponent($base, $exponent) {
    $value: $base;
    @if $exponent > 1 {
        @for $i from 2 through $exponent {
            $value: $value * $base;
        }
    }
    @if $exponent < 1 {
        @for $i from 0 through -$exponent {
            $value: $value / $base;
        }
    }
    @return $value; 
}

OTHER TIPS

Elements can belong to more than one class, so you can do something like this:

.DefaultBackColor
{
    background-color: #123456;
}
.SomeOtherStyle
{
    //other stuff here
}
.DefaultForeColor
{
    color:#654321;
}

And then in the content portion somewhere:

<div class="DefaultBackColor SomeOtherStyle DefaultForeColor">Your content</div>

The weaknesses here are that it gets pretty wordy in the body and you're unlikely to be able to get it down to listing a color only once. But you might be able to do it only two or three times and you can group those colors together, perhaps in their own sheet. Now when you want to change the color scheme they're all together and the change is pretty simple.

But, yeah, my biggest complain with CSS is the inability to define your own constants.

You should comma seperate each id or class for example:

h1,h2 {
  color: #fff;
}

You can use global variables to avoid duplicacy.

p{
  background-color: #ccc; 
}

h1{
  background-color: #ccc;
}

Here, you can initialize a global variable in :root pseudo class selector. :root is top level of the DOM.

:root{
    --main--color: #ccc; 
}

p{
  background-color: var(--main-color);
}

h1{
  background-color: var(--main-color);
}

NOTE: This is an experimental technology Because this technology's specification has not stabilized, check the compatibility table for the proper prefixes to use in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future versions of browsers as the spec changes. More Info here

However, you can always use the Syntactically Awesome Style Sheets i.e.

In case Sass, you have to use $variable_name at the top to initialize the global variable.

$base : #ccc;

p{
  background-color: $base;
}

h1{
   background-color: $base;
}

You can use dynamic css frameworks like less.

Personally, I just use comma-separed selector, but there some solution for writing css programmatically. Maybe this is a little overkill for you simpler needs, but take a look at CleverCSS (Python)

Try Global variables to avoid duplicate coding

h1 {
  color: red;
}
p {
  font-weight: bold;
}

Or you can create different classes

.deflt-color {
  color: green;
}
.dflt-nrml-font {
  font-size: 12px;
}
.dflt-header-font {
  font-size: 18px;
}

As far as I know, without programmatically generating the CSS file, there's no way to, say, define your favorite shade of blue (#E0EAF1) in one and only one spot.

You could pretty easily write a computer program to generate the file. Execute a simple find-and-replace operation and then save as a .css file.

Go from this source.css…

h1,h2 {
  color: %%YOURFAVORITECOLOR%%;
}

div.something {
  border-color: %%YOURFAVORITECOLOR%%;
}

to this target.css…

h1,h2 {
  color: #E0EAF1;
}

div.something {
  border-color: #E0EAF1;
}

with code like this… (VB.NET)

Dim CssText As String = System.IO.File.ReadAllText("C:\source.css")
CssText = CssText.Replace("%%YOURFAVORITECOLOR%%", "#E0EAF1")
System.IO.File.WriteAllText("C:\target.css", CssText)

You can use multiple inheritance in your html elements (e.g. <div class="one two">) but I'm not aware of a way of having constants in the CSS files themselves.

This link (the first found when googling your question) seems to have a fairly indepth look at the issue:

http://icant.co.uk/articles/cssconstants/

CSS Variables, if it ever becomes implemented in all major browsers, may one day resolve this issue.

Until then, you'll either have to copy and paste, or use a preprocessor of whatever sort, like others have suggested (typically using server-sider scripting).

    :root {
      --primary-color: red;
    }

    p {
      color: var(--primary-color);
    } 

<p> some red text </p>

You can change color by JS

var styles = getComputedStyle(document.documentElement);
var value = String(styles.getPropertyValue('--primary-color')).trim(); 


document.documentElement.style.setProperty('--primary-color', 'blue');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top