loop

Themes.

Made.

Easy.

Powered By

view_quilt

Materialize

Responsive CSS framework based on Material Design by Google

my_location

SASS

CSS on steroids: power and elegance to the basic language

settings_ethernet

BEM

A web development approach to achieve flexible and maintainable code

Introduction

The idea behind this demo site is to provide an easy way to apply on-the-fly themes without messing around with intensive JavaScript DOM modifications. Actually, this website just needs one single-liner JavaScript function to do the job. Isn't it great?

For this purpose, I will let SASS to take care of the CSS rules generation when building a theme. Rule schemes for each theme may bring dozens of variations, and thus, managing this code by hand is highly impractical.

I recommend reading this interesting article by Hugo Giraudel where several approaches for this task are presented and documented. I have implemented a slightly modified version of the individual mixins approach as we will see next.

What is a theme?

In short, a theme is the visual appearance of our site, right? Well, lets go further and think of it as a preset package of elements that graphically customize our web content. Or if you prefer, in a more informal language, a theme is the recipe that makes our web look and feel nice. And every recipe is made of ingredients!

We can pack as many ingredients in our recipe as we want, but remember, a good dish is made with a few quality ingredients. Quality over quantity. Let's keep it simple by the moment and consider just a few of them, probably the most significative:

  • Color Palette, with primary, secondary and auxiliar colors.
  • Typography.
  • Shadows, if any.

Now, lets put this into code.

SASS to the rescue!

First of all, lets code our ingredients into theme properties. Real themes used in this site will have plenty more properties, but lets show just a bit to keep things simpler:

                                  
                                    ( "primary-font": Raleway,
                                      "primary-color": hsl(0, 0%, 19%),
                                      "secondary-color": hsl(240, 0%, 63%) )
                                
                                
                                
                                  ( "primary-font": Open Sans,
                                    "primary-color": hsl(0, 69%, 67%),
                                    "secondary-color": hsl(174, 62%, 40%) )
                              
                              
                                
                                  ( "primary-font": Roboto Mono,
                                    "primary-color": hsl(0, 0%, 5%),
                                    "secondary-color": hsl(57, 90%, 60%) )
                              
                              

Then, we can create a collection of themes very easily. Lets save it in our _theme.scss file:

                          
                            $themeCollection: (
                              "bw": (/* Properties here */),
                              "peach-azure": (/* Properties here */),
                              "contrast": (/* Properties here */)
                            ) !default;
                          
                        

Now its time to automatically bind these theme properties to real CSS properties. Here is where magic happens thanks to the SASS mixins. Mixins are just templates that you can reuse on demand with the add-in of parameters, so we can create a smarter logic inside than just copy/paste chunks of code.

What if we do a generic mixin to themify whatever CSS property with theme values? Lets go for it! This is how the file _mixins.scss will look like:

                          
                            @import "themes";

                            $default-duration: 1.5s;

                            @mixin themify( $properties,
                                            $keys,
                                            $transition-duration: $default-duration,
                                            $themes: $themeCollection)
                            {
                              // Iterate over the themes.
                              @each $theme, $themeItem in $themes {
                                // Create a selector CLASS-THEME and also THEME-CLASS.
                                &.theme-#{$theme},
                                .theme-#{$theme} & {
                                  // Iterate over each property-key value.
                                  @for $i from 1 through length($properties){
                                    $property: nth($properties,$i);
                                    $key: nth($keys,$i);
                                    #{$property}: map-get($themeItem, $key);
                                  }
                                  // Finally add transitions over themified properties.
                                  transition-property: #{$properties};
                                  transition-duration: $transition-duration;
                                }
                              }
                            }
                          
                        

This code will generate, for every theme, a themified rule to assign the theme value(s) to every input CSS property(s). Note that I have also added transition effect to the themified properties to make theme changing nicer (unfortunately, a font family change cannot be transitionated).

Usage

We are almost done! Here you have a basic usage example, either with single or mutiple properties, that you can add to your main site.scss file:

                        
                          .navbar {
                              @include themify((background-color,box-shadow),(primary-color, shadow-dark));

                              a {
                                  @include themify(color, text-color-light);
                              }
                        
                      

Final notes

Remember to add a default theme into your body markup. You can also themify your markup by components, or even mix themes all in one, its up to you!

                          
                            
                              <body class="theme-bw">
                                ...
                              </body>
                            
                          
                        

And a JS function like the one below based on regular expressions to quickly change your markup theme on the fly:

                          
                            var themifyMe = function(themeName) {
                                $(document).find("[class*='theme-']").attr("class", function(i, cls) {
                                    return cls.replace(/theme-(.*)/, "theme-" + themeName);
                                });
                            }
                          
                        

Just attach it to an user actionable item.

Try Me!

Did you see that flashing button down on your right? Click it and re-style this site! Included themes are just a sample, but this approach allows you to easily expand your collection within minutes.

palette