React 中的内联 CSS 样式:如何实现 a:hover?
Inline CSS styles in React: how to implement a:hover?
我非常喜欢 inline CSS pattern in React 并决定使用它。
但是,您不能使用 :hover
和类似的选择器。那么在使用内联 CSS 样式时实现悬停突出显示的最佳方法是什么?
#reactjs 的一个建议是拥有一个 Clickable
组件并像这样使用它:
<Clickable>
<Link />
</Clickable>
Clickable
有一个 hovered
状态,并将其作为 props 传递给 Link。但是,Clickable
(我实现它的方式)将 Link
包装在 div
中,以便它可以设置 onMouseEnter
和 onMouseLeave
。这让事情变得有点复杂(例如 span
包裹在 div
中的行为与 span
不同)。
有没有更简单的方法?
我也是这种情况。非常喜欢在组件中保留样式的模式,但悬停状态似乎是最后一个障碍。
我所做的是编写一个 mixin,您可以将其添加到需要悬停状态的组件中。
这个 mixin 会添加一个新的 hovered
属性 到你的组件状态。如果用户将鼠标悬停在组件的主要 DOM 节点上,它将设置为 true
,如果用户离开该元素,它将设置回 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
您可以使用 Radium - 它是一个用于 ReactJS 内联样式的开源工具。它恰好添加了您需要的选择器。很受欢迎,看看吧 - Radium on npm
我认为 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) 更改 link 的样式。
您可以使用 css modules as an alternative, and additionally react-css-modules 进行 class 名称映射。
这样您就可以按如下方式导入您的样式,并使用普通 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);
制作 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;
如果您使用 React 和 Typescript,请查看 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>
我在我最近的一个应用程序中为此使用了一个非常 hack-ish 的解决方案,我发现它比在 vanilla js 中编写自定义悬停设置函数更快(虽然,我承认,也许不是大多数环境中的最佳实践..)因此,如果您仍然感兴趣,请继续。
我创建一个父元素只是为了保存内联 javascript 样式,然后是一个具有 className 或 id 的子元素,我的 css 样式表将锁定并写入悬停样式我专用的 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>
请注意,"child" 内联样式没有 "color" 属性 集。如果是这样,这将不起作用,因为内联样式将优先于我的样式表。
完全 CSS 支持正是大量 CSSinJS 库的原因,要有效地做到这一点,您需要生成实际的 CSS,而不是内联样式。此外,内联样式在更大的系统中反应要慢得多。免责声明 - 我维护 JSS.
添加到 ,这里是涵盖焦点和活动状态的事件,并且使用 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>
)
}
关于 styled-components and react-router v4 你可以这样做:
import {NavLink} from 'react-router-dom'
const Link = styled(NavLink)`
background: blue;
&:hover {
color: white;
}
`
...
<Clickable><Link to="/somewhere">somewhere</Link></Clickable>
对于在 React 组件中使用内联样式(以及使用 :hover CSS 函数)来说,这可能是一个很好的 hack:
...
<style>
{`.galleryThumbnail.selected:hover{outline:2px solid #00c6af}`}
</style>
...
onMouseOver 和 onMouseLeave 与 setState 起初对我来说似乎有点开销 - 但由于这是反应的工作方式,对我来说这似乎是最简单和最干净的解决方案。
例如渲染主题 css 服务器端,也是一个很好的解决方案,可以使 React 组件更干净。
如果您不必将动态样式附加到元素(例如用于主题),则根本不应使用内联样式,而应使用 css 类。
这是保持 html / JSX 简洁的传统 html/css 规则。
简单的方法是使用三元运算符
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>
)
}
派对迟到了,但有解决方案。您可以使用“&”来定义 hover 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"
}
},
使用钩子:
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>
);
};
我不是 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;
}
Before hover
.menu-item:nth-child(1) {
color: white;
background-color: #001b37;
}
On hover
.menu-item:nth-child(1):hover {
color: green;
background-color: white;
}
这是我使用 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>
)
}
<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 : {})
});
}
这是另一个使用 CSS 变量的选项。这需要提前 css 悬停定义,所以我猜它不是纯内联的,但代码很少且灵活。
css(设置悬停状态):
.p:hover:{
color:var(--hover-color) !important,
opacity:var(--hover-opacity)
}
反应:
<p style={{'color':'red','--hover-color':'blue','--hover-opacity':0.5}}>
这是用打字稿编写的悬停通用包装器。该组件将在悬停事件上应用通过道具 'hoverStyle' 传递的样式。
import React, { useState } from 'react';
export const Hover: React.FC<{
style?: React.CSSProperties;
hoverStyle: React.CSSProperties;
}> = ({ style = {}, hoverStyle, children }) => {
const [isHovered, setHovered] = useState(false);
const calculatedStyle = { ...style, ...(isHovered ? hoverStyle : {}) };
return (
<div
style={calculatedStyle}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{children}
</div>
);
};
这可以通过 material-ui makeStyles
调用轻松实现:
import { makeStyles } from '@material-ui/core/styles';
makeStyles({
root: {
/* … */
'&:hover': { /* … */ }
},
});
我使用这个技巧,混合了内联样式和 css:
//inline-style:
const button = {
fontSize: "2em",
};
return (
<div style={button} data-hover="button">
<style>{`[data-hover="button"]:hover {
font-size: 2.1em !important;
}`}</style>
{this.props.text}
</div>
);
我做了类似于 的事情,但我没有使用 material-ui 或 makeStyles。我在样式对象的 css 中将悬停作为条件添加:
const styles = {
hoverStyle: {
color: 'grey',
'&:hover': { color: 'blue !important' },
}
};
var NavBar = (props) => {
const menuOptions = ['home', 'blog', 'projects', 'about'];
return (
<div>
<div>
{menuOptions.map((page) => <div style={styles.hoverStyle} key={page}>{page}</div> )}
</div>
</div>
);
};
这对我有用。
我找到了一种干净的方法来使用 useState
周围的包装器来完成此操作,我称之为 useHover
.
不需要额外 libraries/frameworks。
const App = () => {
const hover = useHover({backgroundColor: "LightBlue"})
return <p {...hover}>Hover me!</p>
}
包装代码:
function useHover(styleOnHover: CSSProperties, styleOnNotHover: CSSProperties = {})
{
const [style, setStyle] = React.useState(styleOnNotHover);
const onMouseEnter = () => setStyle(styleOnHover)
const onMouseLeave = () => setStyle(styleOnNotHover)
return {style, onMouseEnter, onMouseLeave}
}
请注意,当组件未悬停时,useHover
有一个可选的第二个样式参数。
试试看here
您可以创建一个 abstract
悬停 class 例如对于颜色。
.hoverClassColor:hover {
color:var(--hover-color) !important;
}
然后对于您想要在悬停时将颜色更改为 red
的所有元素:
render() {
return <a className={'hoverClassColor'} style={{'--hover-color':'red'}}>Test</a>
}
对我来说它就像内联,因为 classes 是抽象的,可以重复用于你想要实现颜色悬停的所有元素。
以下是我在功能组件中使用钩子的方法。使用onMouseEnter/Leave
,我直接将颜色设置为状态并在元素的样式道具中使用它(而不是设置悬停状态并使用三元组来更改状态,如前面的答案所示)。
function App() {
const [col, setCol] = React.useState('white');
return (
<div className="App">
<button
style={{background: `${col}`}}
onMouseEnter={() => setCol("red")}
onMouseLeave={() => setCol("white")}
>
Red
</button>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>
onMouseEnter={(e) => {
e.target.style.backgroundColor = '#e13570';
e.target.style.border = '2px solid rgb(31, 0, 69)';
e.target.style.boxShadow = '-2px 0px 7px 2px #e13570';
}}
onMouseLeave={(e) => {
e.target.style.backgroundColor = 'rgb(31, 0, 69)';
e.target.style.border = '2px solid #593676';
e.target.style.boxShadow = '-2px 0px 7px 2px #e13570';
}}
在样式中设置默认属性或class然后调用 onMouseLeave() 和 onMouseEnter() 来创建悬停功能。
我非常喜欢 inline CSS pattern in React 并决定使用它。
但是,您不能使用 :hover
和类似的选择器。那么在使用内联 CSS 样式时实现悬停突出显示的最佳方法是什么?
#reactjs 的一个建议是拥有一个 Clickable
组件并像这样使用它:
<Clickable>
<Link />
</Clickable>
Clickable
有一个 hovered
状态,并将其作为 props 传递给 Link。但是,Clickable
(我实现它的方式)将 Link
包装在 div
中,以便它可以设置 onMouseEnter
和 onMouseLeave
。这让事情变得有点复杂(例如 span
包裹在 div
中的行为与 span
不同)。
有没有更简单的方法?
我也是这种情况。非常喜欢在组件中保留样式的模式,但悬停状态似乎是最后一个障碍。
我所做的是编写一个 mixin,您可以将其添加到需要悬停状态的组件中。
这个 mixin 会添加一个新的 hovered
属性 到你的组件状态。如果用户将鼠标悬停在组件的主要 DOM 节点上,它将设置为 true
,如果用户离开该元素,它将设置回 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
您可以使用 Radium - 它是一个用于 ReactJS 内联样式的开源工具。它恰好添加了您需要的选择器。很受欢迎,看看吧 - Radium on npm
我认为 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) 更改 link 的样式。
您可以使用 css modules as an alternative, and additionally react-css-modules 进行 class 名称映射。
这样您就可以按如下方式导入您的样式,并使用普通 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);
制作 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;
如果您使用 React 和 Typescript,请查看 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>
我在我最近的一个应用程序中为此使用了一个非常 hack-ish 的解决方案,我发现它比在 vanilla js 中编写自定义悬停设置函数更快(虽然,我承认,也许不是大多数环境中的最佳实践..)因此,如果您仍然感兴趣,请继续。
我创建一个父元素只是为了保存内联 javascript 样式,然后是一个具有 className 或 id 的子元素,我的 css 样式表将锁定并写入悬停样式我专用的 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>
请注意,"child" 内联样式没有 "color" 属性 集。如果是这样,这将不起作用,因为内联样式将优先于我的样式表。
完全 CSS 支持正是大量 CSSinJS 库的原因,要有效地做到这一点,您需要生成实际的 CSS,而不是内联样式。此外,内联样式在更大的系统中反应要慢得多。免责声明 - 我维护 JSS.
添加到 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>
)
}
关于 styled-components and react-router v4 你可以这样做:
import {NavLink} from 'react-router-dom'
const Link = styled(NavLink)`
background: blue;
&:hover {
color: white;
}
`
...
<Clickable><Link to="/somewhere">somewhere</Link></Clickable>
对于在 React 组件中使用内联样式(以及使用 :hover CSS 函数)来说,这可能是一个很好的 hack:
...
<style>
{`.galleryThumbnail.selected:hover{outline:2px solid #00c6af}`}
</style>
...
onMouseOver 和 onMouseLeave 与 setState 起初对我来说似乎有点开销 - 但由于这是反应的工作方式,对我来说这似乎是最简单和最干净的解决方案。
例如渲染主题 css 服务器端,也是一个很好的解决方案,可以使 React 组件更干净。
如果您不必将动态样式附加到元素(例如用于主题),则根本不应使用内联样式,而应使用 css 类。
这是保持 html / JSX 简洁的传统 html/css 规则。
简单的方法是使用三元运算符
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>
)
}
派对迟到了,但有解决方案。您可以使用“&”来定义 hover 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"
}
},
使用钩子:
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>
);
};
我不是 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;
}
Before hover
.menu-item:nth-child(1) {
color: white;
background-color: #001b37;
}
On hover
.menu-item:nth-child(1):hover {
color: green;
background-color: white;
}
这是我使用 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>
)
}
<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 : {})
});
}
这是另一个使用 CSS 变量的选项。这需要提前 css 悬停定义,所以我猜它不是纯内联的,但代码很少且灵活。
css(设置悬停状态):
.p:hover:{
color:var(--hover-color) !important,
opacity:var(--hover-opacity)
}
反应:
<p style={{'color':'red','--hover-color':'blue','--hover-opacity':0.5}}>
这是用打字稿编写的悬停通用包装器。该组件将在悬停事件上应用通过道具 'hoverStyle' 传递的样式。
import React, { useState } from 'react';
export const Hover: React.FC<{
style?: React.CSSProperties;
hoverStyle: React.CSSProperties;
}> = ({ style = {}, hoverStyle, children }) => {
const [isHovered, setHovered] = useState(false);
const calculatedStyle = { ...style, ...(isHovered ? hoverStyle : {}) };
return (
<div
style={calculatedStyle}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{children}
</div>
);
};
这可以通过 material-ui makeStyles
调用轻松实现:
import { makeStyles } from '@material-ui/core/styles';
makeStyles({
root: {
/* … */
'&:hover': { /* … */ }
},
});
我使用这个技巧,混合了内联样式和 css:
//inline-style:
const button = {
fontSize: "2em",
};
return (
<div style={button} data-hover="button">
<style>{`[data-hover="button"]:hover {
font-size: 2.1em !important;
}`}</style>
{this.props.text}
</div>
);
我做了类似于
const styles = {
hoverStyle: {
color: 'grey',
'&:hover': { color: 'blue !important' },
}
};
var NavBar = (props) => {
const menuOptions = ['home', 'blog', 'projects', 'about'];
return (
<div>
<div>
{menuOptions.map((page) => <div style={styles.hoverStyle} key={page}>{page}</div> )}
</div>
</div>
);
};
这对我有用。
我找到了一种干净的方法来使用 useState
周围的包装器来完成此操作,我称之为 useHover
.
不需要额外 libraries/frameworks。
const App = () => {
const hover = useHover({backgroundColor: "LightBlue"})
return <p {...hover}>Hover me!</p>
}
包装代码:
function useHover(styleOnHover: CSSProperties, styleOnNotHover: CSSProperties = {})
{
const [style, setStyle] = React.useState(styleOnNotHover);
const onMouseEnter = () => setStyle(styleOnHover)
const onMouseLeave = () => setStyle(styleOnNotHover)
return {style, onMouseEnter, onMouseLeave}
}
请注意,当组件未悬停时,useHover
有一个可选的第二个样式参数。
试试看here
您可以创建一个 abstract
悬停 class 例如对于颜色。
.hoverClassColor:hover {
color:var(--hover-color) !important;
}
然后对于您想要在悬停时将颜色更改为 red
的所有元素:
render() {
return <a className={'hoverClassColor'} style={{'--hover-color':'red'}}>Test</a>
}
对我来说它就像内联,因为 classes 是抽象的,可以重复用于你想要实现颜色悬停的所有元素。
以下是我在功能组件中使用钩子的方法。使用onMouseEnter/Leave
,我直接将颜色设置为状态并在元素的样式道具中使用它(而不是设置悬停状态并使用三元组来更改状态,如前面的答案所示)。
function App() {
const [col, setCol] = React.useState('white');
return (
<div className="App">
<button
style={{background: `${col}`}}
onMouseEnter={() => setCol("red")}
onMouseLeave={() => setCol("white")}
>
Red
</button>
</div>
);
}
ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>
onMouseEnter={(e) => {
e.target.style.backgroundColor = '#e13570';
e.target.style.border = '2px solid rgb(31, 0, 69)';
e.target.style.boxShadow = '-2px 0px 7px 2px #e13570';
}}
onMouseLeave={(e) => {
e.target.style.backgroundColor = 'rgb(31, 0, 69)';
e.target.style.border = '2px solid #593676';
e.target.style.boxShadow = '-2px 0px 7px 2px #e13570';
}}
在样式中设置默认属性或class然后调用 onMouseLeave() 和 onMouseEnter() 来创建悬停功能。