Emotion & Styled-components


1.Emotion初期設定


次の例をテスト中に問題が発生しました...
${ChildDiv}{ background-color: red; }
このようなjsx構文では,@emotion/styledパッケージは認識できないようだ.
しかし1時間の除去を経て...解決完了...
まず、ルートフォルダで、以下の手順に従ってバーベルプラグインをインストールします.
  • yarn add --dev @emotion/babel-plugin
  • のフォルダにあります.babelrcファイルを作成したら、次の手順に従います.
  • {
        "presets": [
            [
                "next/babel",
                {
                    "preset-react": {
                        "runtime": "automatic",
                        "importSource": "@emotion/react"
                    }
                }
            ]
        ],
        "plugins": ["@emotion/babel-plugin"]
    }
  • 練習するjsファイルで設定:
  • /** @jsxImportSource @emotion/react */
    import { jsx } from "@emotion/react";
    import styled from "@emotion/styled";
    エラーが解決されました.
    グーグルのネット上を長い間うろうろしていたが、感情の公式文書の中で解決方法を見つけた.
    後で問題が発生したら、まず正式な書類を確認しなければなりません.

    2. Emotion vs Styled-components

  • npm-trendsから見ると、感情はスタイル成分よりも人気がある.
  • size比較


    容量感情がより楽です.
    でもグーグル検索の結果両者の性能に有意差はないという.

  • コード比較
  • styled-components
  • // CSS syntax in tagged template literal
    const Title = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: palevioletred;
    `
    render(<Title>Hiya!</Title>)
    
    // Object syntax
    const button = styled.button({
      fontSize: '1.5em',
      textAlign: 'center',
      color: 'palevioletred'
    });
  • emotion
  • // CSS syntax in tagged template literal
    
    const Button = styled.button`
      padding: 32px;
      background-color: hotpink;
      font-size: 24px;
      border-radius: 4px;
      color: black;
      font-weight: bold;
      &:hover {
        color: white;
      }
    `
    
    render(<Button>Hey! It works.</Button>)
    
    ---
    
    render(
      <h1
        className={css`
          font-size: 1.5em;
          text-align: center;
          color: palevioletred;
        `}
      >
        Hiya!
      </h1>
    )
    
    // Object syntax
    const titleStyles = css({
      fontSize: '1.5em',
      textAlign: 'center',
      color: 'palevioletred'
    })
    
    render(<h1 className={titleStyles}>Hiya!</h1>)
    Emotionでは、「consttitleStyles=css({})」などのクラス属性を追加できます.

    3.CS-IN-JSに詳しい

  • の最も基本的な使用例.
  • import styled from '@emotion/styled"'
    
    const MyDiv = styled.div`
    	width: 200px;
    	height: 200px;
    	background-color: red;
    	&:hover{
    		background-color: blue; 
    	}
    `
    &自分の役割を果たしています.
    上の意味はMyDiv:hoverです.
  • サブエレメントスタイル
  • /** @jsxImportSource @emotion/react */
    import { jsx } from "@emotion/react";
    import styled from "@emotion/styled";
    
    const ChildDiv = styled.div`
    	width: 100px;
    	height: 100px;
    	background-color: blue;
    `;
    const ParentDiv = styled.div`
    	width: 500px;
    	height: 400px;
    
    	${ChildDiv}{
    		background-color: red;
    	}
    `;
    
    const MyApp = () => {
    	return(
    		<>
    			<ParentDiv>
    				<ChildDiv></ChildDiv>
    			</ParentDiv>
    		</>
    	)
    }

    同様に、親ラベルでjsx構文を使用してサブラベルのプロパティを指定できます.
  • Global Styles
  • ルートパス/スタイル/リセットjs
    import { css, Global } from "@emotion/react";
    export const globalStyles = (
        <Global
            styles={css`
                * {
                    box-sizing: border-box;
                    padding: 0;
                    margin: 0;
                }
    
                html,
                body {
                    width: 100vw;
                    height: 100vh;
                    font-size: 16px;
                }
            `}
        />
    );
    
    ルートパス/pages/app.js
    /** @jsxImportSource @emotion/react */
    // ... 생략 ... //
    import { globalStyles } from "../styles/reset";
    function MyApp({ Component, pageProps }) {
    	// ... 생략 ... //
        return (
            <ApolloProvider client={client}>
                {globalStyles}
                <Component {...pageProps} />
            </ApolloProvider>
        );
    }
    export default MyApp;
    {globalStyles}아래의 모든 하위 컴포넌트에 글로벌하게 스타일이 적용된다.
  • Extend -1
  • /** @jsxImportSource @emotion/react */
    import { jsx } from "@emotion/react";
    import styled from "@emotion/styled";
    
    const MyButton = styled.button`
        font-size: 23px;
        border: none;
    `;
    const BlackButton = styled(MyButton)`
        background-color: black;
        color: white;
    `;
    const RedButton = styled(MyButton)`
        background-color: red;
        color: blue;
    `;
    
    const MyApp = () => {
        return (
            <>
                <BlackButton>클릭</BlackButton>
                <RedButton>클릭</RedButton>
            </>
        );
    };
    export default MyApp;
    

    RedButtonにMyButtonスタイルが適用されていることが確認できます.
  • Extend -2
  • /** @jsxImportSource @emotion/react */
    import { jsx } from "@emotion/react";
    import styled from "@emotion/styled";
    
    const MyFont = styled.p`
        font-size: 24px;
        font-weight: bold;
    `;
    
    const MyItalicFont = styled(MyFont.withComponent("span"))`
        font-style: italic;
        font-weight: normal;
    `;
    
    const MyApp = () => {
        return (
            <>
                <MyFont>p</MyFont>
                <MyItalicFont>span</MyItalicFont>
            </>
        );
    };
    export default MyApp;

    MyFontスタイルを継承すると同時に、p->spanラベルに変換して、コードの作成をスムーズにすることもできます.
  • Extend -3
  • /** @jsxImportSource @emotion/react */
    import { jsx } from "@emotion/react";
    import styled from "@emotion/styled";
    
    const MyFont = styled.p`
        font-size: 24px;
        font-weight: bold;
    `;
    
    const MyApp = () => {
        return (
            <>
                <MyFont as={"span"}>p</MyFont>
            </>
        );
    };
    export default MyApp;

    コードの可読性が良くなり、変数宣言を減らすことができるので、いい感じです.
  • Extend -4
    混入は、複数のコンポーネント間で共通の論理または機能を再利用する方法を定義します.
  • /** @jsxImportSource @emotion/react */
    import { jsx, css } from "@emotion/react";
    import styled from "@emotion/styled";
    
    const MyButton = styled.button`
        border: none;
        padding: 10px;
        font-weight: bold;
    `;
    
    const hover = css`
        &:hover {
            background-color: red;
        }
    `;
    
    const BlueButton = styled(MyButton)`
        background-color: blue;
        ${hover}
    `;
    
    const MyApp = () => {
        return (
            <>
                <MyButton>클릭</MyButton>
                <BlueButton>클릭</BlueButton>
            </>
        );
    };
    export default MyApp;
    独自のタグを選択すると、
    必要なタグに${hover}で適用できます.
  • Theme
    styled-conentsのThemeProviderでは、外部定義の色をインポートできます.
  • // color.js
    const MyColor = {
        default: "black",
        myAppColor: "red",
    };
    
    export default MyColor;
    
    /** @jsxImportSource @emotion/react */
    import { jsx, css, ThemeProvider } from "@emotion/react";
    import styled from "@emotion/styled";
    import MyColor from "./color";
    
    const MyButton = styled.button`
        border: none;
        padding: 10px;
        background-color: ${(props) => {
            return props.myAppColor ? MyColor.myAppColor : MyColor.default;
        }};
    `;
    
    const MyApp = () => {
        return (
            <ThemeProvider theme={MyColor}>
                <MyButton default>기본버튼</MyButton>
                <MyButton myAppColor>테마버튼</MyButton>
            </ThemeProvider>
        );
    };
    export default MyApp;

    color.jsからエクスポートされたMyColor関数にはdefaultとmyAppcolorのプロパティが含まれています.
    このファイルを別のファイルからインポートする場合は、MyColor.default , MyColor.myAppcolorのように呼び出すことができます.
    したがってbackground-colorにmyAppColor値がある場合はmyAppColorを適用します.
    ない場合はdefaultを使用して効率的で拡張可能なコードを記述できます.
  • Animation
  • /** @jsxImportSource @emotion/react */
    import { jsx, css, keyframes } from "@emotion/react";
    import styled from "@emotion/styled";
    
    const Rotation = keyframes`
    	from{
    		transform: rotate(0deg);
    	}
    	to{
    		transform: rotate(360deg);
    	}
    `;
    
    const MyButton = styled.button`
        border: none;
        padding: 10px;
        ${(props) => {
            if (props.warning) {
                return css`
                    animation: ${Rotation} 1s linear infinite;
                    background-color: ${props.warning ? "red" : "gray"};
                `;
            }
        }};
    `;
    
    const MyApp = () => {
        return <MyButton warning>버튼</MyButton>;
    };
    export default MyApp;
    

    キーフレームを使用すると、アニメーション効果が得られます.
  • Material-UI
  • が使用可能です.方法は次のとおりです.
    import styled from 'styled-components'
    import {Button} from '@material-ui/core'
    
    const MyButton = styled.button(Button)`
    	&&{
    		color: red;
    		border: 1px solid red;
    	}
    `
    styled-componentとemotionは文法的に似ているが、いくつかの使用方法が異なるため、属性とスタイルを同時に与えることができなかった.
    感情の公式サイトが提供しているガイドをよく読んで、よく探して解決しなければなりません.
    HINT:タグの属性はrenderのjsxタグに単独で作成する必要があります.