CSSを使用しないでください.


導入


どうやってCSSで作るの?
あなたはそれを理論的かつ実質的にCSSで作ることができません.
これはCSSが対JSSを吸う理由の一つです.
確かに、JSSは反応でより多くの機能を持っています、しかし、2021年の誰がバニラJSを使っていますか?

JSSに関して


JSSは、JavaScriptを使用して宣言、コンフリクトフリー、再利用可能な方法でスタイルを記述することができます.これは、ブラウザ、サーバー側でコンパイルすることができますまたはノードのビルド時に.
JSSはフレームワーク不可知論です.これは、複数のパッケージで構成されます:コア、プラグイン、フレームワークの統合など.

JSSの特徴

  • 本当のCSS.
  • 衝突のないセレクタ.
  • コード再利用.
  • 除去の容易さと変更.
  • ダイナミックスタイル.
  • ユーザーコントロールのアニメーション.
  • 重要なCSS.
  • プラグイン.
  • 表現力のある構文.
  • 完全分離.
  • 反応統合.
  • ビルドパイプライン.
  • 例としての小規模プロジェクト


    環境設定


    スタック: nextjs , typescript , jss
    yarn create next-app --typescript
    
    yarn add react-jss jss-plugin-template jss-plugin-global jss-plugin-nested jss-plugin-camel-case jss-plugin-default-unit jss-plugin-compose
    
    もちろんJSSといくつかのプラグインを追加する必要があります.
    でファイルを作成するpages/_document.tsx ( SSRを設定する)
    import React from 'react';
    import Document, { Html, Head, Main, NextScript } from 'next/document';
    import { SheetsRegistry, JssProvider, createGenerateId } from 'react-jss';
    
    export default class MyDocument extends Document {
      render() {
        return (
          <Html lang={'en'}>
            <Head />
            <body>
              <Main />
              <NextScript />
            </body>
          </Html>
        );
      }
    }
    
    MyDocument.getInitialProps = async (ctx) => {
      const registry = new SheetsRegistry();
      const generateId = createGenerateId();
      const originalRenderPage = ctx.renderPage;
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            (
              <JssProvider registry={registry} generateId={generateId}>
                <App {...props} />
              </JssProvider>
            ),
        });
      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            <style id={'server-side-styles'}>{registry.toString()}</style>
          </>
        ),
      };
    };
    
    我々がここでするすべてのことctx.renderPage ツリー全体が要求を取得するよう手動でstylesheet .
    次のスニペットは、使用できるオプションを示しますctx.renderPage .
    その後フォルダを削除styles 現在では、CSSを必要としない.
    インpages/_app.tsx (実際の生活の中でJSSの例については、この話は、代わりに使用するこの構想を使用しないでくださいstate management util と別のレイアウトでプロバイダを分割する(いくつかの構造の瞬間について別の話を読むことができます)
    import type { AppProps } from 'next/app';
    import { useState } from 'react';
    import { ThemeProvider } from 'react-jss';
    
    const _App = ({ Component, pageProps }: AppProps) => {
      const initialTheme = {
        background: '#222222',
        text: '#e7f1fe',
      };
    
      const [theme, setTheme] = useState(initialTheme);
    
      return (
        <ThemeProvider theme={theme}>
          <Component {...pageProps} setTheme={setTheme} />
        </ThemeProvider>
      );
    };
    export default _App;
    
    だからここでラッピング<Component {...pageProps} setTheme={setTheme}/> with <ThemeProvider theme={theme}> そして、我々はフックで初期化しますuseState [theme, setTheme] だからファイルに移動する必要がありますpages/index.tsx
    として、我々は小道具を受け取るindex.tsx 書く必要があるtype どれが我々を受け取るかについて説明します
    type ThemeType = { [Property in 'background' | 'text']: string };
    type AppPropsType = {
     setTheme: Dispatch<SetStateAction<{ThemeType>> 
    };
    
    ここで追加ThemeType .
    最後に、JSSでスタイリングを追加しようとする
    const useStyles = createUseStyles(({ background, text }: ThemeType) => ({}));
    
    だから最初のparamでは、私たちのテーマのプロパティのアクセスを取得することができますし、より良いコードをこのparamsのタイプを与えることができます.
    そして、戻り値としてスタイリングコードを書きます.
    として追加jss-plugin-global デフォルトのブラウザスタイルを無効にする例として、global stylingを変更する機会があります'@global' 値付きで{ body: {padding: 0,margin: 0,},},少なくとも結果は
    const useStyles = createUseStyles(({ background, text }: ThemeType) => ({
      '@global': {
        body: {
          padding: 0,
          margin: 0,
        },
      },
    }));
    
    次に、いくつかのクラスを追加
      container: {
        background,
        color: text,
        width: '100vw',
        height: '100vh',
        font: { family: 'monospace', size: 20 },
      },
    
    ご覧のように、FonFamilmやFontSizeを書く必要はありません.
    我々は、キーを持つオブジェクトで簡単に構造化することができますfont .
    そして、App コンポーネント、私たちはuseStyles そば
     const { container } = useStyles();
     return <div className={container}>App</div>;
    
    このファイルの全てのコード
    import { SetStateAction } from 'react';
    import { Dispatch, FC } from 'react';
    import { createUseStyles } from 'react-jss';
    
    type ThemeType = { [Property in 'background' | 'text']: string };
    type AppPropsType = { setTheme: Dispatch<SetStateAction<ThemeType>> };
    
    const useStyles = createUseStyles(({ background, text }: ThemeType) => ({
      '@global': {
        body: {
          padding: 0,
          margin: 0,
        },
      },
      container: {
        background,
        color: text,
        width: '100vw',
        height: '100vh',
        font: { family: 'monospace', size: 20 },
      },
    }));
    
    const App: FC<AppPropsType> = () => {
      const { container } = useStyles();
      return <div className={container}>App</div>;
    };
    export default App;
    
    コマンドでこの部分をテストします
    yarn dev
    
    我々のテーマを設定すると、我々は(暗い背景と白いテキストの色)を持つ必要があります

    確かに、u easyly CSSでこれを行うことができますはい、そう今すぐ高度な機能になります
    私たちは
    const CENTERED_FLEX_CONTAINER = 'centered-flex-container'
    
    したがって、我々はそれを使用することができます
      [CENTERED_FLEX_CONTAINER]: {
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      },
    
    そして、我々はプラグインを追加するためにjss-plugin-compose 私たちは
    container: {
        composes: [`$${CENTERED_FLEX_CONTAINER}`],
        //other code
    },
    
    参照killer-feature ランダムな色、関数を生成する関数を作成する必要があります.
      const toGetRandomColor = () => `#${Math.random().toString(16).substr(-6)}`;
    
    フック付きuseEffect すべての反復で新しい色を設定する
      const [color, setColor] = useState(theme.text);
    
      useEffect(() => {
        const interval = setInterval(() => {
          setColor(toGetRandomColor());
        }, 420);
        return () => clearInterval(interval);
      }, []);
    
    それから我々はランダムな色を貼り付ける必要がありますuseStyles
    const { container } = useStyles({ color } as any);
    
    そして、usestylesで新しいクラスを加えます
    colorContainer: ({ color }: any) => ({ color })
    
    ので、少なくとも0.42秒では、我々は更新されたクラスを参照してくださいので、devのツールでは、インラインスタイル、クラスが動的に変化する値を絶対的に素晴らしいことを見ることができますので、我々のテーマを動的に変更することができますtheme 私たちはこれを行うことができますuseTheme フック
    後に、配列が必要ですtheme keys それで
      const themeKeysArr = Object.keys(theme) as (keyof ThemeType)[];
    
    したがって、JSXで簡単な入力構造を追加できます
     {themeKeysArr.map((name) => {
       return (
         <input value={theme[name]} placeholder={name.toUpperCase()} onChange={onChange} name={name} key={name} />
        );
      })}
    
    その後、いくつかのスタイリングを入力に追加します
      inputsContainer: {
        margin: [8, 0, 0, 0],
        padding: 10,
        '& input': {
          outline: 'none',
          border: '1px solid',
          borderRadius: 8,
          padding: [6, 8],
          margin: [0, 4],
          color: text,
          background: 'transparent',
        },
      },
    
    JSSで& と同じ論理を持つSass , 使用[8, 0, 0, 0] 設定することができます( margintop - 8 ,マージン(右, vbottom , left )は0に等しい).
    次にクラスを追加container このスタイリングで
      contentContainer: {
        composes: [`$${CENTERED_FLEX_CONTAINER}`],
        flex: { direction: 'column' },
      }
    
    最後に更新jsx このコードの一部
        <div className={`${container} ${colorContainer}`}>
          <div className={contentContainer}>
            <div>STOP USE CSS, USE JSS INSTEAD.</div>
            <div className={inputsContainer}>
              {themeKeysArr.map((name) => {
                return (
                  <input value={theme[name]} placeholder={name.toUpperCase()} onChange={onChange} name={name} key={name} />
                );
              })}
            </div>
          </div>
        </div>
    
    確かに他のクラスを破壊する必要があります.const { container, contentContainer, inputsContainer, colorContainer } = useStyles({ color } as any); マルチクラスを追加するには ( ES 6構文)少なくともこのようなことがあります.
    最後のコード
    import { ChangeEventHandler, SetStateAction, useEffect, useState } from 'react';
    import { Dispatch, FC } from 'react';
    import { createUseStyles, useTheme } from 'react-jss';
    
    type ThemeType = { [Property in 'background' | 'text']: string };
    type AppPropsType = { setTheme: Dispatch<SetStateAction<ThemeType>> };
    
    const CENTERED_FLEX_CONTAINER = 'centered-flex-container';
    
    const useStyles = createUseStyles(({ background, text }: ThemeType) => ({
      '@global': {
        body: {
          padding: 0,
          margin: 0,
        },
      },
      [CENTERED_FLEX_CONTAINER]: {
        display: 'flex',  <div className={`${container} ${colorContainer}`}>
          <div className={contentContainer}>
            <div>STOP USE CSS, USE JSS INSTEAD.</div>
            <div className={inputsContainer}>
              {themeKeysArr.map((name) => {
                return (
                  <input value={theme[name]} placeholder={name.toUpperCase()} onChange={onChange} name={name} key={name} />
                );
              })}
            </div>
          </div>
        </div>
        alignItems: 'center',
        justifyContent: 'center',
      },
    
      container: {
        composes: `$${CENTERED_FLEX_CONTAINER}`,
        background,
        font: { family: 'monospace', size: 20 },
        width: '100vw',
        height: '100vh',
      },
    
      colorContainer: ({ color }: any) => ({ color }),
    
      contentContainer: {
        composes: [`$${CENTERED_FLEX_CONTAINER}`],
        flex: { direction: 'column' },
      },
    
      inputsContainer: {
        margin: [8, 0, 0, 0],
        padding: 10,
        '& input': {
          outline: 'none',
          border: '1px solid',
          borderRadius: 8,
          padding: [6, 8],
          margin: [0, 4],
          color: text,
          background: 'transparent',
        },
      },
    }));
    
    const App: FC<AppPropsType> = ({ setTheme }) => {
      const theme = useTheme<ThemeType>();
      const [color, setColor] = useState(theme.text);
    
      const toGetRandomColor = () => `#${Math.random().toString(16).substr(-6)}`;
    
      useEffect(() => {
        const interval = setInterval(() => {
          setColor(toGetRandomColor());
        }, 420);
        return () => clearInterval(interval);
      }, []);
    
      const { container, contentContainer, inputsContainer, colorContainer } = useStyles({ color } as any);
    
      const onChange: ChangeEventHandler<HTMLInputElement> = ({ target: { value, name } }) => {
        setTheme((state) => ({ ...state, [name]: value }));
      };
      const themeKeysArr = Object.keys(theme) as (keyof ThemeType)[];
    
      return (
        <div className={`${container} ${colorContainer}`}>
          <div className={contentContainer}>
            <div>STOP USE CSS, USE JSS INSTEAD.</div>
            <div className={inputsContainer}>
              {themeKeysArr.map((name) => {
                return (
                  <input value={theme[name]} placeholder={name.toUpperCase()} onChange={onChange} name={name} key={name} />
                );
              })}
            </div>
          </div>
        </div>
      );
    };
    export default App;
    

    結論


    JSSのすべての機能のほんの一部は、この小さな例では、大きな機会を与えるとJSSを理解することができます.
  • Official docs
  • Example code (gitHub)
  • 読んでくれてありがとう♥.