如何在Angular Material中制作自定义主题

by Charlee Li

通过李李

如何在Angular Material中制作自定义主题 (How to make a custom theme in Angular Material)

Angular Material is a great library that implements Material Design for Angular 2+. The official document is sufficient regarding the component usages, while there are few articles about how to customize the theme itself, specifically, the colors used in the theme.

Angular Material是一个很棒的库,可实现Angular 2+的Material Design 。 关于组件用法的官方文档就足够了,而关于如何自定义主题本身(特别是主题中使用的颜色)的文章很少。

In this post I would like to summarize what I’ve learned these months from customizing Angular Material themes.

在这篇文章中,我想总结一下这几个月来我从定制Angular Material主题中学到了什么。

Note this article is NOT about AngularJS Material, which is used for AngularJS 1.x.

请注意,本文与用于AngularJS 1.x的 AngularJS材质 无关 。

Some common posts about customizing themes are:

有关定制主题的一些常见文章是:

  • “Theming your Angular Material app”, the official guide for custom themes,

    自定义主题的官方指南“ 主题化您的Angular Material应用 ”,

  • “The complete guide to Angular Material Themes” by Tomas Trajan, which provides many undocumented instructions. Strongly recommended.

    Tomas Trajan 撰写的 “ Angular Material Themes完整指南 ”,其中提供了许多未记录的说明。 强烈推荐

I didn’t find other useful posts and would appreciate if anyone could provide some resources in the comments.

我没有找到其他有用的帖子,如果有人可以在评论中提供一些资源,我将不胜感激。

如何创建自定义主题 (How to Create a Custom Theme)

Creating a material theme is extremely simple: you only need to pick three colors — primary, accent, and warn — and Angular Material will do the rest for you. The material palette page explains how it works clearly, and you can also create a theme visually with Color Tool.

创建材质主题非常简单:您只需选择三种颜色( 色, 强调色和警告色),而Angular Material会为您完成其余工作。 材质调色板页面说明了其清晰的工作原理,您还可以使用Color Tool直观地创建主题。

In regards to code, all you need to do is to create the following theme file:

关于代码,您需要做的就是创建以下主题文件:

// theme.scss@import '~@angular/material/theming';
$my-theme-primary: mat-palette($mat-green);$my-theme-accent : mat-palette($mat-amber);$my-theme-warn   : mat-palette($mat-red);
$my-theme: mat-light-theme(    $my-theme-primary,    $my-theme-accent,    $my-theme-warn);

Then you need to apply this theme in your main style.scss file:

然后,您需要在主style.scss文件中应用此主题:

@import "theme.scss";
@include mat-core();@include angular-material-theme($my-theme);

如何在组件中使用自定义主题 (How to Use Custom Theme in Components)

After creating our own theme, requirements like this will rise:

创建我们自己的主题后,将产生如下要求:

I want to create a text box. The text color, background color, and border color should all come from our own theme, not by hard coding.
我想创建一个文本框。 文字颜色,背景颜色和边框颜色都应来自我们自己的主题,而不是硬编码。

This requirement is pretty common — anyway, being able to be used in components is exactly why we want to create a custom theme. The problem is how.

这项要求很常见-无论如何,能够在组件中使用正是我们想要创建自定义主题的原因。 问题是如何。

混合方法 (The mixin approach)

The first official document I shared proposed a way of using SCSS’s mixin. I call it a “bottom-up” approach, which includes the following steps:

我共享的第一份正式文档提出了一种使用SCSS的mixin的方法。 我称之为“自下而上”的方法,其中包括以下步骤:

  1. Each component defines a theme mixin, and retrieves colors from $theme parameter.

    每个组件都定义一个主题混合,并从$theme参数检索颜色。

  2. A global theme.scss defines the custom theme, then includes all the component theme mixins and calls them with the custom theme.

    全局theme.scss定义了自定义主题,然后包括所有组件主题mixins并使用自定义主题对其进行调用。

In addition to the theme.scss definition mentioned above, each component needs to create a theme file like this:

除了上面提到的theme.scss定义外,每个组件还需要创建一个主题文件,如下所示:

// src/app/comp-a/comp-a.theme.scss@import '~@angular/material/theming';
@mixin comp-a-theme($theme) {          // define mixin  $primary: map-get($theme, primary);  // retrieve color def  button {                             // apply theme to component    background-color: mat-color($primary);  }}

And probably you want a custom-theme.scss to import all the component level themes:

可能您希望custom-theme.scss导入所有组件级主题:

// src/app/custom-theme.scss@import '~@angular/material/theming';@import 'src/app/comp-a/comp-a.theme';@import 'src/app/comp-b/comp-b.theme';
@mixin custom-themes($theme) {  @include comp-a-theme($theme);  @include comp-b-theme($theme);}

Then import the above custom-theme.scss in your theme.scss:

然后将上面的custom-theme.scss导入您的theme.scss

// theme.scss...@import './custom-theme';@include custom-themes($my-theme);

This hierarchy works, and probably is the only way when you need to support multiple themes.

这种层次结构有效,并且可能是您需要支持多个主题的唯一方法。

However, most of the time we only support one theme, and using a mixin could be cumbersome. Mainly there are three disadvantages with this approach:

但是,大多数时候我们只支持一个主题,使用mixin可能很麻烦。 这种方法主要存在三个缺点:

  1. Every single color reference needs a separate .theme.scss file.

    每个单色参考都需要一个单独的.theme.scss文件。

  2. custom-theme.scss must know exactly which components provide custom themes. This creates unnecessary dependencies.

    custom-theme.scss必须准确知道哪些组件提供了自定义主题。 这将创建不必要的依赖关系。

  3. Most importantly, component level theme files are not encapsulated.

    最重要的是,未封装组件级主题文件。

The first and second points are pretty self-explanatory. Let me explain a little bit about point 3. This involves some background knowledge called “View Encapsulation”.

第一点和第二点很不言而喻。 让我对点3进行一些解释。这涉及一些称为“视图封装”的背景知识。

Angular uses a technique called “View Encapsulation” to keep component CSS local. In other words, rules defined for one component will stay in that component and will not affect other components.

Angular使用一种称为“ 视图封装 ”的技术将组件CSS保持在本地 。 换句话说,为一个组件定义的规则将保留在该组件中,并且不会影响其他组件。

In this way you can define CSS class name freely in your component without worrying about naming conflicts. However, view encapsulation is done only if the CSS is defined through @Component, i.e. @Component({ styleUrls: ['./comp-a.scss'] }).

这样,您可以在组件中自由定义CSS类名,而不必担心命名冲突。 但是,仅在通过@Component定义CSS的情况下才进行视图封装,即@Component({ styleUrls: ['./comp-a.scss'] })

As to our custom theme file comp-a.theme.scss, since it is imported directly by custom-theme.scss, its rules are not encapsulated so it will apply to all elements on the page. In the example above, I used the following code (which was WRONG!):

至于我们的自定义主题文件comp-a.theme.scss ,由于它是由custom-theme.scss直接导入的,因此其规则未封装,因此将适用于页面上的所有元素。 在上面的示例中,我使用了以下代码(错误!):

@mixin comp-a-theme($theme) {  button { ... }    // This will apply to ALL buttons!}

But this will apply the style to all the buttons instead of those buttons belonging to comp-a only. You have to do something like comp-a button in order to make this work correctly.

但这会将样式应用于所有按钮,而不是仅属于comp-a的那些按钮。 您必须执行诸如comp-a button的操作才能使其正常工作。

直接方法 (The direct approach)

Therefore I propose a better approach. Instead of using a mixin, we let each component include the theme file and use the color definition directly.

因此,我提出了一种更好的方法。 让每个组件都包括主题文件并直接使用颜色定义,而不是使用mixin。

In this approach, the component theme file will look like this:

用这种方法,组件主题文件将如下所示:

// NOTE: just do this in your regular scss file.// No need to create separate theme file!// src/app/comp-a/comp-a.scss@import 'src/theme.scss';
$primary: map-get($my-theme, primary);button {  background-color: mat-color($primary);}

And that’s all.

就这样。

Let’s see how this works. First, theme related rules are put into the component SCSS file, so no extra component level theme file required. Second, the main theme.scss does not need to know component level themes (since it does not need to import them), so a simple theme definition is adequate. Third, the component SCSS file is used with @Component so it is encapsulated correctly, which means we can simply define rules for button.

让我们看看它是如何工作的。 首先,将与主题相关的规则放入组件SCSS文件中,因此不需要额外的组件级主题文件。 其次,主theme.scss不需要知道组件级主题(因为它不需要导入它们),因此简单的主题定义就足够了。 第三,组件SCSS文件与@Component使用,因此它被正确封装,这意味着我们可以简单地为button定义规则。

预定义的主题键 (Predefined Theme Keys)

Probably you have noticed the next problem. What are the foreground, primary in above theme files ( map-get($my-theme, primary))? Are there any other keys I can use?

可能您已经注意到下一个问题。 上面的主题文件( map-get($my-theme, primary) )中的foregroundprimary是什么? 我还能使用其他任何键吗?

Well these “keys” refer to different colors defined in the theme. However I could not find any documents explaining these “keys”, so the only way I could find out is to read the source code. (Although it is said that good programmers should read the code, having to read the code is definitely not a good sign for a library.)

这些“键”指的是主题中定义的不同颜色。 但是,我找不到解释这些“键”的任何文档,所以我唯一能找到的方法就是阅读源代码 。 (尽管据说好的程序员应该阅读代码, 但是必须阅读代码绝对不是一个好的库。)

Open node_modules/@angular/material/_theming.scss and you will see the definitions for these keys. For future reference, I would like to summarize the keys here.

打开node_modules/@angular/material/_theming.scss ,您将看到这些键的定义。 为了将来参考,我想在这里总结一下按键。

$theme  |- primary  |- accent  |- warn  |- foreground  |   |- base  |   |- divider  |   |- dividers  |   |- disabled  |   |- disabled-button  |   |- disabled-text  |   |- hint-text  |   |- secondary-text  |   |- icon  |   |- icons  |   |- text  |   |- slider-min  |   |- slider-off  |   `- slider-off-active  |- background  |   |- status-bar  |   |- app-bar  |   |- background  |   |- hover  |   |- card  |   |- dialog  |   |- disabled-button  |   |- raised-button  |   |- focused-button  |   |- selected-button  |   |- selected-disabled-button  |   |- disabled-button-toggle  |   |- unselected-chip  |   `- disabled-list-option  `- is-dark         // bool, whether dark theme or not

For example, if you want to render a disabled text in your component, you may want to use the following code:

例如,如果要在组件中呈现禁用的文本,则可能需要使用以下代码:

$foreground: map-get($my-theme, foreground);.disabled-text {  color: mat-color($foreground, disabled-text);}

Okay these are some lessons I’ve learned from struggling with Angular Material. Hope this post is helpful if you are facing similar problems.

好的,这些是我从Angular Material的努力中学到的教训。 如果您遇到类似的问题,希望这篇文章对您有所帮助。

翻译自: https://www.freecodecamp.org/news/how-to-make-a-custom-theme-in-angular-material-d47122a1e361/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最感叹的莫过于一见如故,最悲伤的莫过于再见陌路。最深的孤独,是你明知道自己的渴望,却得对它装聋作哑。最美的你不是生如夏花,而是在时间的长河里,波澜不惊。...

最感叹的莫过于一见如故,最悲伤的莫过于再见陌路。最深的孤独,是你明知道自己的渴望,却得对它装聋作哑。最美的你不是生如夏花,而是在时间的长河里,波澜不惊。转载于:https://www.cnblogs.com/dj258/p/7003890.html

java vimrc_.vimrc技巧

-------------------------------------------------------------------" 设置字符编码。参考:http://www.rainux.org/blog/index.php/2005/10/20/106" encoding: Vim 内部使用的字符编码方式,包括 Vim 的buffer (缓冲区)、菜单文" 本、消…

将PDF和Gutenberg文档格式转换为文本:生产中的自然语言处理

Estimates state that 70%–85% of the world’s data is text (unstructured data). Most of the English and EU business data formats as byte text, MS Word, or Adobe PDF. [1]据估计,全球数据的70%–85%是文本(非结构化数据)。 大多数…

Go_笔试题记录-指针与值类型实现接口的区别

1、如果Add函数的调用代码为: func main() {var a Integer 1var b Integer 2var i interface{} &asum : i.(*Integer).Add(b)fmt.Println(sum) } 则Add函数定义正确的是() A.type Integer int func (a Integer) Add(b Integer) Intege…

leetcode 48. 旋转图像

解题思路 将数组从里到外分为若干层, 数组 [1,2,3], [4,5,6][7,8,9]的最外层即为 [1,2,3] [4 6][7,8,9] ,将一层分为4条边,如741 123,将741放到123的位置,123放到369的位置,如此类推(但是放置的…

如何恢复误删的OneNote页面

今天不小心把半个月的日记删掉了!(为了减少页面数量,每个月的日记会放在同一个页面上)。 幸运的是OneNote有自动备份功能,喜极而泣。 操作方法来自微软支持 打开丢失了最近笔记的笔记本。 单击“文件”>“信息”&g…

javascript函数式_JavaScript中的函数式编程原理

javascript函数式After a long time learning and working with object-oriented programming, I took a step back to think about system complexity.经过长时间的学习和使用面向对象的编程,我退后了一步来思考系统的复杂性。 “Complexity is anything that mak…

java writeint_Java DataOutputStream.writeInt(int v)类型

DataOutputStream.writeInt(int v)方法示例DataOutputStream的DataOutputStream.writeInt(int v)方法具有以下语法。public final void writeInt(int v) throws IOException示例在下面的代码中展示了如何使用DataOutputStream.writeInt(int v)方法。import java.io.DataInputSt…

协方差意味着什么_“零”到底意味着什么?

协方差意味着什么When I was an undergraduate student studying Data Science, one of my professors always asked the same question for every data set we worked with — “What does zero mean?”当我是一名研究数据科学的本科生时,我的一位教授总是对我们处…

Go_笔试题记录-不熟悉的

1、golang中没有隐藏的this指针,这句话的含义是() A. 方法施加的对象显式传递,没有被隐藏起来 B. golang沿袭了传统面向对象编程中的诸多概念,比如继承、虚函数和构造函数 C. golang的面向对象表达更直观,对…

leetcode 316. 去除重复字母(单调栈)

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。 注意:该题与 1081 https://leetcode-cn.com/problems/smallest-subsequenc…

Go-json解码到结构体

废话不多说,直接干就得了,上代码 package mainimport ("encoding/json""fmt" )type IT struct {Company string json:"company" Subjects []string json:"subjects"IsOk bool json:"isok"…

leetcode 746. 使用最小花费爬楼梯(dp)

数组的每个索引作为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi。 每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。 您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索…

安卓中经常使用控件遇到问题解决方法(持续更新和发现篇幅)(在textview上加一条线、待续)...

TextView设置最多显示30个字符。超过部分显示...(省略号)&#xff0c;有人说分别设置TextView的android:signature"true",而且设置android:ellipsize"end";可是我试了。居然成功了&#xff0c;供大家參考 [java] view plaincopy<TextView android:id…

网络工程师晋升_晋升为工程师的最快方法

网络工程师晋升by Sihui Huang黄思慧 晋升为工程师的最快方法 (The Fastest Way to Get Promoted as an Engineer) We all want to live up to our potential, grow in our career, and do the best work of our lives. Getting promoted at work not only proves that we hav…

java 银行存取款_用Java编写银行存钱取钱

const readline require(‘readline-sync‘)//引用readline-synclet s 2;//错误的次数for (let i 0; i < 3; i) {console.log(‘请输入名&#xff1a;(由英文组成)‘);let user readline.question();console.log(‘请输入密码&#xff1a;(由数字组成)‘);let password …

垃圾邮件分类 python_在python中创建SMS垃圾邮件分类器

垃圾邮件分类 python介绍 (Introduction) I have always been fascinated with Google’s gmail spam detection system, where it is able to seemingly effortlessly judge whether incoming emails are spam and therefore not worthy of our limited attention.我一直对Goo…

leetcode 103. 二叉树的锯齿形层序遍历(层序遍历)

给定一个二叉树&#xff0c;返回其节点值的锯齿形层序遍历。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。例如&#xff1a; 给定二叉树 [3,9,20,null,null,15,7],3/ \9 20/ \15 7 返回…

简单易用的MongoDB

从我第一次听到Nosql这个概念到如今已经走过4个年头了&#xff0c;但仍然没有具体的去做过相应的实践。最近获得一段学习休息时间&#xff0c;购买了Nosql技术实践一书&#xff0c;正在慢慢的学习。在主流观点中&#xff0c;Nosql大体分为4类&#xff0c;键值存储数据库&#x…

html画布图片不显示_如何在HTML5画布上显示图像

html画布图片不显示by Nash Vail由Nash Vail Ok, so here’s a question: “Why do we need an article for this, Nash?”好的&#xff0c;这是一个问题&#xff1a;“为什么我们需要为此写一篇文章&#xff0c;纳什&#xff1f;” Well, grab a seat.好吧&#xff0c;坐下…