web-dev-qa-db-ja.com

ReactのCSS擬似要素

私は React コンポーネントを構築しています。 この素晴らしいプレゼンテーション で示唆されているように、Reactの背後にいる人の1人がCSSコンポーネントをインラインで追加しました。プレゼンテーションの「:: after」というタイトルのスライドのように、CSS擬似クラスをインラインで追加する方法を見つけるために一晩中試してきました。残念ながら、content:"";プロパティを追加するだけでなく、position:absolute; -webkit-filter: blur(10px) saturate(2);も追加する必要があります。スライドは{/* … */}を介してコンテンツを追加する方法を示していますが、他のプロパティをどのように追加しますか?

53

React チームで@Vjeuxから返信を受け取りました:

通常のHTML/CSS:

<div class="something"><span>Something</span></div>
<style>
    .something::after {
    content: '';
    position: absolute;
    -webkit-filter: blur(10px) saturate(2);
}
</style>

インラインスタイルで反応する:

render: function() {
    return (
        <div>
          <span>Something</span>
          <div style={{position: 'absolute', WebkitFilter: 'blur(10px) saturate(2)'}} />
        </div>
    );
},

トリックは、CSSで::afterを使用して新しい要素を作成する代わりに、Reactを使用して新しい要素を作成する必要があることです。この要素をどこにでも追加する必要がない場合は、それを行うコンポーネントを作成します。

-webkit-filterのような特別な属性の場合、それらをエンコードする方法は、ダッシュを削除し、次の文字を大文字にすることです。したがって、それはWebkitFilterに変わります。 {'-webkit-filter': ...}を実行しても動作することに注意してください。

59

インラインスタイルを使用して、擬似クラスまたは擬似要素をターゲットにすることはできません。スタイルシートを使用する必要があります。

CSSを動的に生成する場合、最も簡単な方法はDOM要素<style>を作成することです。

<style dangerouslySetInnerHTML={{
  __html: [
     '.my-special-div:after {',
     '  content: "Hello";',
     '  position: absolute',
     '}'
    ].join('\n')
  }}>
</style>
<div className='my-special-div'></div>
25
Wiktor Kozlik

インラインスタイリングは、疑似または@ルール(@mediaなど)をサポートしません。推奨事項は、:hoverなどのCSS状態でのonMouseEnteronMouseLeaveなどのCSS機能の再実装から、:after:beforeなどの疑似要素を再現して外部スタイルシートを使用するまで、より多くの要素を使用することです。

個人的にこれらすべてのソリューションが嫌いです。 JavaScriptを介したCSS機能の再実装はうまく拡張できません。また、余分なマークアップも追加しません。

各開発者が:hoverなどのCSS機能を再作成している大規模なチームを想像してください。各開発者は異なる方法で行います。チームの規模が大きくなると、できる場合はそれが行われます。 JavaScriptには、CSS機能を再実装する方法がnあり、最終的には、これらの方法のすべてに実装することに賭けることができますスパゲッティコードであること。

じゃあ何をすればいいの? CSSを使用します。あなたがCSS-in-JSキャンプにいる可能性が高いと仮定して、インラインスタイリングについて質問したことは確かです(私もです!)。 HTMLとCSSのコロケーションはJSとHTMLのコロケーションと同じくらい価値があることがわかっていますが、多くの人はまだ気づいていません(JS-HTMLコロケーションにも最初は多くの抵抗がありました)。

このスペースで Style It と呼ばれるソリューションを作成し、ReactコンポーネントにプレーンテキストCSSを簡単に記述できるようにしました。 JSでCSSを再発明するサイクルを無駄にする必要はありません。適切な仕事のための適切なツール、これは:afterを使用した例です:

npm install style-it --save

関数構文 ( JSFIDDLE

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return Style.it(`
      #heart {
        position: relative;
        width: 100px;
        height: 90px;
      }
      #heart:before,
      #heart:after {
        position: absolute;
        content: "";
        left: 50px;
        top: 0;
        width: 50px;
        height: 80px;
        background: red;
        -moz-border-radius: 50px 50px 0 0;
        border-radius: 50px 50px 0 0;
        -webkit-transform: rotate(-45deg);
        -moz-transform: rotate(-45deg);
        -ms-transform: rotate(-45deg);
        -o-transform: rotate(-45deg);
        transform: rotate(-45deg);
        -webkit-transform-Origin: 0 100%;
        -moz-transform-Origin: 0 100%;
        -ms-transform-Origin: 0 100%;
        -o-transform-Origin: 0 100%;
        transform-Origin: 0 100%;
      }
      #heart:after {
        left: 0;
        -webkit-transform: rotate(45deg);
        -moz-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        -o-transform: rotate(45deg);
        transform: rotate(45deg);
        -webkit-transform-Origin: 100% 100%;
        -moz-transform-Origin: 100% 100%;
        -ms-transform-Origin: 100% 100%;
        -o-transform-Origin: 100% 100%;
        transform-Origin :100% 100%;
      }
    `,
      <div id="heart" />
    );
  }
}

export default Intro;

JSXの構文 ( JSFIDDLE

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return (
      <Style>
      {`
        #heart {
          position: relative;
          width: 100px;
          height: 90px;
        }
        #heart:before,
        #heart:after {
          position: absolute;
          content: "";
          left: 50px;
          top: 0;
          width: 50px;
          height: 80px;
          background: red;
          -moz-border-radius: 50px 50px 0 0;
          border-radius: 50px 50px 0 0;
          -webkit-transform: rotate(-45deg);
          -moz-transform: rotate(-45deg);
          -ms-transform: rotate(-45deg);
          -o-transform: rotate(-45deg);
          transform: rotate(-45deg);
          -webkit-transform-Origin: 0 100%;
          -moz-transform-Origin: 0 100%;
          -ms-transform-Origin: 0 100%;
          -o-transform-Origin: 0 100%;
          transform-Origin: 0 100%;
        }
        #heart:after {
          left: 0;
          -webkit-transform: rotate(45deg);
          -moz-transform: rotate(45deg);
          -ms-transform: rotate(45deg);
          -o-transform: rotate(45deg);
          transform: rotate(45deg);
          -webkit-transform-Origin: 100% 100%;
          -moz-transform-Origin: 100% 100%;
          -ms-transform-Origin: 100% 100%;
          -o-transform-Origin: 100% 100%;
          transform-Origin :100% 100%;
        }
     `}

      <div id="heart" />
    </Style>
  }
}

export default Intro;

CSS-Tricks から抜粋したハートの例

10
Joshua Robinson

質問に対する直接的な答えではありませんが、これはTypeScriptを使用してstyle情報を作成するのに苦労している人々を助けるかもしれません。

次の内容が正しくないことを示すエラーが表示されていました。

let iconStyle = {
        position: 'relative',
        maxHeight: '90px',
        top: '25%',
    }

このエラーは、「プロパティ「位置」のタイプには互換性がない」ことを教えてくれました。理由はわかりません。

次のように、厳密なTypeScript宣言を追加することでこれを修正しました。

let iconStyle: CSSProperties = {
        position: 'relative',
        maxHeight: '90px',
        top: '25%',
    }

これは動作します。

1
Stuart Aitken