Table of Contents
For generations, mankind (and probably really smart dolphins) have styled their HTML content using CSS. Things were good. With CSS, you had a good separation between the content and the presentation. The selector syntax gave you a lot of flexibility in choosing which elements to style and which ones to skip. You couldn't even find too many issues to hate the whole cascading thing that CSS is all about.
Well, don't tell React that. While React doesn't actively hate CSS, it has a different view when it comes to styling content. As we've seen so far, one of React's core ideas is to have our app's visual pieces be self-contained and reusable. That is why the HTML elements and the JavaScript that impacts them are in the same bucket we call a component. We got a taste of that in the previous article.
What about how the HTML elements look (aka their styling)? Where should they go? You can probably guess where I am going with this. You can't have a self-contained piece of UI when the styling for it is defined somewhere else. That's why, React encourages you to specify how your elements look right along side the HTML and the JavaScript. In this tutorial, we'll learn all about this mysterious (and possibly scandalous!) approach for styling your content. Of course, we'll also look at how to use CSS as well. There is room for both approaches...even if React may sorta kinda not think so :P
Onwards!
To kick your React skills up a few notches, everything you see here and more (with all its casual clarity!) is available in both paperback and digital editions.
BUY ON AMAZONTo learn how to style our React content, let's work together on a (totally sweet and exciting!) example that simply displays vowels on a page. First, you'll need a blank HTML page that will host our React content. If you don't have one, feel free to use the following markup:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Styling in React</title> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/[email protected]/babel.min.js"></script> <style> #container { padding: 50px; background-color: #FFF; } </style> </head> <body> <div id="container"></div> </body> </html>
All this markup does is load in our React and Babel libraries and specifies a div with an id value of container. To display the vowels, we're going to add some React-specific code.
Just below the container div element, add the following:
<script type="text/babel"> var destination = document.querySelector("#container"); class Letter extends React.Component { render() { return( <div> {this.props.children} </div> ); } } ReactDOM.render( <div> <Letter>A</Letter> <Letter>E</Letter> <Letter>I</Letter> <Letter>O</Letter> <Letter>U</Letter> </div>, destination ); </script>
From what we learned about Components earlier, nothing here should be a mystery. We create a component called Letter that is responsible for wrapping our vowels inside a div element. All of this is anchored in our HTML via a script tag whose type designates it as something Babel will know what to do with.
If you preview your page, you'll see something boring that looks as follows:
Don't worry, we'll make it look a little less boring in a few moments. After we've had a run at these letters, you will see something that looks more like the following:
Our vowels will be wrapped in a yellow background, aligned horizontally, and sport a fancy monospace font. Let's look at how to do all of this in both CSS as well as React's new-fangled approach.
Using CSS to style our React content is actually as straightforward as you can imagine it to be. Because React ends up spitting out regular HTML tags, all of the various CSS tricks you've learned over the years to style HTML still apply. There are just a few minor things to keep in mind.
Before you can use CSS, you need to first get a feel for what the HTML that React spits out is going to look. You can easily figure that out by looking the JSX defined inside the render methods. The parent render method is our ReactDOM based one, and it looks as follows:
<div> <Letter>A</Letter> <Letter>E</Letter> <Letter>I</Letter> <Letter>O</Letter> <Letter>U</Letter> </div>
We have our various Letter components wrapped inside a div. Nothing too exciting here. The render method inside our Letter component isn't that much different either:
<div> {this.props.children} </div>
As you can see, each individual vowel is wrapped inside its own set of div tags. If you had to play this all out (such as, previewing our example in a browser), the final DOM structure for our vowels looks like this:
What we have is simply an HTML-ized expansion of the various JSX fragments we saw in the render method a few moments ago with our vowels nested inside a bunch of div elements.
Once you understand the HTML arrangement of the things you want to style, the hard part is done. Now comes the fun and familiar part of defining style selectors and specifying the properties you want to set. To affect our inner div elements, add the following inside our style tag:
div div div { padding: 10px; margin: 10px; background-color: #ffde00; color: #333; display: inline-block; font-family: monospace; font-size: 32px; text-align: center; }
The div div div selector will ensure we style the right things. The end result will be our vowels styled to look exactly like we set out to when starting out. With that said, a style selector of div div div looks a bit odd, doesn't it? It is too generic. In apps with more than three div elements (which will be very common), you may end up styling the wrong things. It is at times like this where you will want to change the HTML that React generates to make our content more easily styleable.
The way we are going to address this is by giving our inner div elements a class value of letter. Here is where JSX differs from HTML. Make the following highlighted change:
class Letter extends React.Component { render() { return ( <div className="letter"> {this.props.children} </div> ); } }
Notice that we designate the class value by using the className attribute instead of the class attribute. The reason has to do with the word class being a special keyword in JavaScript. If that doesn't make any sense why that is important, don't worry about it for now. We'll cover that later.
Anyway, once you've given your div a className attribute value of letter, there is just one more thing to do. Modify the CSS selector to target our div elements more cleanly:
.letter { padding: 10px; margin: 10px; background-color: #ffde00; color: #333; display: inline-block; font-family: monospace; font-size: 32px; text-align: center; }
As you can see, using CSS is a perfectly viable way to style the content in your React-based apps. In the next section, we'll look at how to style our content using the approach preferred by React.
React favors an inline approach for styling content that doesn't use CSS. While that seems a bit strange at first, it is designed to help make your visuals more reusable. The goal is to have your components be little black boxes where everything related to how your UI looks and works gets stashed there. Let's see this for ourselves.
Continuing our example from earlier, remove the .letter style rule. Once you have done this, your vowels will return to their unstyled state when you preview your app in the browser. For completeness, you should remove the className declaration from our Letter component's render function as well. There is no point having our markup contain things we won't be using.
Right now, let's revert our Letter component back to its original state:
class Letter extends React.Component { render() { return ( <div> {this.props.children} </div> ); } }
The way you specify styles inside your component is by defining an object whose content is the CSS properties and their values. Once you have that object, you assign that object to the JSX elements you wish to style by using the style attribute. This will make more sense once we perform these two steps ourselves, so let's apply all of this to style the output of our Letter component.
Let's get right to it by defining our object that contains the styles we wish to apply:
class Letter extends React.Component { render() { var letterStyle = { padding: 10, margin: 10, backgroundColor: "#ffde00", color: "#333", display: "inline-block", fontFamily: "monospace", fontSize: 32, textAlign: "center" }; return ( <div> {this.props.children} </div> ); } }
We have an object called letterStyle, and the properties inside it are just CSS property names and their value. If you've never defined CSS properties in JavaScript before (ie, by setting object.style), the formula for converting them into something JavaScript-friendly is pretty simple:
Our letterStyle object and its properties are pretty much a direct JavaScript translation of the .letter style rule we looked at a few moments ago. All that remains now is to assign this object to the element we wish to style.
Now that we have our object containing the styles we wish to apply, the rest is very easy. Find the element we wish to apply the style on and set the style attribute to refer to that object. In our case, that will be the div element returned by our Letter component's render function.
Take a look at the highlighted line to see how this is done for our example:
class Letter extends React.Component { render() { var letterStyle = { padding: 10, margin: 10, backgroundColor: "#ffde00", color: "#333", display: "inline-block", fontFamily: "monospace", fontSize: 32, textAlign: "center" }; return( <div style={letterStyle}> {this.props.children} </div> ); } }
Our object is called letterStyle, so that is what we specify inside the curly brackets to let React know to evaluate the expression. That's all there is to it. Go ahead and run the example in the browser to ensure everything works properly and all of our vowels are properly styled.
For some extra validation, if you inspect the styling applied to one of the vowels using your browser developer tool of choice, you'll see that the styles are in-fact applied inline:
While this is no surprise, this might be difficult for those of us used to styles being inside style rules to swallow. As they say, the Times They Are A Changin'.
The last thing we are going to do before we wrap things up is take advantage of how React works with styles. By having our styles defined in the same vicinity as the JSX, we can make the various style values easily customizable by the parent (aka the consumer of the component). Let's see this in action.
Right now, all of our vowels have a yellow background. Wouldn't it be cool if we could specify the background color as part of each Letter declaration? To do this, in our ReactDOM.render method, first add a bgcolor attribute and specify some colors as shown in the following highlighted lines:
ReactDOM.render( <div> <Letter bgcolor="#58B3FF">A</Letter> <Letter bgcolor="#FF605F">E</Letter> <Letter bgcolor="#FFD52E">I</Letter> <Letter bgcolor="#49DD8E">O</Letter> <Letter bgcolor="#AE99FF">U</Letter> </div>, destination );
Next, we need to use this property. In our letterStyle object, set the value of backgroundColor to this.props.bgColor:
var letterStyle = { padding: 10, margin: 10, backgroundColor: this.props.bgcolor, color: "#333", display: "inline-block", fontFamily: "monospace", fontSize: 32, textAlign: "center" };
This will ensure that our the backgroundColor value is inferred from what we set via the bgColor attribute as part of the Letter declaration. If you preview this in your browser, you will now see our same vowels sporting some totally sweet background colors:
What we've just done is something that is going to be very hard to replicate using plain CSS. Now, as we start to look at components whose contents change based on state or user interaction, you'll see more such examples where the React way of styling things has a lot of good merit :P
As we dive further and learn more about React, you'll see several more cases where React does things quite differently than what we've been told is the correct way of doing things on the web. In this tutorial, we saw React promoting inline styles in JavaScript as a way to style content as opposed to using CSS style rules. Earlier, we looked at JSX and how the entirety of your UI can be declared in JavaScript using an XML-like syntax that sorta kinda looks like HTML.
In all of these cases, if you look deeper beneath the surface, the reasons for why React diverges from conventional wisdom makes a lot of sense. Building apps with their very complex UI requirements requires a new way of solving them. HTML, CSS, and JavaScript techniques that probably made a lot of sense when dealing with web pages and documents may not be applicable in the web app world.
With that said, you should pick and choose the techniques that make the most sense for your situation. While I am biased towards React's way of solving our UI development problems, I'll do my best to highlight alternate or conventional methods as well. Tying that back to what we saw here, using CSS style rules with your React content is totally OK as long as you made the decision knowing the things you gain as well as lose by doing so.
Next up: Creating Complex Components
Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!
:: Copyright KIRUPA 2024 //--