ReactのインラインCSSスタイル:a:hoverの実装方法?


178

私はかなり好きです はReactのインラインCSSパターンがそれを使用することにしました。

ただし、 :hoverおよび同様のセレクター。では、インラインCSSスタイルを使用しているときに、ハイライトオンホバーを実装する最良の方法は何でしょうか。

#reactjsからの提案の1つは、Clickableコンポーネントを用意し、次のように使用することです。

<Clickable>
    <Link />
</Clickable>

Clickable持っているhovered状態をとリンクする小道具として渡します。しかし、Clickable(私はそれを実装する方法は)ラップLinkdivそれが設定できるようにonMouseEnterし、onMouseLeaveそれに。これは、物事を少し複雑にします(例えばspandiv動作はとは異なりますspan)。

より簡単な方法はありますか?


1
あなたは完全に正しいです-インラインスタイルで:hover etcセレクターをシミュレートする唯一の方法は、onMouseEnterおよびを使用することonMouseLeaveです。それの正確な実装に関して-それは完全にあなた次第です。特定の例を見るには、<Clickable/>ラッパーをaにしてみspanませんか?
Chris Houghton、

3
私はあなたが今まであなたがラジウム試すことができそうServerRenderしたい場合は、これはもはや実行時にあなたを助ける、ExtractText WebPACKのプラグインと一緒に外部スタイルシートを使用することをお勧めし github.com/FormidableLabs/radiumを
abhirathore2006

現在、スタイル付きコンポーネントは、CSS / SCSのすべての可能性をリアクションでシミュレートするための最良のソリューションです。
Ahmad Behzadi 2017

回答:


43

私も同じ状況です。コンポーネントのスタイルを維持するパターンと同じですが、ホバー状態は最後のハードルのようです。

ホバー状態を必要とするコンポーネントに追加できるミックスインを作成しました。このミックスインはhovered、コンポーネントの状態に新しいプロパティを追加します。これはtrue、ユーザーがコンポーネントのメインDOMノードにカーソルを合わせ、それを次のように設定した場合に設定されますfalse要素を離れた場合に。

コンポーネントのレンダリング関数で、次のようなことができます。

<button style={m(
     this.styles.container,
     this.state.hovered && this.styles.hover,
)}>{this.props.children}</button>

これで、hovered状態の状態が変化するたびに、コンポーネントが再レンダリングされます。

これらのパターンのいくつかを自分でテストするために使用する、このためのサンドボックスリポジトリも作成しました。私の実装の例を見たい場合はチェックしてください。

https://github.com/Sitebase/cssinjs/tree/feature-interaction-mixin


3
長期的には適切な解決策ではありません
。Radium

16
@ abhirathore2006 Radiumは同じように機能し、問題は具体的には外部スタイルシートを使用せずにこれを行う方法です
Charlie Martin

バニラスプレッド演算子を使用するほうが理にかなっていると思いませんか?
PAT-O-MATION

102

onMouseEnterとonMouseLeaveを使用する方法だと思いますが、追加のラッパーコンポーネントの必要性はわかりません。これが私がそれをどのように実装したかです:

var Link = React.createClass({
  getInitialState: function(){
    return {hover: false}
  },
  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },
  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else {
      linkStyle = {backgroundColor: 'blue'}
    }
    return(
      <div>
        <a style={linkStyle} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>Link</a>
      </div>
    )
}

次に、ホバーの状態(true / false)を使用してリンクのスタイルを変更できます。


1
これはカバーするように見えます:hoverが、カバーしないようです:focus
Adam Tuttle

3
@AdamTuttle reactにはonFocusイベントがあります。あなたはのために同じことを行うことができるように:focusように:hover、必要とするのではなく、除く外onMouseEnteronMouseLeaveあなただけの必要があるだろうonFocus
ジョナサン・

7
このメソッドはメインスレッドでの実行を強制するのに対し、一般的なCSSイベントははるかに効率的に処理されることに注意してください。
Hampus Ahlgren 2017

53

パーティーに遅れますが、解決策が付属しています。「&」を使用して、n番目の子などのホバーのスタイルを定義できます。

day: {
    display: "flex",
    flex: "1",
    justifyContent: "center",
    alignItems: "center",
    width: "50px",
    height: "50px",
    transition: "all 0.2s",
    borderLeft: "solid 1px #cccccc",

    "&:hover": {
      background: "#efefef"
    },
    "&:last-child": {
      borderRight: "solid 1px #cccccc"
    }
},

1
これは解決策ではありません。問題は、個別のスタイルシートではなく、INLINE cssでそれを行う方法でした。
エミー

34
おい、よく見て。これはインラインスタイルです。
ヤロスワフWlazło

15
これはReactでは機能しません。styled-componentsのような追加のライブラリが必要です。
GG。

3
インラインスタイルでは機能しません。この例は混乱を招きます。それが本当に機能している場合は、完全なコンポーネントでより良い例を提供してください。
アレクサンドル

2
優れた!魅力的な作品!
フョードル

26

Radiumを使用できます。これは、ReactJSのインラインスタイル用のオープンソースツールです。それはあなたが必要とするセレクターを正確に追加します。とても人気があります-チェックしてください-Radium on npm


私はこの投稿に出くわしましたが、次の状況でラジウムをどのように実装しますか?module.exports = React.createClass({ displayName: 'App',})

1
@Rkhayatあなたはそれをラップするかmodule.exports = Radium(React.createClass({ displayName: 'App',}))、クラスを値に割り当て@Radium、ドキュメントがgithub.com/FormidableLabs/radium#usage
pbojinov

CSSと呼ばれるこの素晴らしいものもあります;)
Pixelomo 2018

11

完全なCSSサポートがまさにこの大量のCSSinJSライブラリを使用する理由です。これを効率的に行うには、インラインスタイルではなく実際のCSSを生成する必要があります。また、インラインスタイルは、より大きなシステムでの反応がはるかに遅くなります。免責事項-私はJSSを維持しています。


9

Made Style It-一部-この理由のために(他のライブラリ/構文の実装とインラインスタイリングがプロパティ値のプレフィックスのサポートを欠いているため、他の意見が不一致です)。JavaScriptでCSSを簡単に記述でき、完全に自己完結型のコンポーネントであるHTML-CSS-JSが必要であると考えています。ES5 / ES6テンプレート文字列を使用して、これでできるようになりました。:)

npm install style-it --save

関数構文JSFIDDLE

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

class Intro extends React.Component {
  render() {
    return Style.it(`
      .intro:hover {
        color: red;
      }
    `,
      <p className="intro">CSS-in-JS made simple -- just Style It.</p>
    );
  }
}

export default Intro;

JSX構文JSFIDDLE

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

class Intro extends React.Component {
  render() {
    return (
      <Style>
      {`
        .intro:hover {
          color: red;
        }
      `}

        <p className="intro">CSS-in-JS made simple -- just Style It.</p>
      </Style>
    );
  }
}

export default Intro;

JSX構文の例で、JSFiddleリンクのコードが正しいことに気付きましたが、ここに示す例では、Styleの終了タグの後に括弧が欠落しており、おそらく括弧がないためにインデントがオフになっています。
bradleygsmith

8

ジョナサンの答えに加えて、フォーカスとアクティブ状態をカバーするイベントと、イベントが適用されているターゲット内に子要素がある場合、後者はバブルしないので、onMouseOver代わりに使用onMouseEnterします。

var Link = React.createClass({

  getInitialState: function(){
    return {hover: false, active: false, focus: false}
  },

  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },

  toggleActive: function(){
    this.setState({active: !this.state.active})
  },

  toggleFocus: function(){
    this.setState({focus: !this.state.focus})
  },

  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else if (this.state.active) {
      linkStyle = {backgroundColor: 'blue'}
    } else if (this.state.focus) {
      linkStyle = {backgroundColor: 'purple'}
    } 

    return(
      <div>
        <a style={linkStyle} 
          onMouseOver={this.toggleHover} 
          onMouseOut={this.toggleHover} 
          onMouseUp={this.toggleActive} 
          onMouseDown={this.toggleActive} 
          onFocus={this.toggleFocus}> 
          Link 
        </a>
      </div>
    )
  }

7

これが、React Hooksを使用した私のソリューションです。スプレッド演算子と三項演算子を組み合わせたものです。

style.js

export default {
  normal:{
    background: 'purple',
    color: '#ffffff'
  },
  hover: {
    background: 'red'
  }
}

Button.js

import React, {useState} from 'react';
import style from './style.js'

function Button(){

  const [hover, setHover] = useState(false);

  return(
    <button
      onMouseEnter={()=>{
        setHover(true);
      }}
      onMouseLeave={()=>{
        setHover(false);
      }}
      style={{
        ...style.normal,
        ...(hover ? style.hover : null)
      }}>

        MyButtonText

    </button>
  )
}


6

これは、reactコンポーネント内にインラインスタイルを設定する(そして:hover CSS関数を使用する)ための素晴らしいハックになる可能性があります。

...

<style>
  {`.galleryThumbnail.selected:hover{outline:2px solid #00c6af}`}
</style>

...

5

Typescriptで Reactを使用している場合は、Typestyleをチェックアウトします。

以下は:hoverのサンプルコードです

import {style} from "typestyle";

/** convert a style object to a CSS class name */
const niceColors = style({
  transition: 'color .2s',
  color: 'blue',
  $nest: {
    '&:hover': {
      color: 'red'
    }
  }
});

<h1 className={niceColors}>Hello world</h1>

4

代わりにcssモジュールを使用でき、さらにreact-css-modulesクラス名のマッピングにはを。

このようにして、次のようにスタイルをインポートし、コンポーネントにローカルでスコープされた通常のcssを使用できます。

import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';

class Table extends React.Component {
    render () {
        return <div styleName='table'>
            <div styleName='row'>
                <div styleName='cell'>A0</div>
                <div styleName='cell'>B0</div>
            </div>
        </div>;
    }
}

export default CSSModules(Table, styles);

これはwebpack cssモジュールの例です


参考:Meteorを使用している場合は、このパッケージgithub.com/nathantreid/meteor-css-modulesを確認してください。今のところ自分で使って大成功しています。
Spiralis

これは、reactコンポーネントのスタイルを設定するのに最適な方法ですが、インラインスタイルのすべての制御を提供するわけではありません。たとえば、:hoverRadiumまたは別のonMouseOverベースのソリューションのように実行時にスタイルを変更することはできません
Charlie Martin

4

最初は、setStateを指定したonMouseOverとonMouseLeaveは少しオーバーヘッドのように見えましたが、これがリアクションの仕組みなので、私にとっては最も簡単でクリーンなソリューションのようです。

たとえば、テーマのCSSをサーバーサイドでレンダリングすることも優れたソリューションであり、Reactコンポーネントをよりクリーンに保ちます。

要素に動的スタイルを追加する必要がない場合(たとえば、テーマの場合)、インラインスタイルをまったく使用せず、代わりにcssクラスを使用する必要があります。

これは、html / JSXをクリーンでシンプルに保つための従来のhtml / cssルールです。


4

簡単な方法は三項演算子を使用することです

var Link = React.createClass({
  getInitialState: function(){
    return {hover: false}
  },
  toggleHover: function(){
    this.setState({hover: !this.state.hover})
  },
  render: function() {
    var linkStyle;
    if (this.state.hover) {
      linkStyle = {backgroundColor: 'red'}
    } else {
      linkStyle = {backgroundColor: 'blue'}
    }
    return(
      <div>
        <a style={this.state.hover ? {"backgroundColor": 'red'}: {"backgroundColor": 'blue'}} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>Link</a>
      </div>
    )
  }

1

フックを使用すると:

const useFade = () => {
  const [ fade, setFade ] = useState(false);

  const onMouseEnter = () => {
    setFade(true);
  };

  const onMouseLeave = () => {
    setFade(false);
  };

  const fadeStyle = !fade ? {
    opacity: 1, transition: 'all .2s ease-in-out',
  } : {
    opacity: .5, transition: 'all .2s ease-in-out',
  };

  return { fadeStyle, onMouseEnter, onMouseLeave };
};

const ListItem = ({ style }) => {
  const { fadeStyle, ...fadeProps } = useFade();

  return (
    <Paper
      style={{...fadeStyle, ...style}}
      {...fadeProps}
    >
      {...}
    </Paper>
  );
};

0

私の目的に合った最近のアプリケーションの1つで、これにかなりハックっぽいソリューションを使用しています。バニラjsでカスタムホバー設定関数を書くよりも速いことがわかります(ただし、ほとんどの環境でおそらくベストプラクティスではないかもしれません) ..)それで、あなたがまだ興味があるなら、ここに行きます。

インラインJavaScriptスタイルを保持するためだけに親要素を作成し、CSSスタイルシートがラッチするclassNameまたはIDを持つ子を作成して、専用のCSSファイルにホバースタイルを書き込みます。これは、より細かい子要素が継承を介してインラインjsスタイルを受け取るが、ホバースタイルがcssファイルによってオーバーライドされるため、機能します。

つまり、基本的に、私の実際のcssファイルは、ホバー効果を保持することのみを目的として存在し、それ以外にはありません。これにより、非常に簡潔で管理しやすくなり、インラインのReactコンポーネントスタイルで面倒な作業を行うことができます。

次に例を示します。

const styles = {
  container: {
    height: '3em',
    backgroundColor: 'white',
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'stretch',
    justifyContent: 'flex-start',
    borderBottom: '1px solid gainsboro',
  },
  parent: {
    display: 'flex',
    flex: 1,
    flexDirection: 'row',
    alignItems: 'stretch',
    justifyContent: 'flex-start',
    color: 'darkgrey',
  },
  child: {
    width: '6em',
    textAlign: 'center',
    verticalAlign: 'middle',
    lineHeight: '3em',
  },
};

var NavBar = (props) => {
  const menuOptions = ['home', 'blog', 'projects', 'about'];

  return (
    <div style={styles.container}>
      <div style={styles.parent}>
        {menuOptions.map((page) => <div className={'navBarOption'} style={styles.child} key={page}>{page}</div> )}
      </div>
    </div>
  );
};


ReactDOM.render(
  <NavBar/>,
  document.getElementById('app')
);
.navBarOption:hover {
  color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

「子」インラインスタイルには「色」プロパティセットがないことに注意してください。そうした場合、インラインスタイルが私のスタイルシートよりも優先されるため、これは機能しません。


0

これが答えであるかどうかは100%わかりませんが、CSS:hover効果を色と画像をインラインでシミュレートするために使用するトリックです。

`This works best with an image`

class TestHover extends React.PureComponent {
render() {
const landingImage = {     
"backgroundImage": "url(https://i.dailymail.co.uk/i/pix/2015/09/01/18/2BE1E88B00000578-3218613-image-m-5_1441127035222.jpg)",
"BackgroundColor": "Red", `this can be any color`
"minHeight": "100%",
"backgroundAttachment": "fixed",
"backgroundPosition": "center",
"backgroundRepeat": "no-repeat",
"backgroundSize": "cover", 
"opacity": "0.8", `the hove trick is here in the opcaity slightly see through gives the effect when the background color changes`
    }

  return (
    <aside className="menu">
        <div className="menu-item">
          <div style={landingImage}>SOME TEXT</div>
        </div>
    </aside>
      ); 
  }
}
ReactDOM.render(
    <TestHover />,
  document.getElementById("root")
);

CSS:

.menu {
top: 2.70em;
bottom: 0px;
width: 100%;
position: absolute;
}

.menu-item {
cursor: pointer;
height: 100%;
font-size: 2em;
line-height: 1.3em;
color: #000;
font-family: "Poppins";
font-style: italic;
font-weight: 800;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}

ホバーする前

.menu-item:nth-child(1) {
color: white;
background-color: #001b37;
} 

ホバー時

.menu-item:nth-child(1):hover {
color: green;
background-color: white;
}

例:https : //codepen.io/roryfn/pen/dxyYqj?editors=0011


0
<Hoverable hoverStyle={styles.linkHover}>
  <a href="https://example.com" style={styles.link}>
    Go
  </a>
</Hoverable>

Hoverableは次のように定義されます。

function Hoverable(props) {
  const [hover, setHover] = useState(false);

  const child = Children.only(props.children);

  const onHoverChange = useCallback(
    e => {
      const name = e.type === "mouseenter" ? "onMouseEnter" : "onMouseLeave";
      setHover(!hover);
      if (child.props[name]) {
        child.props[name](e);
      }
    },
    [setHover, hover, child]
  );

  return React.cloneElement(child, {
    onMouseEnter: onHoverChange,
    onMouseLeave: onHoverChange,
    style: Object.assign({}, child.props.style, hover ? props.hoverStyle : {})
  });
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.