React'ta satır içi CSS stilleri: a: hover nasıl uygulanır?


178

React'deki satır içi CSS modelini oldukça beğendim ve kullanmaya karar verdim.

Ancak :hoverve benzer seçicileri kullanamazsınız . Peki, satır içi CSS stillerini kullanırken fareyle üzerine gelindiğinde vurgulamanın en iyi yolu nedir?

#Reactjs'den bir öneri, bir Clickablebileşene sahip olmak ve bunu şu şekilde kullanmaktır:

<Clickable>
    <Link />
</Clickable>

ClickableBir sahiptir hovereddevlet ve Link sahne olarak geçirir. Bununla birlikte, Clickable(uygulama şeklim) , ayarlayabilmesi ve ona sığabilmesi için Linkiçine sarar . Bu, işleri biraz karmaşık hale getirir (örneğin , bir davranışa sarılmış ).divonMouseEnteronMouseLeavespandivspan

Daha basit bir yol var mı?


1
Kesinlikle haklısın - simüle etmenin tek yolu: satır içi stillere sahip fareyle vb. Seçicileri kullanmak onMouseEnterve onMouseLeave. Bunun tam olarak uygulanmasıyla ilgili - tamamen size kalmış. Özel örneğinize bakmak için neden <Clickable/>sargıyı a yapmıyorsunuz span?
Chris Houghton

3
ExtractText Webpack eklentisi ile birlikte harici stil sayfalarını kullanmanızı öneririm, bu, ServerRender'ı istediğinizde daha uzun vadede size yardımcı olacaktır, aksi takdirde Radium github.com/FormidableLabs/radium
abhirathore2006

Şu anda Tarz Bileşen reaksiyonda css / scss tüm olasılıkları simüle etmek için en iyi çözümdür.
Ahmad Behzadi

Yanıtlar:


43

Ben de aynı durumdayım. Stili bileşenlerde tutma deseni gibi ama durma durumları son engel gibi görünüyor.

Yaptığım şey, üzerine gelme durumları gerektiren bileşeninize ekleyebileceğiniz bir mixin yazmaktı. Bu karışım, hoveredbileşeninizin durumuna yeni bir özellik ekleyecektir . trueKullanıcının, bileşenin ana DOM düğümü üzerine gelip gelmeyeceği falseve kullanıcılar öğeyi terk ederse yeniden ayarlayacağı şekilde ayarlanır .

Şimdi bileşen oluşturma işlevinizde aşağıdakileri yapabilirsiniz:

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

Şimdi durumun durumu her hovereddeğiştiğinde bileşen yeniden ortaya çıkacaktır.

Ben de bunun için kendimi test etmek için kullandığım bir sanal alan repo oluşturdum. Uygulamamın bir örneğini görmek istiyorsanız bir göz atın.

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


3
uzun vadede iyi bir çözüm değil, Radium daha iyi bir seçim olacak veya harici bir stil sayfası olacak
abhirathore2006

16
@ abhirathore2006 Radium aynı şekilde çalışır ve soru özellikle harici bir stil sayfası kullanmadan nasıl yapılacağıdır
Charlie Martin

Vanilya yayma operatörü kullanmak daha anlamlı olmaz mıydı?
PAT-O-MATION

102

Ben onMouseEnter ve onMouseLeave gitmek için yollar olduğunu düşünüyorum, ama ek bir sarmalayıcı bileşen ihtiyacı görmüyorum. İşte nasıl uyguladım:

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>
    )
}

Daha sonra bağlantının stilini değiştirmek için fareyle üzerine gelme durumunu (true / false) kullanabilirsiniz.


1
Bu örtbas gibi görünüyor :hoverama değil:focus
Adam Tuttle

3
@AdamTuttle tepki bir onFocusolay var; için aynı şeyi yapabileceğini böylece :focusolarak :hoveryerine ihtiyaç duyan hariç onMouseEnterve onMouseLeavesadece gerekironFocus
Jonathan

7
Bu yöntemin ana iş parçacığında yürütmeyi zorladığını, buna karşılık tipik CSS olaylarının çok daha verimli bir şekilde gerçekleştirildiğini unutmayın.
Hampus Ahlgren

54

Partiye geç ama çözüm geliyor. Fareyle üzerine gelindiğinde Çocuk vb. İçin stilleri tanımlamak üzere "&" kullanabilirsiniz:

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
Bu bir çözüm değil, soru INLINE css ile nasıl yapılır, ayrı bir stil sayfasıyla değil.
Emmy

36
Dostum, daha yakından bak. Bu satır içi tarzı IS.
Jarosław Wlazło

15
Bu React ile çalışmaz. Tarz bileşenler gibi ekstra bir kütüphaneye ihtiyacınız var.
GG.

3
Satır içi stil ile çalışmaz, bu örnek karışıklık getirir. Gerçekten işe yarıyorsa, lütfen tam bileşenle daha iyi bir örnek verin.
Alexandre

2
Mükemmel! Tıkır tıkır çalışıyor!
Fyodor

26

Radium'u kullanabilirsiniz - ReactJS ile satır içi stiller için açık kaynaklı bir araçtır. Tam olarak ihtiyacınız olan seçicileri ekler. Çok popüler, bir göz at - Radium on npm


Bu yazıyla yeni karşılaştım, aşağıdaki durumda Radium'u nasıl uygularsınız? module.exports = React.createClass({ displayName: 'App',})

1
@Rkhayat module.exports = Radium(React.createClass({ displayName: 'App',}))Sınıfı bir değere atayabilir veya sınıfı bir değere atayabilir ve @Radiumdekoratörü üstüne dokümanlar ekleyerek github.com/FormidableLabs/radium#usage
pbojinov

CSS olarak adlandırılan bu harika şey de var;)
Pixelomo

11

Tam CSS desteği, bu büyük miktarda CSSinJS kitaplığının tam olarak sebebidir, bunu verimli bir şekilde yapmak için satır içi stiller değil, gerçek CSS oluşturmanız gerekir. Ayrıca satır içi stiller daha büyük bir sistemde daha yavaş tepki verir. Feragatname - JSS'yi koruyorum .


9

Yapılmış Stil - kısmen - bu nedenle (diğerleri diğer libs / sözdizimi ve satır içi stiller uygulama özelliklerinin önek için destek eksikliği ile anlaşmazlık). Sadece JavaScript'te CSS yazabileceğimize ve HTML-CSS-JS bileşenlerine sahip olduğumuza inanmalıyız. ES5 / ES6 şablon dizeleri ile artık yapabiliriz ve oldukça da güzel olabilir! :)

npm install style-it --save

İşlevsel Sözdizimi ( 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 Sözdizimi ( 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 Sözdizimi örneğinde fark ettim, JSFiddle bağlantısı doğru koda sahip, ancak burada gösterilen örnek kapanış Style etiketinden sonra kapanış parantezi eksik ve girintileme muhtemelen eksik parantez nedeniyle kapalı.
bradleygsmith

8

Üzerine ekleme Jonathan'ın cevap , burada odağı ve aktif ülkelerini kapsayacak şekilde olaylardır ve kullanma onMouseOveryerine onMouseEnterolay uygulanıyor hedef içinde herhangi bir çocuk elemanlarını varsa ikinci irade değil kabarcık beri.

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

İşte React Hooks kullanarak çözümüm. Forma operatörünü ve üçlü operatörü birleştirir.

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

Bu, bir reaksiyon bileşeninde satır içi stile sahip olmak için güzel bir saldırı olabilir (ve ayrıca: hover CSS işlevini kullanarak):

...

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

...

5

Ödeme Türü kullandığınız takdirde typescript ile tepki.

Aşağıda bunun için bir örnek kod verilmiştir:

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

Alternatif olarak css modüllerini kullanabilir ve ek olarak tepki-css modülleri de kullanabilirsiniz. sınıf adı eşlemesi için .

Bu şekilde stillerinizi aşağıdaki gibi içe aktarabilir ve bileşenlerinize yerel olarak yerleştirilmiş normal css'yi kullanabilirsiniz:

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);

İşte bir webpack css modülleri örneği


Bilginize: Meteor kullanıyorsanız şu paketi inceleyin: github.com/nathantreid/meteor-css-modules . Şimdiye kadar büyük bir başarıya sahip olarak kullanıyorum.
Spiralis

Bu, tepki bileşenlerini biçimlendirmenin harika bir yoludur, ancak size satır içi stillerin tüm denetimini vermez. Örneğin, :hoverRadium veya başka bir onMouseOvertemel çözümle çalışma zamanında stilleri değiştiremezsiniz
Charlie Martin

4

setState ile onMouseOver ve onMouseLeave ilk başta bana biraz ek yük gibi geldi - ama tepki bu şekilde çalıştığından, benim için en kolay ve en temiz çözüm gibi görünüyor.

örneğin bir tema css sunucu tarafı oluşturmak da iyi bir çözümdür ve reaksiyon bileşenlerini daha temiz tutar.

öğelere dinamik stiller eklemeniz gerekmiyorsa (örneğin bir tema için) satır içi stiller kullanmamalısınız, bunun yerine css sınıflarını kullanmalısınız.

html / JSX'i temiz ve basit tutmak için geleneksel bir html / css kuralıdır.


4

Basit yol üçlü operatör kullanmaktır

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

Kancaların kullanımı ile:

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

Bunun için çalışan son uygulamalardan birinde bunun için oldukça hack-ish çözümü kullanıyorum ve vanilya js'de özel fareyle üzerine gelme ayarları işlevleri yazmaktan daha hızlı buluyorum (yine de, çoğu ortamda en iyi uygulama olmayabilir) ..) Yani, hala ilgileniyorsan, işte gidiyor.

Yalnızca satır içi javascript stillerini tutmak için bir üst öğe oluşturdum, sonra css stil sayfamın üzerine gelip vurgulu stilini özel css dosyama yazacağı bir className veya kimliğe sahip bir çocuk. Bu, daha ayrıntılı alt öğe satır içi js stillerini kalıtım yoluyla aldığından, ancak vurgulu stillerinin css dosyası tarafından geçersiz kılındığı için çalışır.

Temelde, gerçek css dosyam sadece vurgulu efektler tutmak için var, başka bir şey yok. Bu, oldukça kısa ve yönetilmesini kolaylaştırıyor ve satır içi React bileşen stillerimdeki ağır kaldırmayı yapmama izin veriyor.

İşte bir örnek:

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>

"Alt" satır içi stilinin "renk" özellik kümesine sahip olmadığına dikkat edin. Olsaydı, bu işe yaramaz çünkü satır içi stil stil sayfama göre öncelikli olur.


0

Bu sorunun cevabı olup olmadığından% 100 emin değilim, ama CSS: simgeleme efektini renklerle ve satır içi görüntülerle simgelemek için kullandığım hile.

`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;
}

Fareyle üzerine gelmeden önce

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

Üzerinde gezinme

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

Örnek: 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'ın şu şekilde tanımlandığı durumlarda:

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 : {})
  });
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.