Dojo 樣式進階

翻譯自:https://github.com/dojo/frame...css

Dojo 中的樣式和主題

Dojo 部件最適合做爲簡單的組件,每一個組件處理單一職責。它們應該儘量的封裝和模塊化,以提升可重用性,同時避免與應用程序使用的其餘組件出現衝突。html

可使用常規的 CSS 爲部件設置樣式,可是爲了達到封裝和複用的目標,每一個部件應該維護各自的 CSS 模塊(CSS module),該模塊與部件的源代碼存放在各自的文件中。這樣就能夠獨立地設置各部件的樣式,而不會與應用程序其餘地方使用的類名衝突。node

Dojo 界定出如下幾類樣式,每一類都表明了企業 web 應用程序中的樣式需關注的不一樣方面和粒度:git

如上述列表所示,不管是跨整個應用程序,仍是單個樣式類中的單條樣式規則,Dojo 爲應用程序開發者提供了幾種互相補充的機制來提供或重寫 CSS 樣式類。瀏覽器

部件的結構樣式

Dojo 藉助 CSS Modules,既提供了 CSS 的全部靈活性,又引入了本地化樣式類的額外優點,防止大型應用程序中無心間的樣式衝突。Dojo 也爲每一個 CSS 模塊生成類型定義文件,容許部件用與導入其餘 TypeScript 模塊類似的方式來導入 CSS 模塊,並以類型安全的方式引用 CSS 類名,同時在設計期間可使用 IDE 自動完成功能。安全

部件的 CSS 模塊文件應該使用 .m.css 擴展名,並約定 CSS 模塊的文件名要與關聯的部件名保持一致。具備此擴展名的文件會被看成 CSS 模塊來處理,而不是普通的 CSS 文件。

示例

如下是部件的 CSS 模塊文件:

src/styles/MyWidget.m.css
.myWidgetClass {
    font-variant: small-caps;
}

.myWidgetExtraClass {
    font-style: italic;
}

在對應的部件中使用此樣式,以下所示:

src/widgets/MyWidget.ts
import { create, tsx } from '@dojo/framework/core/vdom';

import * as css from '../styles/MyWidget.m.css';

const factory = create();

export default factory(function MyWidget() {
    return <div classes={[css.myWidgetClass, css.myWidgetExtraClass]}>Hello from a Dojo widget!</div>;
});

在構建的應用程序中查看示例部件中的 CSS 類時,它們不會直接包含 myWidgetClassmyWidgetExtraClass,而是通過混淆處理的 CSS 類名,相似於 MyWidget-m__myWidgetClass__33zN8MyWidget-m__myWidgetExtraClass___g3St

混淆後的類名專用於 MyWidget 元素,而這是由 Dojo 的 CSS 模塊化構建流程決定的。有了這種機制,則同一個應用程序的其餘部件也可使用 myWidgetClass 類名,即便具備不一樣的樣式規則,也不會在每組樣式間出現任何衝突。

警告: 混淆處理的 CSS 類名是不穩定的,可能會隨着應用程序的構建而更改,因此開發人員不能顯式地引用它們(例如試圖在應用程序的其餘位置定位一個元素)。

提取和擴展樣式

CSS 自定義屬性

Dojo 可使用現代的 CSS 特性,例如自定義屬性和 var(),來提取和集中管理應用程序中的通用樣式屬性。

沒必要在每一個部件的 CSS 模塊中爲顏色或字體設置相同的值,而是經過提取自定義屬性,在每一個 CSS 模塊中引用該屬性名,而後在集中一處的 CSS :root 僞類中設置值。這種隔離更易於維護跨整個應用程序的公共樣式。

例如:

src/themes/variables.css
:root {
    /* different sets of custom properties can be used if an application supports more than one possible theme */
    --light-background: lightgray;
    --light-foreground: black;

    --dark-background: black;
    --dark-foreground: lightgray;

    --padding: 32px;
}
src/themes/myDarkTheme/MyWidget.m.css
@import '../variables.css';

.root {
    margin: var(--padding);

    color: var(--dark-foreground);
    background: var(--dark-background);
}

注意,在一個頁面中,:root 僞類是全局的,可是由於 Dojo 使用了 CSS 模塊,則可能會在應用程序的多處指定 :root 屬性。可是 Dojo 沒法保證 CSS 模塊的處理順序,所以爲了確保 :root 中屬性的一致性,建議在應用程序的代碼中只有一處 :root 定義,統一放在 variables.css 文件中。這個集中存放的變量文件是一個常規的 CSS 文件(不是一個 CSS 模塊),當 CSS 模塊須要使用自定義屬性值時,可使用 @import 導入。

Dojo 默認的構建流程按原樣將自定義屬性輸出到應用程序的樣式表中。對於最新的瀏覽器來講,這樣作沒有問題;但當使用的瀏覽器沒有實現 CSS 自定義屬性標準(如 IE)時,就會出現問題。爲了解決這個問題,可使用遺留模式(dojo build app --legacy)來構建應用程序,這種狀況下,Dojo 會在構建期間解析自定義屬性的值,並複製到輸出的樣式表中。一個值將包含原來的 var() 引用,第二個值是專爲舊版瀏覽器解析的值,當沒法處理 var() 時就使用解析後的值。

CSS 模塊的組合功能

將主題應用到 Dojo 部件後,部件的默認樣式類會徹底被主題提供的樣式類覆蓋。當只須要經過主題修改樣式類中的一部分屬性,而其他屬性依然使用默認值時,就會出現問題。

Dojo 應用程序中的 CSS 模塊文件可使用 composes: 功能將樣式從一個類選擇器應用到另外一個類選擇器。當經過調整現有的主題來建立一個新主題時,或者在單個主題中提取通用的樣式屬性時(注意,提取單個屬性的值是更標準的作法是 CSS 自定義屬性),這個功能是頗有用的。

警告: composes: 功能可能會比較脆弱,例如當擴展一個不受當前應用程序控制的第三方主題時。第三方主題所作的任何更改,均可能會破壞基於 composes 功能的應用程序主題,且這樣的破壞很難定位和解決。

可是,在大型應用程序中仔細使用此功能會頗有用。好比,集中管理一組公共屬性:

src/themes/common/ButtonBase.m.css
.buttonBase {
    margin-right: 10px;
    display: inline-block;
    font-size: 14px;
    text-align: left;
    background-color: white;
}
src/themes/myBlueTheme/MyButton.m.css
.root {
    composes: buttonBase from '../common/ButtonBase.m.css';
    background-color: blue;
}

Dojo 樣式最佳實踐

因爲 Dojo 應用程序中的樣式主要是針對單個部件的,所以不須要使用複雜的選擇器。在 Dojo 中爲應用程序設置樣式時應儘量簡單,開發人員可經過如下幾條簡單的建議作到這一點:

  • 維護封裝的部件樣式

    • 一個 CSS 模塊應只解決一個問題。與部件一一對應的 CSS 模塊,一般只包含對應單個部件的樣式類。CSS 模塊也能夠被多個部件共享,好比應用程序定義一個跨整個應用程序的、公共的排版模塊。在 TypeScript 代碼中,部件引用多個 CSS 模塊也是一種常見的作法。
    • 不要在 CSS 模塊以外使用樣式類來引用部件,或者使用爲部件提供覆蓋樣式的主題來引用部件。
    • 不要依賴構建的應用程序中的樣式類名,由於 Dojo 會對類名作混淆處理。
  • Prefer class-level selector specificity
  • 優先使用類選擇器(class selector)

    • 不該使用類型選擇器(type selector),由於這樣作會破壞部件的封裝性,可能對使用相同元素類型的其餘部件產生負面影響。
    • 不該使用 id 選擇器(id selector)。Dojo 部件旨在封裝和複用,而使用元素的 id 違背此目標。Dojo 提供了其餘機制來加強或覆蓋特定部件實例的樣式,如部件的 classestheme 屬性。
  • 避免嵌套選擇器

    • 部件應該足夠簡單,只使用一個類選擇器。若是須要,部件也能使用多個、獨立的類來應用額外的樣式。單個部件也可使用定義在多個 CSS 模塊中的樣式。
    • 複雜的部件應該被重構爲一個簡單的父部件和多個簡單的子部件,這樣能夠爲單獨每一個部件封裝專用的樣式。
  • 避免使用 BEM 命名規範

    • 優先使用與部件的用途相關的類名
  • 避免使用 !important

Dojo 應用程序支持主題

Dojo 應用程序須要一種方法,來爲全部部件展現一致的外觀,這樣用戶就能夠總體地把握和使用應用程序功能,而不是認爲將東拼西湊的元素混搭在網頁中。這一般要根據公司或產品的營銷主題來指定顏色、佈局或字體等實現的。

製做支持主題的部件

考慮讓部件支持主題須要作兩方面的準備:

  1. 須要爲部件的工廠函數注入 theme 中間件,const factory = create({ theme })
  2. 渲染部件時,應該使用 theme.classes(css) 返回的一個或多個部件樣式類。

按慣例,當開發的部件須要分發時,還須要考慮第三點要求(Dojo 部件庫中的部件都遵循此約定):

  1. 部件的 VDOM 根節點(即部件渲染後的最外圍節點)應該包含一個名爲 root 的樣式類。這樣當在自定義主題中覆寫第三方可主題化部件的樣式時,就能以一致的方式定位到頂層節點。

theme 中間件是從 @dojo/framework/core/middleware/theme 模塊中導入的。

theme.classes 方法

theme.classes 將部件的 CSS 類名轉換應用程序或部件的主題類名。

theme.classes<T extends ClassNames>(css: T): T;
  • 注意事項1: 主題的重寫只在 CSS 類一級,而不是 CSS 類中的單個樣式屬性。
  • 注意事項2: 若是當前激活的主題沒有重寫給定的樣式類,則部件會退而使用該類的默認樣式屬性。
  • 注意事項3: 若是當前激活的主題的確重寫了給定的樣式類,則 只會 將主題中指定的 CSS 屬性應用到部件上。例如,若是部件的默認樣式類包含 10 個 CSS 屬性,可是當前的主題只指定了一個,則部件渲染時只會使用這一個 CSS 屬性,並丟掉在主題中未重寫的其餘 9 個屬性。

theme 中間件屬性

可主題化部件示例

下面是一個可主題化部件的 CSS 模塊文件:

src/styles/MyThemeableWidget.m.css
/* requirement 4, i.e. this widget is intended for wider distribution,
therefore its outer-most VDOM element uses the 'root' class: */
.root {
    font-family: sans-serif;
}

/* widgets can use any variety of ancillary CSS classes that are also themeable */
.myWidgetExtraThemeableClass {
    font-variant: small-caps;
}

/* extra 'fixed' classes can also be used to specify a widget's structural styling, which is not intended to be
overridden via a theme */
.myWidgetStructuralClass {
    font-style: italic;
}

在相應的可主題化的部件中使用這些樣式:

src/widgets/MyThemeableWidget.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import * as css from '../styles/MyThemeableWidget.m.css';

/* requirement 1: */
const factory = create({ theme });

export default factory(function MyThemeableWidget({ middleware: { theme } }) {
    /* requirement 2 */
    const { root, myWidgetExtraThemeableClass } = theme.classes(css);
    return (
        <div
            classes={[
                /* requirement 3: */
                root,
                myWidgetExtraThemeableClass,
                css.myWidgetExtraThemeableClass
            ]}
        >
            Hello from a themed Dojo widget!
        </div>
    );
});

使用多個 CSS 模塊

部件也能導入和引用多個 CSS 模塊,除了本指南的其它部分介紹的基於 CSS 的方法(CSS 自定義屬性CSS 模塊化組合功能)以外,這提供了另外一種經過 TypeScript 代碼來提取和複用公共樣式屬性的方法。

擴展上述示例:

src/styles/MyThemeCommonStyles.m.css
.commonBase {
    border: 4px solid black;
    border-radius: 4em;
    padding: 2em;
}
src/widgets/MyThemeableWidget.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import * as css from '../styles/MyThemeableWidget.m.css';
import * as commonCss from '../styles/MyThemeCommonStyles.m.css';

const factory = create({ theme });

export default factory(function MyThemeableWidget({ middleware: { theme } }) {
    const { root } = theme.classes(css);
    const { commonBase } = theme.classes(commonCss);
    return <div classes={[root, commonBase, css.myWidgetExtraThemeableClass]}>Hello from a themed Dojo widget!</div>;
});

重寫部件實例的主題

部件的使用者能夠將一個有效的主題傳給部件實例的 theme 屬性,來重寫特定部件實例的主題。當須要在應用程序的不一樣部分以多種方式顯示給定的部件時,這個功能就能派上用場。

例如,在可主題化部件示例的基礎上構建:

src/themes/myTheme/styles/MyThemeableWidget.m.css
.root {
    color: blue;
}
src/themes/myThemeOverride/theme.ts
import * as myThemeableWidgetCss from './styles/MyThemeableWidget.m.css';

export default {
    'my-app/MyThemeableWidget': myThemeableWidgetCss
};
src/widgets/MyApp.tsx
import { create, tsx } from '@dojo/framework/core/vdom';

import MyThemeableWidget from './src/widgets/MyThemeableWidget.tsx';
import * as myThemeOverride from '../themes/myThemeOverride/theme.ts';

const factory = create();

export default factory(function MyApp() {
    return (
        <div>
            <MyThemeableWidget />
            <MyThemeableWidget theme={myThemeOverride} />
        </div>
    );
});

此處,渲染了兩個 MyThemeableWidget 實例,若是指定了應用程序範圍的主題,則第一個部件會使用此主題,不然使用部件的默認樣式。相比之下,第二個部件始終使用 myThemeOverride 中定義的主題。

爲部件傳入額外的樣式

主題機制提供了一種簡便的方式,爲應用程序中的每一個部件統一應用自定義樣式,但當用戶但願爲給定的部件實例應用額外的樣式時,在這種場景下主題機制就不夠靈活。

能夠經過可主題化部件的 classes 屬性來傳入額外的樣式類。這些樣式類是追加的,不會重寫部件已有的樣式類,它們的目的是對已經存在的樣式進行細粒度的調整。提供的每一組額外的樣式類都須要按照兩個級別的 key 進行分組:

  1. 合適的部件主題 key,用於指定應用樣式類的部件,包括其中的任何子部件。
  2. 小部件使用的某個已存在的 CSS 類,部件使用者能夠在單個 DOM 元素上擴展樣式,一個部件上可擴展多個樣式。

例如,額外的樣式類屬性的類型定義爲:

type ExtraClassName = string | null | undefined | boolean;

interface Classes {
    [widgetThemeKey: string]: {
        [baseClassName: string]: ExtraClassName[];
    };
}

做爲一個提供額外樣式類的示例,下面調整 Dojo combobox 實例,以及其中的子部件 text input。此操做會將 combobox 使用的 text input 控件的背景色以及其自身面板的背景色改成藍色。combobox 控件面板中的下拉箭頭也會變爲紅色:

src/styles/MyComboBoxStyleTweaks.m.css
.blueBackground {
    background-color: blue;
}

.redArrow {
    color: red;
}
src/widgets/MyWidget.tsx
import { create, tsx } from '@dojo/framework/core/vdom';

import ComboBox from '@dojo/widgets/combobox';
import * as myComboBoxStyleTweaks from '../styles/MyComboBoxStyleTweaks.m.css';

const myExtraClasses = {
    '@dojo/widgets/combobox': {
        controls: [myComboBoxStyleTweaks.blueBackground],
        trigger: [myComboBoxStyleTweaks.redArrow]
    },
    '@dojo/widgets/text-input': {
        input: [myComboBoxStyleTweaks.blueBackground]
    }
};

const factory = create();

export default factory(function MyWidget() {
    return (
        <div>
            Hello from a tweaked Dojo combobox!
            <ComboBox classes={myExtraClasses} results={['foo', 'bar']} />
        </div>
    );
});

注意,部件的做者負責顯式地將 classes 屬性傳給全部的要使用樣式類的子部件,由於 Dojo 自己沒法將這個屬性注入給或自動傳給子部件。

製做支持主題的應用程序

要爲應用程序中全部可主題化的部件指定一個主題,可在應用程序頂層部件中使用 theme 中間件中的 theme.set API。要設置默認的或初始的主題,則在調用 theme.set 以前要先使用 theme.get 進行確認。

例如,爲應用程序設置一個初始主題:

src/App.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import myTheme from '../themes/MyTheme/theme';

const factory = create({ theme });

export default factory(function App({ middleware: { theme }}) {
    // if the theme isn't set, set the default theme
    if (!theme.get()) {
        theme.set(myTheme);
    }
    return (
        // the application's widgets
    );
});

有關導入的 myTheme 結構說明,請參考編寫主題

請注意,使用可主題化的部件時,若是沒有顯示指定主題(例如,沒有使用 theme.set 設置一個默認主題,也沒有顯式地重寫部件實例的主題或樣式類),則每一個部件都使用默認的樣式規則。

若是使用一個徹底獨立分發的主題(/learn/styling/working-with-themes#distributing-themes),應用程序還須要將囊括主題的 index.css 文件集成到自身的樣式中來。在項目的 main.css 文件中導入。

src/main.css
@import '@{myThemePackageName}/{myThemeName}/index.css';

與之相比,另外一種使用外部構建主題的部份內容的方法是經過主題組合功能(/learn/styling/working-with-themes#composing-off-dojo-themes)實現的。

更改當前激活的主題

theme 中間件中的 .set(theme) 函數用於在整個應用程序級別更改當前激活的主題。爲 .set 傳入所需的主題,這將讓應用程序樹中全部可主題化的部件失效,並使用新的主題從新渲染。

src/widgets/ThemeSwitcher.tsx
import { create, tsx } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';

import myTheme from '../themes/MyTheme/theme';
import alternativeTheme from '../themes/MyAlternativeTheme/theme';

const factory = create({ theme });

export default factory(function ThemeSwitcher({ middleware: { theme } }) {
    return (
        <div>
            <button
                onclick={() => {
                    theme.set(myTheme);
                }}
            >
                Use Default Theme
            </button>
            <button
                onclick={() => {
                    theme.set(alternativeTheme);
                }}
            >
                Use Alternative Theme
            </button>
        </div>
    );
});

使用主題

部件的主題 key

Dojo 的主題框架使用「部件主題 key」 概念將重寫的樣式與對應部件的相關樣式關聯。覆蓋的樣式一般在主題中指定;但若是須要,也能夠直接傳給 theme 中間件的 classes 屬性

一個部件的主題 key 的確切格式爲:

{package-name}/{widget-css-module-name}

其中 package-name 是項目 package.jsonname 屬性的值,widget-css-module-name 是部件使用的主 CSS 模塊的文件名(_不包括_ .m.css 擴展名)。

主題 key 示例

給定以下項目:

package.json
{
    "name": "my-app"
}

遵循部件的 CSS 模塊命名規範時,一個 src/widgets/MyWidget.ts 使用的 CSS 模塊名相似於 src/styles/MyWidget.m.css。所以 MyWidget 的主題 key 爲:

my-app/MyWidget

此處,部件的名稱與其 CSS 模塊文件的名稱相同,可是開發人員要注意,不要將部件的主題 key 誤認爲就是部件的 TypeScript 類名。

再看第二個部件,沒有遵循 CSS 模塊的命名規範,如 src/widgets/BespokeWidget.ts 使用的 CSS 模塊爲 src/styles/BespokeStyleSheet.m.css,則部件的主題 key 應改成:

my-app/BespokeStyleSheet

編寫主題

主題就是一個 TypeScript 模塊,會導出一個默認對象,其中將部件主題 key 映射到導入的類型化的 CSS 模塊上。主題中的 CSS 模塊與部件直接使用的常規模塊相同。一旦應用程序應用了主題,則主題定義對象中的主題 key 標識的每個部件的樣式,都會被主題 key 對應的 CSS 模塊中的樣式覆蓋。

如下是 MyWidget 部件完整主題中的一個簡單示例(使用默認的 CSS 模塊 MyWidget.m.css),位於 my-app 項目中:

src/themes/myTheme/styles/MyWidget.m.css
.root {
    color: blue;
}
src/themes/myTheme/theme.ts
import * as myThemedWidgetCss from './styles/MyWidget.m.css';

export default {
    'my-app/MyWidget': myThemedWidgetCss
};

此處,MyWidget 遵循命名規範,將主樣式類命名爲 root,這樣 myTheme 就能夠被 src/themes/myTheme/styles/MyWidget.m.css CSS 模塊中的 root 類覆蓋掉。

經過主題 key my-app/MyWidget,主題將新的 root 樣式類關聯到 MyWidget 上。當應用 myTheme 主題後,MyWidget 會將其顏色設置爲藍色,且不會再接收其初始 CSS 模塊的 root 類中定義的其餘樣式。

爲第三方部件搭建主題

應用程序的主題可能須要包含第三方部件使用的樣式,好比Dojo 自帶部件庫中提供的樣式。

@dojo/cli-create-theme 中提供了一些工具,使用 dojo create theme CLI 命令,能爲第三方部件快速生成主題腳手架。可經過如下方式在應用程序中安裝:

npm install --save-dev @dojo/cli-create-theme

而後在項目根目錄下按以下方式使用:

dojo create theme -n {myThemeName}

運行此命令,會在詢問兩個問題後開始建立 myThemeName 主題:

  • What Package to do you want to theme?

    • 答案應該是包含第三方部件的全部包,如 @dojo/widgets。本命令會繼續詢問更多的包,直到用戶結束此操做。
  • Which of the {third-party-package} theme files would you like to scaffold?

    • 在回答第一個問題時,會顯示第三方包中全部可主題化的部件。而後用戶在其中選擇一部分兼容的部件包含到輸出的主題中,一般只選擇在當前應用程序中實際用到的部件,確保主題足夠小。

命令成功執行後,會在當前項目中建立幾個文件:

  • src/themes/{myThemeName}/theme.ts
  • src/themes/{myThemeName}/{third-party-package}/path/to/{selectedWidget}.m.css

爲全部 {selectedWidget} 建立的主題 CSS 模塊都提供了可主題化的 CSS 選擇器,而後就能夠爲 {myThemeName} 填充合適的樣式規則。

兼容的包

任何包含 theme 目錄的第三方包都是兼容的,其中既包含部件的 CSS 模塊文件(*.m.css),也包含對應的編譯後的定義文件(*.m.css.js - 詳情參見分發主題)。

例如:

node_modules
└── {third-party-package}
    └── theme
        │   {widget}.m.css
        │   {widget}.m.css.js

分發主題

Dojo 的 cli-build-theme 提供了一個 CLI 命令,構建的主題可分發給多個應用程序使用。它會建立出以各類不一樣方式使用主題所需的全部文件

注意,當使用 dojo create theme 搭建新的主題時,並不須要使用 dojo build theme,由於全部相關文件都已就位。這主要用於使用 @dojo/cli-build-app@dojo/cli-build-widget 構建項目時來構建主題。

要使用此工具,在須要主題化的項目下安裝 @dojo/cli-build-theme

npm install --save-dev @dojo/cli-build-theme

而後構建主題,請運行命令,並指定一個主題名以及一個可選的發佈版本號:

dojo build theme --name={myThemeName} --release={releaseVersion}

若是沒有指定 release,則會使用 package.json 中的當前版本號。

運行該命令後,會在項目中建立一個 dist/src/{myThemeName} 文件夾,其中包含:

使用 Dojo 提供的主題

@dojo/themes 包提供了一組當即可用的主題,涵蓋了 Dojo 自帶部件庫的全部部件。能夠按原樣使用主題庫,或者做爲基礎組合出完整的應用程序主題。

  1. 要使用主題,在項目中安裝 @dojo/themes,好比使用 npm i @dojo/themes 命令。而後,對於常規的 Dojo 應用程序:
  2. 在項目的 main.css 文件中導入主題的 CSS 文件:

    @import '~@dojo/themes/dojo/index.css';
  3. 導入主題的 TypeScript 模塊,而後使用:

    import theme from '@dojo/themes/dojo';
    
    render() {
        return w(Button, { theme }, [ 'Hello World' ]);
    }

若是嘗試在 Custom elements 中使用它,則安裝完 @dojo/themes 以後:

  1. index.html 中添加 Custom elements 專用的主題 CSS 文件:

    <link rel="stylesheet" href="node_modules/@dojo/themes/dojo/dojo-{version}.css" />
  2. index.html 中添加 Custom elements 專用的主題 JS 文件:

    <script src="node_modules/@dojo/themes/dojo/dojo-{version}.js"></script>

擴展 Dojo 主題

一旦在項目中安裝了 @dojo/themes,就可將其做爲擴展應用程序主題的基礎,在新的主題中使用 CSS 模塊化的組合功能來包含相關的組件。

@dojo/themes 中也包含一個 擁有 :rootvariables.css 文件,若是擴展的應用程序主題須要在新主題的某處引用 Dojo 內置的屬性,則能夠導入該文件。

下面是一個 @dojo/widgets/button 使用新主題的示例,擴展自 @dojo/themes,將按鈕的背景色改成綠色,而其餘的主題樣式屬性保持不變:

src/themes/myTheme/theme.ts
import * as myButton from './myButton.m.css';

export default {
    '@dojo/widgets/button': myButton
};
src/themes/myTheme/myButton.m.css
@import '@dojo/themes/dojo/variables.css';

.root {
    composes: root from '@dojo/themes/dojo/button.m.css';
    background-color: var(--dojo-green);
}
相關文章
相關標籤/搜索