So much has been said about the appropriate way to style modern web apps. Thereâs the general and oldest method of styling at document level - creating a style.css file and linking to it in the HTML file and more recently the method of styling in JS. This is popularly known as CSS-in-JS.
CSS-in-JS is a styling approach that abstracts the CSS model to the component level, rather than the document level. This is the idea that CSS can be scoped to a specific component only and as opposed to the document level. The benefits of using CSS-in-JS includes:
An example of the CSS-in-JS approach is styled-components . Styled Components allow you to write plain CSS in your components without worrying about class name collisions. It helps to write CSS thatâs scoped to a single component and does not leak to any other element in the page.
Styled Components enable writing of CSS in JavaScript using tagged template literals. It removes the mapping between components and stylesâââcomponent is made into a low-level styling construct. Styled Components was created because of the following reasons:
We can install Styled Components using NPM, with the command below:
Styled Components utilizes tagged template literals to style your components. It removes the mapping between components and styles. This means that when youâre defining your styles, youâre actually creating a normal React component, that has your styles attached to it.
With the installation done, letâs go ahead to create our first Styled Component. Weâll be creating a reusable Button component styled with Styled Components:
In the code block above, the Button variable created here is a React component that can be used in the function component. The variable is assigned to styled.button which features a backtick syntax, in which you can write the actual CSS.
As you can see, Styled Components allows you to write CSS just the way youâd write in your normal style.css document and even use pseudo-selectors like :hover .
Because React apps work a lot with state, Styled Components also allows you to dynamically set CSS properties using props . You can pass a function to your style declarations, with one parameter, being the componentâs prop value. You can then use props to adjust your styling as seen the Button example below:
In the example, the Button component changes the color , border , and background-color based on the props passed, in this case the primary prop. We are using an arrow function that is passing in props and checking to see if the prop primary is present. If it is, then we are telling JavaScript to render out the CSS style enclosed in additional double back-ticks.
To further understand Styled Components, weâll be using it to build an app, a clone of the popular image sharing app, Instagram.
The goal is to build an Instagram clone and hereâs a screenshot of what the app will look like below:
To get started, weâll need to create a React app and that can be done easily using the create-react-app CLI package. The create-react-app CLI package enables creating React apps easily with no build configuration. The CLI can be used as seen below. This command creates a React app in a folder named stylagram :
In order to build this app, weâll be dividing this app into different components:
Weâll first build out these components individually and then bring everything together at the end.
To create the header component, create a file titled Header.js in the src/components/ folder. You can then edit with the code below:
Our Header component is a navigation bar thatâs split into three sections; the logo which is at the far left, the search bar which is in the middle and the icons which are situated to the far right.
As seen in the code block above, various components styled with Styled Components are created and used to build the navigation bar. Itâs also interesting to note that Styled Components also supports nesting of CSS as seen in the Input component.
As seen above, pseudo-selectors and pseudo-elements are well handled in Styled Components and pretty much everything that can be done in traditional CSS can be done in Styled Components.
To create the header component, create a file titled Profile.js in the src/components/ folder. You can then edit with the code below.
In the code block above, just like the Header.js component, we create various styled components that are used to build the Profile component. The styled variable contains many functions representing all known HTML elements, this allows us to style heading tags, img tags e.t.c as seen in the code block above.
Also, a feedSource array is created, this contains objects of data that will be used to display feed images just like Instagram. The source links are actually linked to my personal Instagram images.
We use the SingleImage component to display the pictures in the feedSource array. The array is iterated through using the .map function and then data is fed to the SingleImage component as props.
To create the header component, create a file titled Image.js in the src/components/ folder. You can then edit with the code below.
In the code block above, the Image function component accepts a prop. That prop is then used in the component itself. The Img component which is an HTML img element styled variable accepts a src attribute which is set to the source value.
If you hover on an Instagram image, you get to see the number of likes, number of comments if itâs an image, and number of plays if itâs a video. Weâll also be replicating that on our version of the Instagram app.
There are icons that are displayed in the ImgIcons component when the image is hovered on (weâll see how thatâs handled later on). One of the Play and Heart icons are displayed conditionally based on if the image.isVideo value is true or false.
As mentioned above, weâll like to see the number of engagements a particular image or video has when hovered on. This is implemented using CSS and by adding an overlay over the image and then showing the likes/views and comments count. Something like the code block below:
In the code block above, the imageContainer div is a parent div and it contains two child divs. When the imageContainer div is hovered on, the display value for the imageOverlay div is set to block thereby creating the dark overlay over the image.
In Styled Components, this can be done by referring to another component within a component. This is known as the âcomponent selectorâ pattern. Whenever a component is created or wrapped by the styled() factory function, it is also assigned a stable CSS class for use in targeting.
As seen in the code snippet above, the Image.js component, the component selector pattern is used like so:
ImgMeta component has a display value of none and this only changes to flex when the parent component ImgContainer is hovered on.
One gotcha for the pattern above is that the styled component been selected needs to have been created before being used in another component. For example, the ImgContainer component was created before being used in the ImgMeta component.
There are cases in which we need to set some styles that apply to every section of the React app. A file like index.css in the src folder should be able to handle this. However, we can go a step further by writing those global styles with Styled Components.
To do that, create a file called globalStyle.js in the newly created src/theme folder.
With the file created, you can go ahead to copy the code block above into it. To start with, the createGlobalStyle function is imported from Styled Components. It is a helper function to generate a special StyledComponent that handles global styles.
With the above done, you can go ahead to place it at the top of your React tree and the global styles will be injected when the component is ârenderedâ.
Styled Components supports extending style. This means styles can be inherited to a new component based on the previous styled component and extend it with some new styles.
In the example above, we used a Button component created in the above and passed it to the styled() constructor to create a new button with extending styles:
You can find out more about extending styles in the Styled Components documentation .
Styled Components also supports the use of easily reusing CSS in other components. It does with a helper function called css which is imported from styled-components package as seen below. The helper function is used to generate CSS from a template literal with interpolations.
In the code block above, if thereâs a prop value of complex the complexMixin styles will be applied to the StyledComp component.
The css helper function also allows the generation of valid CSS using template literals within interpolations, meaning it is used to generate CSS using when inside ${} wrapped inside another template literal string.
In the code block above, the styles defined in the css helper function will only be applied if a prop of primary is present. You can find out more about the css helper function in the Styled Components documentation .
Styled Components has full theming support by exporting a <ThemeProvider> wrapper component. The ThemeProvider wrapper component accepts a theme props and provides a theme to all React components underneath itself via the context API.
This means that all Styled Components will have access to the provided theme, even when they are multiple levels deep.
In the example above, we create a Button component that accepts props for dynamic styles, in this case, a theme prop. The Button component also has a default theme setting for whenever a theme prop is not passed.
In the return statement of the function, there are two variations of the Button, one as a standalone button and one thatâs wrapped in a ThemeProvider component. In the ThemeProvider component, we pass themeSettings as a prop and what that means is that the second button will get the CSS styles defined in the themeSettings object. You can find out more about theming in the Styled Components documentation .
Styled Components allow you to do so much more and weâve only scratched the surface in this tutorial. We just built a simple application (an Instagram clone) which gave us the overview of the Styled Components. You can read more about Styled Components in their official documentation . The codebase for the Stylagram app can be seen on GitHub here . If youâve used Styled Components in your project before, you can write about your experience so far and reviews below.