如何为特定的CSS选择器定义sass映射



我正在尝试在我的项目中自定义scs,这样我就可以根据最外层元素上应用的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;
}

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

所以我试着使用函数。

$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);
}

上面的代码运行良好。但是我想要一个基于主题的彩色地图。例如:深色有自己的语义颜色图,浅色有自己的,我可以根据范围访问。

.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没有定义。

所以我的问题是

";有没有一种方法可以根据CSS选择器定义$theme或语义颜色函数或$sematic颜色图(在我的情况下是.light或.d深色(">

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

我参考的文章:

SASS 中的主题

在Web界面中创建颜色语言(使用Sass Maps(

eductba SASS地图

我不确定我做得是否完全正确。。。但在我看来,您的想法和代码总体上运行良好。

唯一的问题似乎是:在查找$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
}

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

首先:我相信您的代码(SASS映射/-函数(的工作方式是正确的

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

所以让我们从基础开始:

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函数/-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中实现主题风格有多种方法。这是一种传统的方法,有一个良好的组织地图是一个非常直观的方法。

最新更新