HiveBrain v1.2.0
Get Started
← Back to all entries
patternhtmlMinor

Improve page-specific CSS for different color schemes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
csscolorimprovedifferentforpagespecificschemes

Problem

For a website with four pages (blog, portfolio, profil and impressum) I have four different color schemes (for links, headings, code, etc.). This results in bloated CSS which I want to reduce.

Here is a demo. You see the navigation items use the color scheme of the page it links to. In the demo we're on the blog page with a green theme. Styling the different pages works by adding a class to the root element (i.e. `).

How can I improve this approach of styling things page-dependant?

Also what kind of naming would be appropriate? I could use the titles of the pages (
page--blog, link--blog, …) or the colors (page--green, link--green, …). Other ideas/suggestions?

HTML:


    
        BlogPortfolioProfilImpressum
    
    
        Regular paragraph, containing a link. Crazy, huh?
    


CSS:

.site-nav {
    background-color: #444;

    a {
        color: white;
        display: inline-block;
        padding: 20px;
    }
}

.link--green {
    background-color: forestgreen;

    .page:not(.page--blog) &:hover {
        background-color: yellowgreen;
    }
}

.link--blue { /* ... */ }
.link--orange { /* ... */ }
.link--red { /* ... */ }

.page-content {
    a,
    h1, h2, h3, h4, h5, h6 {
        .page--blog & {
            color: forestgreen;
        }

        .page--profil & { /* ... */ }
        .page--portfolio & { /* ... */ }
        .page--impressum & { /* ... */ }
    }
}


possible solutions/ideas:

  • additional CSS file only used on these sites (extra HTTP request)



  • page-specific CSS in style` tags inside the actual html document (hard to manage)



  • Using SASS mixins to generate the CSS for the four pages (won't reduce bloat)

Solution

Some days passed and I feel like I should share the changes I have made so far.

Naming

I started using page names instead of color names on classes and variables. This leaves me with the benefit of being able to change the color scheme of an entire page only by changing the value of the color variable.

.page--home       -> .page--blog
.nav__item--green -> .nav__item--blog
$green-color      -> $blog-color


Generating page-specific CSS with a mixin

  • I need to style certain elements depending on the class I assign to the root element (e.g. `)



  • The needed arguments I pass to the mixin are $element (a selector like .site-nav or h1) and $property (a CSS property like color)



  • There also is an optional argument which allows me to switch to light color variations



Mixin:

@mixin themify($element, $property, $light-colors: false) {
    $pages: null;
    @if $light-colors == true {
        $pages: blog      $green-color-light,
                portfolio $orange-color-light,
                profil    $blue-color-light,
                impressum $red-color-light;
    } @else {
        $pages: blog      $green-color,
                portfolio $orange-color,
                profil    $blue-color,
                impressum $red-color;
    }

    @each $page in $pages {
        .page--#{nth($page, 1)} #{$element} {
            #{$property}: nth($page, 2);
        }
    }
}

/* Call the mixin without optional argument */
@include themify(site-nav, background-color);

/* ...use the light colors instead of the normal ones */
@include themify(site-nav, background-color, $light-color: true);


Problems with the mixin:

  • I can't pass a list of selectors like a, h1, h2, h3, h4, h5, h6` – Didn't find a solution so far (probably going to involve multi-dimensional lists)



  • Still creates the bloated CSS, but eases my work



I still would love to hear some suggestions/improvements.

Code Snippets

.page--home       -> .page--blog
.nav__item--green -> .nav__item--blog
$green-color      -> $blog-color
@mixin themify($element, $property, $light-colors: false) {
    $pages: null;
    @if $light-colors == true {
        $pages: blog      $green-color-light,
                portfolio $orange-color-light,
                profil    $blue-color-light,
                impressum $red-color-light;
    } @else {
        $pages: blog      $green-color,
                portfolio $orange-color,
                profil    $blue-color,
                impressum $red-color;
    }

    @each $page in $pages {
        .page--#{nth($page, 1)} #{$element} {
            #{$property}: nth($page, 2);
        }
    }
}

/* Call the mixin without optional argument */
@include themify(site-nav, background-color);

/* ...use the light colors instead of the normal ones */
@include themify(site-nav, background-color, $light-color: true);

Context

StackExchange Code Review Q#39890, answer score: 5

Revisions (0)

No revisions yet.