React CSS
Tags: tutorial, javascript, css, react
Published: 2021-01-04 22:45:52

###### *This article is sponsored by [Flutterwave](https://dashboard.flutterwave.com/signup?referrals=RV686851) - Flutterwave is the easiest way to make and accept payments both online and offline from customers anywhere in the world. It is absolutely free!*

Styles can be applied to a component from an external CSS file. The *Person/Person.js* file is such an external file. 

**Webpack** is the package responsible for the handling of files. For example with the webpack-babel configuration, not only can we use the ES6+ syntax to `import` or `export` JavaScript files (Babel), we can also `import` CSS file(s), *Person/Person.js*  into a JavaScript file, *App.js* (Webpack).

Let's style the components below with CSS:

**App.js**
```jsx
import React from 'react';
import { useState } from 'react';
import Person from './Person/Person';

const App = () => {
  const [state, setState] = useState({
    persons: {
      name: 'Bello',
      language: 'React',
      id: '2sdr3'
    }
  });

  const personNameHandler = () => {
    setState({
      persons: {
        name: 'Andela',
        language: 'React',
        id: '2sdr3'
      }
    })
  };

  return (
    <div>
      <Person
        name={state.persons.name}
        language={state.persons.language}
        id={state.persons.id} />
      <button
        onClick={personNameHandler}>Change Person State</button>
    </div>
  );
};

export default App;
```

**Person/Person.js**
```jsx
import React from 'react';
import './Person.css';

const Person = props => {
    return (
        <div className="Person">
            <h3>Name: {props.name}</h3>
            <h3>Skill: {props.language}</h3>
            <h3>ID: {props.id}</h3>
        </div>
    );
};

export default Person;
```

### External-Internal CSS
CSS rules are globally scoped on components even when written in a separate or external file.

See the example below:

**Person/Person.css**
```css
.Person {
    margin: 20px auto;
    padding: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
    line-height: 1.7;
    width: 12.375rem;
    font-family: 'Roboto', sans-serif;
    background-color: white;
}
```

Let's import [Google Font](https://fonts.google.com/specimen/Roboto?sidebar.open=true&selection.family=Roboto:wght@300) into *index.css*.

**index.css**
```css
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap');

*, 
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    padding: 0;
    margin: 0;
}

body {
    background-color: #f0f0f0;
}
```

*You may wish to delete the App.css file*.

{% stackblitz react-pjqhyv %}

*Note*: When you inspect the imported CSS font `@import url('https://...');`, it's in a separate `<style>` element. This is done automatically by **webpack**.

Use shortcut key, `Ctrl` + `Shift` + `'` to open the developer tools. Inspect the Person component. Do you notice any **auto-prefix**? If **yes**, it means you are either using an older Chrome, Firefox, or Safari version browser (or any other browser that uses their engine). If **No**, it means your browser can do without the auto-prefix but renders the right styling on the element. This is possible because it's configured in your *package.json* or in any other file.

**package.json**
```json
"browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
```
<!-- In the future, this will change because `last 1 chrome version` means the last chrome browser will support auto-prefix for React 1.71. In future React -->

Also, since these CSS files are imported into the JavaScript file by the **webpack** management system, it's intuitive to expect that the stying is globally scoped. That is the CSS rules are injected in the `style` element.

In the `<head>` element look for the `<style>` elements. There are 4 style elements in the *index.html* file. That is, they all globally scoped in the *index.html*.

For example, the *Person/Person.css* CSS rules are injected in the `<style>` element of the *index.html* file.

**index.html**
```css
<style>
.Person {
    margin: 20px auto;
    padding: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
    line-height: 1.7;
    width: 12.375rem;
    font-family: 'Roboto', sans-serif;
}
</style>
```
*The sourceMappingURL data warning disappears because styling is applied to components or elements.*

### Inline CSS
If a React element needs styling, there's no need to write the rules in a separate file or globally. React elements can be styled inline but not in CSS format but JavaScript syntax.

In the example below the name, `styleButton` is an object. The property names of the object are written in camelCase when necessary. 

Let's style the button element:

**App.js**
```jsx
import React from 'react';
import { useState } from 'react';
import Person from './Person/Person';

const App = () => {
  const [state, setState] = useState({
    persons: {
      name: 'Bello',
      language: 'React',
      id: '2sdr3'
    }
  });

  const personNameHandler = () => {
    setState({
      persons: {
        name: 'Andela',
        language: 'React',
        id: '2sdr3'
      }
    })
  };

  const styleButton = {
    border: '1px solid black',
    borderRadius: '4px',
    backgroundColor: 'blueviolet',
    color: 'white',
    display: 'block',
    margin: '0 auto',
    padding: '10px',
    cursor: 'pointer'
  }

  return (
    <div>
      <Person
        name={state.persons.name}
        language={state.persons.language}
        id={state.persons.id} />
      <button
        style={styleButton}
        onClick={personNameHandler}>Change Person State</button>
    </div>
  );
};

export default App;
```

As you can see above, the style attribute, `style` is in-line with the `<button>` element - `style={styleButton}`.

{% stackblitz react-dpstym %}

An alternative syntax is shown below - `style={{...}}` syntax:

**App.js**
```jsx
import React from 'react';
import { useState } from 'react';
import Person from './Person/Person';

const App = () => {
  const [state, setState] = useState({
    persons: {
      name: 'Bello',
      language: 'React',
      id: '2sdr3'
    }
  });

  const personNameHandler = () => {
    setState({
      persons: {
        name: 'Andela',
        language: 'React',
        id: '2sdr3'
      }
    })
  };

  return (
    <div>
      <Person
        name={state.persons.name}
        language={state.persons.language}
        id={state.persons.id} />
      <button
        style={{
          border: '1px solid black',
          borderRadius: '4px',
          backgroundColor: 'blueviolet',
          color: 'white',
          display: 'block',
          margin: '0 auto',
          padding: '10px',
          cursor: 'pointer'
        }}
        onClick={personNameHandler}>Change Person State</button>
    </div>
  );
};

export default App;
``` 

### CSS Module
**CSS module** is an alternative way to add CSS to your app. It allows you to import your CSS module in a script file.

Let's center the body of the *App.js* component:

**body.module.css**

```css
body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

button {
    border: 1px solid #000;
    border-radius: 4px;
    background-color: blueviolet;
    color: white;
    display: block;
    margin: 0 auto;
    padding: 10px;
    cursor: pointer
}
```

*Note*: The CSS module allows JavaScript file to import the `.module.css` file for styling in a component or on an element. The syntax is `filename.module.css`. Where `.module.css` is the extension The added advantage is you do not have to worry about name conflicts.

**App.js**
```jsx
import React from 'react';
import { useState } from 'react';
import Person from './Person/Person';
import bodyStyles from './body.module.css';

const App = () => {
  const [state, setState] = useState({
    persons: {
      name: 'Bello',
      language: 'React',
      id: '2sdr3'
    }
  });

  const personNameHandler = () => {
    setState({
      persons: {
        name: 'Andela',
        language: 'React',
        id: '2sdr3'
      }
    })
  };

  return (
    <div className={bodyStyles}>
      <Person
        name={state.persons.name}
        language={state.persons.language}
        id={state.persons.id} />
      <button
        onClick={personNameHandler}>Change Person State</button>
    </div>
  );
};

export default App;
```

{% stackblitz react-pkff6j %}

You can be more specific by using the `.` notation to style a specific element. The `className={bodyStyles.button}` attribute is added to the `button` element.

```jsx
import React from 'react';
import { useState } from 'react';
import Person from './Person/Person';
import bodyStyles from './body.module.css';

const App = () => {
  const [state, setState] = useState({
    persons: {
      name: 'Bello',
      language: 'React',
      id: '2sdr3'
    }
  });

  const personNameHandler = () => {
    setState({
      persons: {
        name: 'Andela',
        language: 'React',
        id: '2sdr3'
      }
    })
  };

  return (
    <div className={bodyStyles.body}>
      <Person
        name={state.persons.name}
        language={state.persons.language}
        id={state.persons.id} />
      <button className={bodyStyles.button}
        onClick={personNameHandler}>Change Person State</button>
    </div>
  );
};

export default App;
```

**Happy Coding!!!**

<a href="https://www.buymeacoffee.com/bellotech" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>

{% user bello %}
#### Techstack | Fiverr
Techstack article, sponsored by Flutterwave.
- Connect to freelancers with proven business experience.
- Get matched with the perfect talent by a customer service manager.
- Freelance to get extra income or become a full-time freelancer.

[Sign up](http://www.fiverr.com/s2/fa85266916) to find the perfect freelance services for your business or become a freelancer.

{% youtube EkPDLVqKkLc %}

[Support](https://dashboard.flutterwave.com/donate/3lo9klliqwbu) what I do and push me to keep making free content.