สไตล์ CSS แบบอินไลน์ในการตอบสนอง: วิธีการใช้: โฮเวอร์


178

ฉันชอบรูปแบบ CSS แบบอินไลน์ใน Reactและตัดสินใจที่จะใช้

อย่างไรก็ตามคุณไม่สามารถใช้:hoverและ selector ที่คล้ายกันได้ ดังนั้นวิธีที่ดีที่สุดในการใช้ไฮไลต์บนโฮเวอร์ขณะใช้สไตล์ CSS แบบอินไลน์คืออะไร

หนึ่งข้อเสนอแนะจาก #reactjs คือการมีClickableส่วนประกอบและใช้งานดังนี้:

<Clickable>
    <Link />
</Clickable>

Clickableมีhoveredรัฐและผ่านมันเป็นอุปกรณ์ประกอบฉากที่จะเชื่อมโยง อย่างไรก็ตาม, Clickable(วิธีที่ฉันใช้มัน) ล้อมรอบLinkในdivเพื่อที่จะสามารถตั้งค่าonMouseEnterและonMouseLeaveมัน สิ่งนี้ทำให้สิ่งที่ซับซ้อนเล็กน้อย (เช่นspanห่อในdivพฤติกรรมที่แตกต่างกว่าspan)

มีวิธีที่ง่ายกว่านี้ไหม?


1
คุณอย่างถูก - วิธีเดียวที่จะจำลอง: โฉบเตอร์ ฯลฯ ด้วยรูปแบบอินไลน์คือการใช้และonMouseEnter onMouseLeaveเกี่ยวกับการนำไปปฏิบัติที่แน่นอน - ขึ้นอยู่กับคุณ หากต้องการดูตัวอย่างเฉพาะของคุณทำไมไม่ทำให้<Clickable/>เสื้อคลุมเป็นspan?
Chris Houghton

3
ฉันขอแนะนำให้ใช้สไตล์ชีตภายนอกพร้อมกับปลั๊กอิน ExtractText Webpack ซึ่งจะช่วยให้คุณทำงานได้นานขึ้นหากคุณต้องการ ServerRender ไม่เช่นนั้นคุณสามารถลอง Radium github.com/FormidableLabs/radium
abhirathore2006

คอมโพเนนต์สไตล์ปัจจุบันเป็นทางออกที่ดีที่สุดในการจำลองความเป็นไปได้ทั้งหมดของ css / scss ในการตอบสนอง
Ahmad Behzadi

คำตอบ:


43

ฉันอยู่ในสถานการณ์เดียวกัน ชอบรูปแบบของการเก็บสไตล์ในส่วนประกอบ แต่สถานะโฮเวอร์ดูเหมือนเป็นสิ่งกีดขวางสุดท้าย

สิ่งที่ฉันทำคือการเขียนมิกซ์อินที่คุณสามารถเพิ่มองค์ประกอบของคุณที่ต้องการรัฐเลื่อน มิกซ์อินนี้จะเพิ่มhoveredคุณสมบัติใหม่ให้กับสถานะขององค์ประกอบของคุณ มันจะถูกตั้งค่าเป็นtrueหากผู้ใช้เลื่อนเมาส์ไปที่โหนด DOM หลักขององค์ประกอบและตั้งค่ากลับเป็นfalseหากผู้ใช้ออกจากองค์ประกอบ

ในฟังก์ชั่นการเรนเดอร์องค์ประกอบของคุณคุณสามารถทำสิ่งต่อไปนี้:

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

ตอนนี้ทุกครั้งที่สถานะของการhoveredเปลี่ยนแปลงองค์ประกอบจะแสดงผลใหม่

ฉันยังสร้าง repo sandbox สำหรับสิ่งนี้ที่ฉันใช้ในการทดสอบรูปแบบเหล่านี้ด้วยตัวเอง ลองใช้ดูหากคุณต้องการดูตัวอย่างการใช้งานของฉัน

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


3
ไม่ได้เป็นทางออกที่ดีสำหรับการทำงานอีกต่อไปเรเดียมจะเป็นทางเลือกที่ดีกว่าหรือใช้สไตล์ชีตภายนอก
abhirathore2006

16
@ abhirathore2006 เรเดียมทำงานในลักษณะเดียวกันและคำถามก็คือวิธีการทำเช่นนี้โดยไม่ต้องใช้สไตล์ชีทภายนอก
Charlie Martin

การใช้ตัวดำเนินการแพร่กระจายวานิลลาจะไม่สมเหตุสมผลหรือไม่
PAT-O-MATION

102

ฉันคิดว่า onMouseEnter และ onMouseLeave เป็นหนทางที่จะไป แต่ฉันไม่เห็นความต้องการส่วนประกอบ wrapper เพิ่มเติม นี่คือวิธีที่ฉันใช้มัน:

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

จากนั้นคุณสามารถใช้สถานะของโฮเวอร์ (จริง / เท็จ) เพื่อเปลี่ยนสไตล์ของลิงค์


1
สิ่งนี้ดูเหมือนจะครอบคลุม:hoverแต่ไม่ใช่:focus
Adam Tuttle

3
@AdamTuttle ตอบกลับมีonFocusเหตุการณ์ เพื่อให้คุณสามารถทำสิ่งเดียวกันสำหรับ:focusเป็น:hoverยกเว้นแทนที่จะต้องonMouseEnterและonMouseLeaveคุณจะต้องเท่านั้นonFocus
โจนาธาน

7
โปรดทราบว่าวิธีนี้บังคับให้ดำเนินการกับเธรดหลักในขณะที่เหตุการณ์ CSS ทั่วไปได้รับการจัดการอย่างมีประสิทธิภาพมากขึ้น
Hampus Ahlgren

54

มาปาร์ตี้ แต่มาพร้อมทางออก คุณสามารถใช้ "&" เพื่อกำหนดสไตล์สำหรับโฮเวอร์ nth Child ฯลฯ :

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 ไม่ใช่สไตล์ชีทแยก
Emmy

35
เพื่อนมองใกล้ นี่คือรูปแบบอินไลน์
JarosławWlazło

15
สิ่งนี้ใช้ไม่ได้กับ React คุณต้องมีไลบรารีเพิ่มเติมเช่นองค์ประกอบที่มีสไตล์
GG

3
มันไม่ทำงานกับสไตล์อินไลน์ตัวอย่างนี้ทำให้เกิดความสับสน ถ้ามันใช้งานได้จริงโปรดให้ตัวอย่างที่ดีกว่ากับส่วนประกอบแบบเต็ม
Alexandre

2
ยอดเยี่ยม ทำงานเหมือนจับใจ!
ฟีโอดอร์

26

คุณสามารถใช้เรเดียม - เป็นเครื่องมือโอเพ่นซอร์สสำหรับรูปแบบอินไลน์ด้วย ReactJS มันเพิ่มตัวเลือกที่คุณต้องการ เป็นที่นิยมมากลองดูสิ - เรเดียมเมื่อเวลา 23.00 น


ฉันเพิ่งเจอโพสต์นี้คุณจะใช้เรเดียมในสถานการณ์ต่อไปนี้อย่างไร module.exports = React.createClass({ displayName: 'App',})

1
@Rkhayat คุณสามารถห่อมันmodule.exports = Radium(React.createClass({ displayName: 'App',}))หรือกำหนดคลาสให้เป็นค่าและเพิ่ม@Radiumมัณฑนากรด้านบนเป็นเอกสารที่กล่าวถึงgithub.com/FormidableLabs/radium#usage
pbojinov

นอกจากนี้ยังมีสิ่งที่ยอดเยี่ยมที่เรียกว่า CSS;)
Pixelomo

11

การสนับสนุน CSS แบบเต็มคือเหตุผลที่ห้องสมุด CSSinJS จำนวนมากต้องการทำเช่นนี้อย่างมีประสิทธิภาพคุณต้องสร้าง CSS จริงไม่ใช่สไตล์อินไลน์ นอกจากนี้รูปแบบอินไลน์ยังทำงานช้ากว่ามากในระบบที่ใหญ่ ความรับผิดชอบ - ฉันจะรักษาJSS


9

Made Style It - ส่วนหนึ่ง - เนื่องจากเหตุผลนี้ (คนอื่นไม่เห็นด้วยกับการใช้ libs / syntax และ inline stylings อื่น ๆ ขาดการสนับสนุนสำหรับค่าคุณสมบัติ prefixing) เชื่อว่าเราควรจะสามารถเขียน CSS ใน JavaScript และมีส่วนประกอบในตัว 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 มีรหัสที่ถูกต้อง แต่ตัวอย่างที่แสดงที่นี่หายไปวงเล็บปิดหลังจากแท็กสไตล์การปิดและการเยื้องอาจปิดเพราะวงเล็บที่ขาดหายไป
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

นี่อาจเป็นแฮ็คที่ดีสำหรับการมีสไตล์แบบอินไลน์ภายในองค์ประกอบการตอบสนอง (และใช้: ฟังก์ชั่นโฮเวอร์ CSS):

...

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

...

5

ชำระเงินTypestyleหากคุณกำลังใช้ React กับ Typescript

ด้านล่างนี้เป็นตัวอย่างรหัสสำหรับ: โฮเวอร์

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


FYI: ถ้าคุณกำลังใช้ดาวตกตรวจสอบแพคเกจนี้: github.com/nathantreid/meteor-css-modules ฉันใช้มันด้วยตัวเองซึ่งประสบความสำเร็จอย่างมาก
Spiralis

นี่เป็นวิธีที่ยอดเยี่ยมในการออกแบบสไตล์การตอบสนองขององค์ประกอบ แต่ก็ไม่ได้ช่วยให้คุณสามารถควบคุมสไตล์อินไลน์ได้ทั้งหมด ตัวอย่างเช่นคุณไม่สามารถเปลี่ยน:hoverรูปแบบที่รันไทม์อย่างที่คุณสามารถทำได้ด้วย Radium หรือonMouseOverโซลูชันอื่น ๆ
Charlie Martin

4

onMouseOver และ onMouseLeave กับ setState ในตอนแรกดูเหมือนจะเป็นเรื่องเล็กน้อยสำหรับฉัน - แต่เนื่องจากนี่เป็นวิธีการทำงานของปฏิกิริยาตอบสนองดูเหมือนว่าเป็นทางออกที่ง่ายที่สุดและสะอาดที่สุดสำหรับฉัน

การเรนเดอร์ css เซิร์ฟเวอร์ที่เป็นชุดรูปแบบนั้นเป็นโซลูชันที่ดีและทำให้ส่วนประกอบที่ตอบสนองสะอาดยิ่งขึ้น

หากคุณไม่จำเป็นต้องผนวกสไตล์แบบไดนามิกเข้ากับองค์ประกอบ (ตัวอย่างเช่นสำหรับชุดรูปแบบ) คุณไม่ควรใช้สไตล์อินไลน์เลย แต่ใช้คลาส css แทน

นี่เป็นกฎ html / css ดั้งเดิมเพื่อให้ html / JSX สะอาดและเรียบง่าย


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

ด้วยการใช้ hooks:

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

ฉันใช้แฮ็ค - ไอแฮ็คสวย ๆ สำหรับสิ่งนี้ในหนึ่งในแอปพลิเคชั่นล่าสุดที่ทำงานเพื่อวัตถุประสงค์ของฉันและฉันพบว่าเร็วกว่าการเขียนฟังก์ชั่นการตั้งค่าโฮเวอร์แบบกำหนดเองใน vanilla js (แม้ว่าฉันรู้จัก .. ) ดังนั้นในกรณีที่คุณยังสนใจอยู่

ฉันสร้างองค์ประกอบผู้ปกครองเพียงเพื่อประโยชน์ในการถือรูปแบบจาวาสคริปต์แบบอินไลน์จากนั้นเด็กที่มี className หรือ id ที่ CSS สไตล์ชีทของฉันจะสลักลงและเขียนสไตล์โฉบในไฟล์ CSS เฉพาะของฉัน สิ่งนี้ทำงานได้เพราะองค์ประกอบย่อยที่ละเอียดยิ่งขึ้นได้รับสไตล์ inline js ผ่านการสืบทอด แต่มีลักษณะโฮเวอร์ที่ถูกแทนที่โดยไฟล์ css

โดยทั่วไปแล้วไฟล์ css ที่แท้จริงของฉันมีอยู่เพื่อจุดประสงค์เดียวในการเก็บเอฟเฟกต์โฮเวอร์ไว้ แต่อย่างอื่น สิ่งนี้ทำให้มันค่อนข้างรัดกุมและง่ายต่อการจัดการและช่วยให้ฉันสามารถยกของหนักในรูปแบบองค์ประกอบ Inact ของฉัน

นี่คือตัวอย่าง:

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: โฮเวอร์เอฟเฟ็กต์ด้วยสีและรูปภาพในบรรทัด

`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.