ダイナミックCSSテーマ


インスピレーション


私は、いくつかのデザインシステムがプラットホーム不可知であるために構築されるので、JSでCSSの代わりにグローバルCSS 3変数を使用しているテーマシングルページアプリケーション(SPA)アプリを学ぶ方法を学びたかったです.私はエルムを使用しているので、誰かが私にそれを専門的に使用するまで私の好きな趣味の言語ですので😎

仕様


あなたが前にCSSテーマをしたことがないならば、心配しないでください-それは驚くほど簡単です.我々は1つのボタンを画面に集中し、テキストをクリックして起動する必要がありますテーマを活性化するユーザーに通知する必要があります.ユーザーがテーマを切り替えることができる回数の制限はありません.デフォルトのテーマは“solarizedライト”です.通常、あなたのアプリケーションは、データベースに格納するか、ローカルキャッシュに格納することによってユーザー選択を覚えていますが、このデモではありません.と言えば、ライブデモで遊ぶことができますhere !
注意:あなたがそれを持っているならば、必ず暗いリーダークロム拡張をオフにしてください.

コード


第一に、我々はデフォルトでテーマの色を設定する必要があります:root CSS擬似クラスhere ) と.dark テーマが「ソーラードダーク」に変更されたときのオーバーライドのクラスです.
:root {
  --theme-background: #fdf6e3;
  --theme-selection-background: #ece7d5;
  --theme-foreground: #657a81;
  --theme-accent1: #2aa198;
  --theme-accent2: #b58900;
}

.dark {
  --theme-background: #002b36;
  --theme-selection-background: #073642;
  --theme-foreground: #b58900;
  --theme-accent1: #d33682;
  --theme-accent2: #268bd2;
}
次に、ELMは、現在のテーマが何であるかを知る必要があるHTMLをレンダリングする責任があります.この状態は、変更テーマボタンのレンダリングロジック内のテキストを変更するために使用されます.それで、我々の単純なドメインをモデル化して、我々のユビキタス言語を決定しましょう.
オプション1 :
アクション→ トグルテーマ
type alias Model =
    Bool

type Msg
    = ToggleTheme Bool
オプション2 :
アクション→ 変化テーマ
type Theme
    = SolarizedLight
    | SolarizedDark

type alias Model =
    Theme

type Msg
    = ChangeTheme Theme
どちらかのオプションが動作しますが、私は、和タイプは、よりエレガントで拡張可能なので、視覚障害者のための高コントラストモードなどのより多くのテーマを追加する必要がありますので、オプション2と一緒に行って、私たちのボタンレンダリングロジックを作成しましょう.
themeButton : Model -> Html Msg
themeButton model =
    case model of
        SolarizedDark ->
            button [ class "theme-btn", onClick (ChangeTheme SolarizedLight) ]
                [ text "Toggle Light" ]

        SolarizedLight ->
            button [ class "theme-btn", onClick (ChangeTheme SolarizedDark) ]
                [ text "Toggle Dark" ]
最後のビットは、古い古いJavaScriptを使用して、現在のテーマを反映するために、DOM上のCSSクラスを操作します.The .dark 以前に作成したクラスは、<body> 要素の色がオーバーライドします.ELMはDOMを直接操作することはできません(既に知っていたら)どうやってこれを行うのですか?
エンムエルムports — JS(JavaScript - AS - A)と対話するスマートな方法.ありがたいことに、これは我々が必要とするすべてのバニラJSです.
app.ports.changeTheme.subscribe(theme => {
    if (theme === "") {
        document.body.classList.remove("dark");
    } else {
        document.body.classList.add(theme);
    }
})
もう一つのビット.当社の更新機能を放送する必要がありますchangeTheme 我々がちょうど言ったメッセージ↑ それぞれのテーマで.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg _ =
    case msg of
        ChangeTheme theme ->
            case theme of
                SolarizedDark ->
                    ( SolarizedDark, changeTheme "dark" )

                SolarizedLight ->
                    ( SolarizedLight, changeTheme "" )

結論


その他のJavaScriptの言語には、JavaScriptの言語のようなJavaScriptのインターoptingについてのさまざまな哲学があります.私は今どんな権利に対しても議論をしていません、しかし、この小さな例は、EMMが信用できないコードを端に押しつける方法を強調します.

ハンスフフマン / ダイナミックCSSテーマ


CSS 3変数を使用して、テーマを動的に変更します。