问题
I\'m aware that you can specify styles within React classes, like this:
var MyDiv = React.createClass({
render: function() {
var style = {
color: \'white\',
fontSize: 200
};
return <div style={style}> Have a good and productive day! </div>;
}
});
Should I be aiming to do all styling this way, and have no styles at all specified in my CSS file?
Or should I avoid inline styles completely?
It seems odd and messy to do a little bit of both - two places would need to be checked when tweaking styling.
回答1:
There aren't a lot of "Best Practices" yet. Those of us that are using inline-styles, for React components, are still very much experimenting.
There are a number of approaches that vary wildly: React inline-style lib comparison chart
All or nothing?
What we refer to as "style" actually includes quite a few concepts:
- Layout — how an element/component looks in relationship to others
- Appearance — the characteristics of an element/component
- Behavior and state — how an element/component looks in a given state
Start with state-styles
React is already managing the state of your components, this makes styles of state and behavior a natural fit for colocation with your component logic.
Instead of building components to render with conditional state-classes, consider adding state-styles directly:
// Typical component with state-classes
<li
className={classnames({ 'todo-list__item': true, 'is-complete': item.complete })} />
// Using inline-styles for state
<li className='todo-list__item'
style={(item.complete) ? styles.complete : {}} />
Note that we're using a class to style appearance but no longer using any .is-
prefixed class for state and behavior.
We can use Object.assign
(ES6) or _.extend
(underscore/lodash) to add support for multiple states:
// Supporting multiple-states with inline-styles
<li 'todo-list__item'
style={Object.assign({}, item.complete && styles.complete, item.due && styles.due )}>
Customization and reusability
Now that we're using Object.assign
it becomes very simple to make our component reusable with different styles. If we want to override the default styles, we can do so at the call-site with props, like so: <TodoItem dueStyle={ fontWeight: "bold" } />
. Implemented like this:
<li 'todo-list__item'
style={Object.assign({},
item.due && styles.due,
item.due && this.props.dueStyles)}>
Layout
Personally, I don't see compelling reason to inline layout styles. There are a number of great CSS layout systems out there. I'd just use one.
That said, don't add layout styles directly to your component. Wrap your components with layout components. Here's an example.
// This couples your component to the layout system
// It reduces the reusability of your component
<UserBadge
className="col-xs-12 col-sm-6 col-md-8"
firstName="Michael"
lastName="Chan" />
// This is much easier to maintain and change
<div class="col-xs-12 col-sm-6 col-md-8">
<UserBadge
firstName="Michael"
lastName="Chan" />
</div>
For layout support, I often try to design components to be 100%
width
and height
.
Appearance
This is the most contentious area of the "inline-style" debate. Ultimately, it's up to the component your designing and the comfort of your team with JavaScript.
One thing is certain, you'll need the assistance of a library. Browser-states (:hover
, :focus
), and media-queries are painful in raw React.
I like Radium because the syntax for those hard parts is designed to model that of SASS.
Code organization
Often you'll see a style object outside of the module. For a todo-list component, it might look something like this:
var styles = {
root: {
display: "block"
},
item: {
color: "black"
complete: {
textDecoration: "line-through"
},
due: {
color: "red"
}
},
}
getter functions
Adding a bunch of style logic to your template can get a little messy (as seen above). I like to create getter functions to compute styles:
React.createClass({
getStyles: function () {
return Object.assign(
{},
item.props.complete && styles.complete,
item.props.due && styles.due,
item.props.due && this.props.dueStyles
);
},
render: function () {
return <li style={this.getStyles()}>{this.props.item}</li>
}
});
Further watching
I discussed all of these in more detail at React Europe earlier this year: Inline Styles and when it's best to 'just use CSS'.
I'm happy to help as you make new discoveries along the way :) Hit me up -> @chantastic
回答2:
The style attribute in React expect the value to be an object, ie Key value pair.
style = {}
will have another object inside it like {float:'right'}
to make it work.
<span style={{float:'right'}}>{'Download Audit'}</span>
Hope this solves the problem
回答3:
I use inline styles extensively within my React components. I find it so much clearer to colocate styles within components because it's always clear what styles the component does and doesn't have. Plus having the full power of Javascript at hand really simplifies more complex styling needs.
I wasn't convinced at first but after dabbling in it for several months, I'm fully converted and am in process of converting all my CSS to inline or other JS-driven css methods.
This presentation by Facebook employee and React contributor "vjeux" is really helpful as well — https://speakerdeck.com/vjeux/react-css-in-js
回答4:
The main purpose of the style attribute is for dynamic, state based styles. For example, you could have a width style on a progress bar based on some state, or the position or visibility based on something else.
Styles in JS impose the limitation that the application can't provide custom styling for a reusable component. This is perfectly acceptable in the aforementioned situations, but not when you change the visible characteristics, especially color.
回答5:
James K Nelson in his letter "Why You Shouldn’t Style React Components With JavaScript" states that there is no actually need of using inline styles with its downsides. His statement is that old boring css with less/scss is the best solution. The part of his thesises in favor to css:
- extendable externally
- leverable (inline styles overleap everything)
- designer-friendly
回答6:
What I do is give each one of my reusable component a unique custom element name and then create a css file for that component, specifically, with all styling options for that component (and only for that component).
var MyDiv = React.createClass({
render: function() {
return <custom-component style={style}> Have a good and productive day! </custom-component>;
}
});
And in file 'custom-component.css', every entry will start with the custom-component tag:
custom-component {
display: block; /* have it work as a div */
color: 'white';
fontSize: 200;
}
custom-component h1 {
font-size: 1.4em;
}
That means you don't loose the critical notion of separating of concern. View vs style. If you share your component, it is easier for other to theme it to match the rest of their web page.
回答7:
Styling in JSX is very similar to styling in HTML.
HTML Case:
div style="background-color: red; color: white"
JSX Case:
div style={{ backgroundColor: 'red', color: 'white' }}
回答8:
It's really depends on how big your application is, if you wanna use bundlers like webpack and bundle CSS and JS together in the build and how you wanna mange your application flow! At the end of day, depends on your situation, you can make decision!
My preference for organising files in big projects are separating CSS and JS files, it could be easier to share, easier for UI people to just go through CSS files, also much neater file organising for the whole application!
Always think this way, make sure in developing phase everything are where they should be, named properly and be easy for other developers to find things...
I personally mix them depends on my need, for example... Try to use external css, but if needed React will accept style as well, you need to pass it as an object with key value, something like this below:
import React from 'react';
const App = props => {
return (
<div className="app" style={{background: 'red', color: 'white'}}> /*<<<<look at style here*/
Hello World...
</div>
)
}
export default App;
回答9:
Here is the boolean based styling in JSX syntax:
style={{display: this.state.isShowing ? "inherit" : "none"}}
回答10:
I usually have scss file associated to each React component. But, I don't see reason why you wouldn't encapsulate the component with logic and look in it. I mean, you have similar thing with web components.
回答11:
Depending on your configuration inline styling can offer you Hot reload. The webpage is immediately re-rendered every time the style changes. This helps me develop components quicker. Having said that, I am sure you can setup a Hot reload environment for CSS + SCSS.
回答12:
For some components, it is easier to use inline styles. Also, I find it easier and more concise (as I'm using Javascript and not CSS) to animate component styles.
For stand-alone components, I use the 'Spread Operator' or the '...'. For me, it's clear, beautiful, and works in a tight space. Here is a little loading animation I made to show it's benefits:
<div style={{...this.styles.container, ...this.state.opacity}}>
<div style={{...this.state.colors[0], ...this.styles.block}}/>
<div style={{...this.state.colors[1], ...this.styles.block}}/>
<div style={{...this.state.colors[2], ...this.styles.block}}/>
<div style={{...this.state.colors[7], ...this.styles.block}}/>
<div style={{...this.styles.block}}/>
<div style={{...this.state.colors[3], ...this.styles.block}}/>
<div style={{...this.state.colors[6], ...this.styles.block}}/>
<div style={{...this.state.colors[5], ...this.styles.block}}/>
<div style={{...this.state.colors[4], ...this.styles.block}}/>
</div>
this.styles = {
container: {
'display': 'flex',
'flexDirection': 'row',
'justifyContent': 'center',
'alignItems': 'center',
'flexWrap': 'wrap',
'width': 21,
'height': 21,
'borderRadius': '50%'
},
block: {
'width': 7,
'height': 7,
'borderRadius': '50%',
}
}
this.state = {
colors: [
{ backgroundColor: 'red'},
{ backgroundColor: 'blue'},
{ backgroundColor: 'yellow'},
{ backgroundColor: 'green'},
{ backgroundColor: 'white'},
{ backgroundColor: 'white'},
{ backgroundColor: 'white'},
{ backgroundColor: 'white'},
{ backgroundColor: 'white'},
],
opacity: {
'opacity': 0
}
}
Then, in componentWillMount(), I set an interval like so...
this.interval = setInterval(() => {
let colors = this.state.colors;
let opacity = this.state.opacity;
if(this.props.reverse) {
let color = colors[colors.length-1];
colors.pop();
colors.unshift(color)
} else {
let color = colors[0];
colors.shift();
colors.push(color);
}
opacity['opacity'] < 1 ? opacity['opacity']+=0.06 : null;
this.setState({colors, opacity});
}, this.speed);
回答13:
You can use inline styles but you will have some limitations if you are using them in all of your stylings, some known limitations are you can't use CSS pseudo selectors and media queries in there.
You can use Radium to solve this but still, I feel has the project grows its gonna get cumbersome.
I would recommend using CSS modules.
using CSS Modules you will have the freedom of writing CSS in CSS file and don't have to worry about the naming clashes, it will be taken care by CSS Modules.
An advantage of this method is that it gives you styling functionality to the specific component. This will create much more maintainable code and readable project architecture for the next developer to work on your project.
回答14:
The problem with inline styles is Content Security Policies (CSP) are becoming more common, which do not allow it. Therefore, I recommend avoiding inline styles completely.
Update: To explain further, CSP are HTTP headers sent by the server that restrict what content can appear on the page. It is simply a further mitigation that can be applied to a server to stop an attacker from doing something naughty if the developer code the site poorly.
The purpose of most of these restrictions is to stop XSS (cross-site scripting) attacks. XSS is where an attacker figures out a way to include his own javascript on your page (for example, if I make my username bob<SCRIPT>alert("hello")</SCRIPT>
and then post a comment, and you visit the page, it shouldn't show an alert). Developers should deny the ability to have a user add content like this to the site, but just in case they made a mistake, then CSP blocks the page from loading if it finds any script>
tags.
CSP are just an extra level of protection for developers to ensure if they made a mistake, that an attacker can't cause problems to visitors to that site.
So that all is XSS, but what if the attacker can't include <script>
tags but can include <style>
tags or include a style=
parameter on a tag? Then he might be able to change the look of the site in such a way that you're tricked into clicking the wrong button, or some other problem. This is much less of a concern, but still something to avoid, and CSP does that for you.
A good resource for testing a site for CSP is https://securityheaders.io/
You can read more about CSP at: http://www.html5rocks.com/en/tutorials/security/content-security-policy/
回答15:
Comparing to writing your styles in a css file, React's style attribute has the following advantages:
- The ability to use the tools javascript as a programming language provides to control the style of your elements. This includes embedding variables, using conditions, and passing styles to a child component.
- A "componental" approach. No more seperation of of HTML, JS, and CSS code written for the component. Component's code is consolidated, and written in one place.
However, the React's style attribute comes with a few drawbacks - you can't
- Can't use media queries
- Can't use pseudo selectors,
- less effecient compared to CSS classes.
Using CSS in JS, you can get all the advantages of a style tag, without those drawbacks. As of today there are a few popular well supported css in js-libraries, including: Emotion, Styled-Components, and Radium. Those libraries are to css kind of what React is to HTML. They allow you to write your CSS and control your CSS in your JS code.
let's compare how our code will look for styling a simple element. We'll style a "hello world" div so it shows big on desktop, and smaller on mobile.
Using the style attribute
return (
<div style={{fontSize:24}} className="hello-world">
Hello world
</div>
)
Since media query is not possible in a style tag, we'll have to add a className to the element and add a css rule.
@media screen and (max-width: 700px){
.hello-world {
font-size: 16px;
}
}
Using Emotion's 10 css tag
return (
<div
css={{
fontSize: 24,
[CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY]:{
fontSize: 16
}
}
>
Hello world
</div>
)
Emotion also supports template strings as well as styled components. So if you prefer you can write:
return (
<Box>
Hello world
</Box>
)
const Box = styled.div`
font-size: 24px;
${CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY}{
font-size: 16px;
}
`
Behind the hoods "Css in JS" uses css classes. Emotion specifically was build with performance in mind, and uses caching. Compared to React style attributes Css in JS will provide better performance.
Best Practices
Here are a few best practices I recommend:
- If you want to style your elements inline, or in your JS, use a css-in-js library, don't use a style attribute.
Should I be aiming to do all styling this way, and have no styles at all specified in my CSS file?
- If you use a css-in-js solution there is no need to write styles in Css files. Writting your css in JS is superior as you can use all the tools a programming language as JS provides.
should I avoid inline styles completely?
- Structuring your style code in JS is pretty similar to structuring your code in general. For example:
- recognize styles that repeat, and write them in one place. There are two ways to do this in Emotion:
// option 1 - Write common styles in CONSTANT variables
// styles.js
export const COMMON_STYLES = {
BUTTON: css`
background-color: blue;
color: white;
:hover {
background-color: dark-blue;
}
`
}
// SomeButton.js
const SomeButton = (props) => {
...
return (
<button
css={COMMON_STYLES.BUTTON}
...
>
Click Me
</button>
)
}
// Option 2 - Write your common styles in a dedicated component
const Button = styled.button`
background-color: blue;
color: white;
:hover {
background-color: dark-blue;
}
`
const SomeButton = (props) => {
...
return (
<Button ...>
Click me
</Button>
)
}
React coding pattern is of encapsulated components - HTML and JS that controls a component is written in one file. That is where your css/style code to style that component belongs.
When necessary, add a styling prop to your component. This way you can reuse code and style written in a child component, and customize it to your specific needs by the parent component.
const Button = styled.button([COMMON_STYLES.BUTTON, props=>props.stl])
const SmallButton = (props)=>(
<Button
...
stl={css`font-size: 12px`}
>
Click me if you can see me
</Button>
)
const BigButton = (props) => (
<Button
...
stl={css`font-size: 30px;`}
>
Click me
</Button>
)
回答16:
You can use StrCSS as well, it creates isolated classnames and much more! Example code would look like. You can (optional) install the VSCode extension from the Visual Studio Marketplace for syntax highlighting support!
source: strcss
import { Sheet } from "strcss";
import React, { Component } from "react";
const sheet = new Sheet(`
map button
color green
color red !ios
fontSize 16
on hover
opacity .5
at mobile
fontSize 10
`);
export class User extends Component {
render() {
return <div className={sheet.map.button}>
{"Look mom, I'm green!
Unless you're on iOS..."}
</div>;
}
}
回答17:
Some time we require to style some element from a component but if we have to display that component only ones or the style is so less then instead of using the CSS class we go for the inline style in react js. reactjs inline style is as same as HTML inline style just the property names are a little bit different
Write your style in any tag using style={{prop:"value"}}
import React, { Component } from "react";
import { Redirect } from "react-router";
class InlineStyle extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<div>
<div
style={{
color: "red",
fontSize: 40,
background: "green"
}}// this is inline style in reactjs
>
</div>
</div>
</div>
);
}
}
export default InlineStyle;
来源:https://stackoverflow.com/questions/26882177/react-js-inline-style-best-practices