【问题标题】:How to define a sass map for specific CSS selector如何为特定的 CSS 选择器定义一个 sass 映射
【发布时间】:2021-06-17 21:54:00
【问题描述】:

我正在尝试在我的项目中自定义 scss,以便我可以根据应用于最外层元素的 css 选择器来使用 css 变量。 我的基本思路是定义颜色变量,然后使用这些颜色变量在两个不同的 css 选择器中定义语义颜色变量。

$primary: orange;
$primary-dark: redorange;
$warn: red;
$accent: grey;
$dark-grey: #757678;
$light-grey: #f7f7f7;

$error-text: $warn;
.light {
    
    $background: $light-grey;
    $button-bg: $primary;
}

.dark {
    
    $background: $dark-grey;
    $button-bg: $primary-dark;
}

这是我尝试过的一种解决方案,但在 scss 中我们无法根据选择器更改变量的范围。

所以我尝试使用函数。

$white: #fff;
$light-grey: #eaeaea
$primry-dark: redorange;
$primary: orange;
$black: #000;

  $semantic-colors: (
    background: (
      screen: $white,
      tile: $light-grey,
    ),
    buttons: (
      primary: $primary
      link: $white
      icons: $primary-dark;
    )
  );


  @function semantic-color($semantic-color:'background', $tone: "base") {
  // @return red;
  @return map-get(map-get($semantic-colors, $semantic-color), $tone);
}


.side-nav-link {
  background-color: semantic-color(background, tile);
}

上面的代码工作正常。但我想要一个基于主题的颜色图。例如: dark 有自己的语义颜色图,light 有自己的,我可以根据范围访问。

.light {
    $semantic-colors: (
    background: (
      base: $white,
      tile: $light-grey,
    ),
    buttons: (
      primary: $primary,
      link: $white,
      icons: $primary-dark;
    )
  );

}

.dark {
    
      $semantic-colors: (
    background: (
      base: $black,
      tile: $dark-grey,
    ),
    buttons: (
      primary: $primary-dark,
      link: $black,
      icons: $primary;
    )
  );

}

我可以在语义颜色映射中创建两个不同的映射:

$semantic-colors: (
 light:(
    background: (
      base: $white,
      tile: $light-grey,
    ),
    buttons: (
      primary: $primary
      link: $white
      icons: $primary-dark;
    )
  ),
  dark:(
      background: (
      base: $black,
      tile: $dark-grey,
    ),
    buttons: (
      primary: $primary-dark,
      link: $black,
      icons: $primary;
    )
   )
 );

然后修改我的函数以根据 $theme 变量在特定地图中获取颜色。

例如:

$theme: dark;

   @function semantic-color($semantic-color:'background', $tone: "base") {
  // @return red;
  @return map-get(map-get(map-get($semantic-colors, $theme), $semantic-color), $tone);
}

但我不知道如何根据 .light 和 .dark 选择器定义 $theme。

如果我尝试做这样的事情:

.light {
    $theme: light;
}

.dark {
    $theme: dark;
}

然后在语义颜色函数中使用 $theme 变量然后我得到错误 $theme is not defined.

所以我的问题是

“有没有一种方法可以根据 CSS 选择器(在我的情况下为 .light 或 .dark)定义 $theme 或语义颜色函数或 $sematic-color 映射?” p>

我已阅读 sass 文档,但找不到适合我情况的解决方案。

我参考的文章:

Theming in SASS

Creating a Color Language in Web Interfaces (with Sass Maps)

educba SASS Map

【问题讨论】:

  • @Alwasalearner:感谢您对我的回答的反馈。所以我没有得到问题/想法确实不是正确的方法。也许您想更集中/澄清您的问题。
  • 嗨@Brebber,我正在尝试更改scss 变量的范围,就像我们在css 变量中所做的那样,以便我可以使用浅色或深色主题。这是一篇文章,它提出了一种方法,但我无法理解这个解决方案medium.com/@dmitriy.borodiy/…

标签: css sass scss-mixins scss-functions


【解决方案1】:

我不确定我是否完全正确......但我看到你的想法和代码总体上运作良好。

唯一的问题似乎是:您的代码中出现了一些错误$semantic-colors!?

这个(更正版本 = 仅在 $semantic-colors 中更正)在这里有效:

//########### SASS: demo file


//### VARS
$primary: orange;
$primary-dark: redorange;
$warn: red;
$accent: grey;
$dark-grey: #757678;
$light-grey: #f7f7f7;
$white: #ffffff;
$black: #000000;

$error-text: $warn;

$semantic-colors: (
  light: (
    background: (
      base: $white,
      tile: $light-grey,
    ),
    buttons: (
      primary: $primary, 
      link: $white,
      icons: $primary-dark,
    ),
  ),
  dark: (
    background: (
      base: $black,
      tile: $dark-grey,
    ),
    buttons: (
      primary: $primary-dark,
      link: $black,
      icons: $primary,
    ),
  ),
);


//### METHODS

$theme: dark;   

@function semantic-color($semantic-color: "background", $tone: "base") {
  // @return red;
  @return map-get(
    map-get(map-get($semantic-colors, $theme), $semantic-color),
    $tone
  );
}


//### STYLES

.light {
    $theme: light;

    background: semantic-color('background', 'base');
}



//###########################
//###### CSS: compiled file

.light {
  background: #ffffff;  // if $theme changes to dark this becomes #000000
}

【讨论】:

  • Brebber,感谢您提出解决方案。但是有了这个解决方案,我必须将我的 scss 选择器包装在我无法控制的 .light 选择器中。
  • 感谢反馈。我直接评论了你的问题。这只是我理解的一个问题:为什么您无法控制 var.我有点困惑......你没有写完整的sass吗? var是写CSS的。 CSS 类(可能是body class=light)是在 HTML/PHP 中编写 SASS/CSS 后设置的,可以在任何地方做,与 SASS var 无关...???根据该变量,您想要的 css 输出是什么?
【解决方案2】:

由于您的评论,我相信现在可以更好地理解您的问题。因此,根据您的最后评论,我添加了一个额外的答案,因为它更多的是对一般方法的解释,而不是对您的代码的具体答案。

首先:我相信您的代码(SASS-map/-function)以正确的方式工作

对我来说,这似乎更像是一个关于理解主题技术如何工作的问题。

那么让我们从基础开始吧:

1。在html 中进行主题化需要做什么:


// set a theme anchor with classes
// --> class to body
<body class="theme_light">


   ... code ...
   ... all elements within body will be styled by theme-light-classes


   // or ALTERNATIVE do it with a marker where your app starts in html
   // --> class to app-root-element
   <div class="app_root theme_light">

      ... code ...
      ... all elements within app-div will by styled by theme-light-classes

   </div>

</body>

2。基于 HTML 你在CSS:

根据使用的标记技术(正文或应用程序)为两个(!)主题的元素编写样式...

// write styling classes for both themes (dark + light)
// as child selector based on the html theme-anchor-classes

/* stylings light theme */

.theme_light .content {
   background: #theme-light-background-color;
   color: #theme-light-font-color;
}

.theme_light .button {
   background: #theme-light-button-background-color;
   color: #theme-light-button-font-color;
} 


/* stylings dark theme */

.theme_dark .content {
   background: #theme-dark-background-color;
   color: #theme-dark-font-color;
}

.theme_dark .button {
   background: #theme-dark-button-background-color;
   color: #theme-dark-button-font-color;
} 
  

// if you anchor with app class your css-selectors would have to be

/* light theme */
.app_root.theme_light .content { ... }
.app_root.theme_light .content { ... }

/* dark theme */
.app_root.theme_dark .content { ... }
.app_root.theme_dark .content { ... }

3。使用您的 SASS-function/-map 在SASS 中实现此目的

在此步骤中,我们使用您的(仍在工作的)功能和您的问题中的地图。在 SASS 中编写 CSS 与嵌套元素类一样简单......


// write themes dark & white nested to the anchor classes
// use function & map from question

.theme_light {

   // set sass theme varible 
   // to get from function values for theme light
   $theme: light;


   // write stylings
   // function will automatic return values for light theme
   body {
      background: semantic-color('background', 'base');
      color: semantic-color('text-color', 'base'); 
   }
   button {
      background: semantic-color('buttons', 'primary');
      color: semantic-color('buttons-text', 'primary'); 
   }

}


.theme_dark {

   // set sass theme varible 
   // to get from function values for theme dark
   $theme: dark;


   // write stylings
   // function will automatic NOW return values for light theme
   body {
      background: semantic-color('background', 'base');
      color: semantic-color('text-color', 'base'); 
   }
   button {
      background: semantic-color('buttons', 'primary');
      color: semantic-color('buttons-text', 'primary'); 
   }

}

//### 
//### --> that will compile the needed css!!!
//###


//### NOTE:
//--> if you use app-anchor-class 
//--> your nesting would be as follow

.app_root.theme_light { ... same code as above ... } 
.app_root.theme_dark { ... same code as above ... }


提示:

  1. 如您所见,您的函数是一个强大的工具:如示例所示,它导致编写相同的代码两次。如果你编写一个 SASS mixin(使用指令 @content 将单个主题样式传递给它),你可以减少它,这样你就可以一次编写所有主题。

  2. 如您所见,SASS 变量 $theme 在 SASS 中用作开关,它会更改您的函数 semantic-color() 以获得正确的颜色(浅色或深色)。

  3. 在 SASS 中有很多实现主题样式的方法。这是传统方法之一,拥有良好组织的地图是一种非常直观的方法。

【讨论】:

    猜你喜欢
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-28
    • 2021-12-31
    • 1970-01-01
    • 2011-06-14
    • 2012-01-07
    相关资源
    最近更新 更多