- What is JSX and how is it different than HTML?
- What are syntactic differences between HTML and JSX?
- What are the two ways to add style to a component in React?
- How do you import stylesheets into React application?
Styling has been one of the building blocks of web development. Cascading Style Sheets is a style sheet language used for describing the presentation of a document written in a markup language like HTML. React only provides a virtual DOM, whereas the presentation part still lies with CSS.
- Styling in React JSX.
- Inline styling and using external stylesheet.
- Defining styles as objects.
- Importing stylesheets into React application.
- Video: Styling of React App in 3 different ways - Using inline CSS, external CSS and CSS modules.
- Look through these slides: CSS in React
Note: No need to watch any sections on React Bootstrap, since we've recently removed Bootstrap from the curriculum.
Let's create a simple div, and style it using inline CSS and flexbox. Then we will achieve the same using external CSS instead.
- Fork this CodePen starter code to your account and name it
Styling In React
. - First of all get rid of all the unnecessary stuff showing on DOM , remove all the lines in render of
App.js
. - Now we create a simple div parent div which will contain few div as child elements. - After creating that , yourApp.js
will look like this -
const App = () => {
return (
<div className="App">
<div>
<div>Child Div 1</div>
<div>Child Div 2</div>
<div>Child Div 3</div>
</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
-
Now we will be adding CSS to this App to differentiate the div elements and achieve this one by one using
- Inline CSS
- External CSS file
To differentiate, we will add background color, simple padding and divide the parent div into flex box.
-
Using inline CSS:
- Let us give a background color and some margin on top and bottom to parent element and make its display as flex.
<div style={{margin:"10px 0", backgroundColor:"orange", display:"flex"}} >
- Now add
backgroundColor
to each child div with some padding and flex basis.
<div style={{ flexBasis: '25%', padding: '10px', backgroundColor: 'green' }} > Child Div 1 </div>
-
Your
App.js
will look like:<div className="App"> {/* Start of Parent Div */} <div style={{ margin: '10px 0', backgroundColor: 'orange', display: 'flex' }} > {/* Start of Child Divs */} <div style={{ flexBasis: '25%', padding: '10px', backgroundColor: 'green' }} > Child Div 1 </div> <div style={{ flexBasis: '25%', padding: '10px', backgroundColor: 'red' }} > Child Div 2 </div> <div style={{ flexBasis: '25%', padding: '10px', backgroundColor: 'blue' }} > Child Div 3 </div> </div> {/* End of Parent Div */} </div>
- Let us give a background color and some margin on top and bottom to parent element and make its display as flex.
-
Using external CSS
-
In your CSS file in the CodePen, add a parent class with same styling as you did in inline CSS.
-
Create a class for each child element.
-
Your CSS file will look like - -
.parent { margin: 10px 0; display: flex; width: 100vw; background-color: darkorange; } .child1 { flex-basis: 25%; max-width: 25%; padding: 10px; background-color: green; } .child2 { flex-basis: 25%; max-width: 25%; padding: 10px; background-color: red; } .child3 { flex-basis: 25%; max-width: 25%; padding: 10px; background-color: blue; }
-
Your
App.js
will look like:return ( <div className="App"> {/* Start of Parent Div */} <div className="parent"> {/* Start of Child Divs */} <div className="child1">Child 1</div> <div className="child2">Child 2</div> <div className="child3">Child 3</div> </div> {/* End of Parent Div */} </div> );
-
-
Avoid these mistakes when combining different classes based on certain state/props.
- When a component is receiving a prop and CSS is rendered depending upon the value of that prop.
- Let us take a component, say
ButtonComp
, which returns a button and adds a classbtn-class
as default class to the button in the component. Now if the component receives a prop ascolor
, then an additionalerror
class should be added to the button in that component.- If color is received as a prop by the component then
className = "error btn-class"
- else
className = "btn-class"
- If color is received as a prop by the component then
-
Incorrect Way
<button className={'btn-class' + props.color ? 'error' : ''}> ButtonComp{' '} </button>
- Reason - ClassName only accepts a single string. The
+
operator beforeprops.color
will try to parse it to an integer value. Therefore it always takes thetrue
value and displays the error class.
- Reason - ClassName only accepts a single string. The
-
Incorrect Way
<button className = { <button className = {props.color ? "error" : "" + "btn-class" }>ButtonComp </button>
- Reason - ClassName takes a single string. Hence if the component receives a prop as color, the
error
class will be displayed, whereas if thecolor
prop is not received by the component then an empty string""
+
btn-class
makes the classNamebtn-class
.- However, our requirement was to add not only the
error
class but alsobtn-class
when acolor
prop is received.
- However, our requirement was to add not only the
- Reason - ClassName takes a single string. Hence if the component receives a prop as color, the
-
Correct Way
Or if we use backticks, it can be written as -<button className={props.color ? 'btn-class error' : 'btn-class'}> ButtonComp{' '} </button>
-
Alternate Correct Way
<button className={`btn-class ${props.color ? 'error' : ''}`}> ButtonComp{' '} </button>
-
Wrong path provided while importing CSS in your file structure.
-
If the path provided for external CSS file or module in the JSX file is incorrect then React throws an error, i.e. it will not be able to build the webpack. The error will look like -
- > Failed to compile. - > ./src/App.js
-
-
Forgetting to use camelCase for CSS styles in React JSX.
-
Using class instead of className gives a warning.
-
If any inline style property is used as two words like background-color, you will encounter an error. This is because these styles are not in a .css file. They are in JSX (Javascript extension for React), so it is actually a JS object; and JS cannot parse dashes. Also note the double curly braces. The outer set of braces means “now instead of React JSX, what’s in these braces will be pure JavaScript.”
style={}
. Then inside is a JS object{backgroundColor: “red”}
.-
Incorrect Way:
<button style={{background-color:"red" }}>
-
Correct Way:
<button style={{backgroundColor:"red"}} >
-
-
More advanced CSS tools used in real life include:
-
Organizing your CSS with Sass
-
Materialize CSS framework is slick and pretty widely used. They have a great "atomic" library of ready-to-use classes that are really well organized.
-
Tailwind CSS framework starts with a large set of classes out of the box that you can then customize.
-
Styled Components is the result of wondering how we could enhance CSS for styling React component systems.
- Why choose Styled Components?
- No class name bugs: styled-components generates unique class names for your styles. You never have to worry about duplication, overlap or misspellings.
- Simple dynamic styling: adapting the styling of a component based on its props or a global theme is simple and intuitive without having to manually manage dozens of classes.
- Example
import styled from 'styled-components'; const Button = styled.button` background: transparent; border-radius: 3px; border: 2px solid palevioletred; color: palevioletred; margin: 0 1em; padding: 0.25em 1em; `; render(<Button>Do something</Button>);
- Why choose Styled Components?