How to properly generate Sass Themes

北城以北 提交于 2021-02-20 03:52:11

问题


I need to generate css based on sass variables. How to turn this:

$themes: (
  light: (
    text: black
  ),

  dark: (
    text: white
  )
);    

.foo {
  display: flex;
  color: @include themify('text');
}

Into this:

.foo {
  display: flex;
}

.light .foo {
  color: #000;
}

.dark .foo {
  color: #fff;
}

Any ideas of how to implement this?


回答1:


You can't reuse the color declaration using a mixin, so instead, you need to pass it to the mixin.

Check that out

$themes: (
  light: (
    text: black
  ),

  dark: (
    text: white
  )
);

@mixin themify($prop, $key, $themeList: $themes) {
  @each $themeName ,$theme in $themeList {
    $value: map-get($theme, $key);
    .#{$value} {
      #{$prop}: $value;
    } 
  }
}

.foo {
  display: flex;
  @include themify('color', 'text');
}

The result will be: https://gist.github.com/felixmosh/c8110a93ef55a0a52bd369b23f88e525




回答2:


Here you go

/*
 * Theme definitions
 */

$themes: (
  light: (
    backgroundColor: white,
    textColor: #408bbd,
    buttonTextColor: #408bbd,
    buttonTextTransform: none,
    buttonTextHoverColor: #61b0e7,
    buttonColor: #fff,
    buttonBorder: 2px solid #408bbd,
  ),
  dark: (
    backgroundColor: #222,
    textColor: #ddd,
    buttonTextColor: #aaa,
    buttonTextTransform: uppercase,
    buttonTextHoverColor: #ddd,
    buttonColor: #333,
    buttonBorder: 1px solid #333,
  ),
  purple: (
    backgroundColor: purple,
    textColor: #ddd,
    buttonTextColor: #aaa,
    buttonTextTransform: uppercase,
    buttonTextHoverColor: #ddd,
    buttonColor: #333,
    buttonBorder: 1px solid #333,
  ),
);

/*
 * Implementation of themes
 */
@mixin themify($themes) {
  @each $theme, $map in $themes {
    .theme-#{$theme} & {
      $theme-map: () !global;
      @each $key, $submap in $map {
        $value: map-get(map-get($themes, $theme), '#{$key}');
        $theme-map: map-merge($theme-map, ($key: $value)) !global;
      }
      @content;
      $theme-map: null !global;
    }
  }
}

@function themed($key) {
  @return map-get($theme-map, $key);
}

/*
 * Actual styles for the app
 */

body {
  margin: 0;
}

html, body {
  height: 100%;
}

#app-root {
  margin: 0;
  padding: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  
  > div {
    display: flex;
    flex: 1;
  }
}

.app-container {
  display: flex;
  flex-direction: column;
  flex: 1;
  align-items: center;
  justify-content: center;

  .title {
    font-family: sans-serif;
    font-weight: lighter;
  }

  @include themify($themes) {
    color: themed('textColor');  
    background-color: themed('backgroundColor');  
  }

  .button {
    max-width: 20em;
    cursor: pointer;
    border-radius: 5px;
    padding: 15px 32px;
    display: inline-block;
    transition: color 0.1s, border-color 0.1s, background-color 0.1s;

    @include themify($themes) {
      border: themed('buttonBorder');
      color: themed('buttonTextColor'); 
      border-color: themed('buttonTextColor');
      background-color: themed('buttonColor');
      text-transform: themed('buttonTextTransform');

      &:hover {
        color: themed('buttonTextHoverColor'); 
        border-color: themed('buttonTextHoverColor');
        background-color: themed('buttonHoverColor');
      }
    }
  } 
}
<main id="app-root">
  <div class="theme-purple">
    <div class="app-container">
      <h1 class="title">Purple theme</h1>
      <button class="button">A button</button>
    </div>
  </div>
  <div class="theme-light">
    <div class="app-container">
      <h1 class="title">Light theme</h1>
      <button class="button">A button</button>
    </div>
  </div>

  <div class="theme-dark">
    <div class="app-container">
      <h1 class="title">Dark theme</h1>
      <button class="button">A button</button>
    </div>
  </div>
  
  

</main>

demo



来源:https://stackoverflow.com/questions/52109288/how-to-properly-generate-sass-themes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!