Lekce 6. - React - CSS

17.03.2021 Programování #react #programování

Aplikace kaskádových stylů v technologii Reactu. Kompletní návod na používání CSS nebo SCSS.


I když existuje několik způsobů, jak pracovat s CSS, zde se budeme zabývat vloženými CSS, šablonami stylů CSS a moduly CSS.

Mezi další možnosti patří - CSS-in-JS (např. Stylizované komponenty, Emotion, JSS), Sass & SCSS, Less, Utility-First-CSS (např. Tailwind CSS).

Začneme šablonou stylů CSS

To je docela jednoduché. Nejedná se o nic nového, vychází se z pravidel aplikace CSS v HTML. Začněme tedy vytvořením nového souboru s názvem App.css ve složce src. Do tohoto souboru přidejte následující základní styly:

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Segoe UI", Arial, sans-serif;
  line-height: 1.4;
  color: #444;
  background: #fff;
  height: 100vh;
}

Uložte soubor.

Dále jej naimportujte do souboru index.js:

import React from "react"
import ReactDOM from "react-dom"
//component file
import TodoContainer from "./components/TodoContainer"

//stylesheet
import "./App.css"

ReactDOM.render(
  <React.StrictMode>
    <TodoContainer />
  </React.StrictMode>,
  document.getElementById("root")
)

Pokud chcete, můžete soubor importovat do souboru nadřazené komponenty, TodoContainer.js nikoli do souboru index.js. Uložte soubor.

Začněme přidávat názvy tříd.

V HTML přidáváme třídy CSS k prvkům pomocí atributu class. Ale v React JSX používáme speciální atribut className.

Otevřete TodoContainer.js a aktualizujte metodu render() tak, aby zahrnovala názvy tříd.

render() {
  return (
    <div className="container">
      <div className="inner">
        <Header />
        <InputTodo addTodoProps={this.addTodoItem} />
        <TodosList
          todos={this.state.todos}
          handleChangeProps={this.handleChange}
          deleteTodoProps={this.delTodo}
        />
      </div>
    </div>
  );
}

Poznámka: Přidali jsme další obal pomocí div do render().

Dále otevřete soubor InputTodo.js a aktualizovat elementy forminput button tak, aby zahrnovali názvy tříd.

<form onSubmit={this.handleSubmit} className="form-container">
  <input
    type="text"
    className="input-text"
    placeholder="Add todo..."
    value={this.state.title}
    name="title"
    onChange={this.onChange}
  />
  <button className="input-submit">Submit</button>
</form>

Poté aktualizujte soubor App.css tak, aby zahrnoval následující styly:

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  max-width: 600px;
  margin: 0 auto;
}

.inner {
  width: 100%;
  padding: 8rem 10px 4rem;
}

.form-container {
  width: 100%;
  margin-bottom: 20px;
  display: flex;
  border-radius: calc(0.5 * 100px);
  box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.38);
  justify-content: space-evenly;
}

.input-text {
  font-size: 1rem;
  font-weight: 400;
  width: 85%;
  padding-right: 5px;
  padding-left: 10px;
  border-radius: calc(0.5 * 100px);
}

.input-text::placeholder {
  color: #000;
}

.input-submit {
  background: transparent;
  color: #5b5b5b;
  text-transform: capitalize;
  cursor: pointer;
  font-weight: 600;
  margin-right: 10px;
}

.input-text,
.input-submit {
  height: 45px;
  outline: none;
  border: none;
}

Uložte si soubory a zkontrolujte rozhraní.

Inline styling

Podobně jako v klasickém HTML lze přidávat styly pomocí atributu style. V React JSX, ale atribut přiřadíme JavaScript objektu.

Přejděte do souboru Header.js a aktualizujte prvek záhlaví tak, aby obsahoval atribut style.

return (
  <header>
    <h1
      style={{
        fontSize: "6rem",
        fontWeight: "600",
        marginBottom: "2rem",
        lineHeight: "1em",
        color: "#ececec",
        textTransform: "lowercase",
        textAlign: "center",
      }}
    >
      todos
    </h1>
  </header>
)

Uložte soubor a zkontrolujte frontend.

V kódu si všimněte dvou složených závorek. Již víme, že platné výrazy JavaScriptu v JSX jsou psány uvnitř složených závorek. Druhá složená závorka je pro vložený styling ve formě objektu JavaScriptu.

Všimněte si také, že stylové klávesy jsou v camelCase.

Dalším způsobem, jak použít inline styl v React, je použití proměnných. Stále v souboru Header.js přidejte nad příkaz return následující kód :

const headerStyle = {
  padding: "20px 0",
  lineHeight: "1.5em",
}

Poté aktualizujte element < header >, abyste měli:

<header style={headerStyle}>

Uložte soubor. Váš kód by teď měl vypadat takto:

import React from "react"

const Header = () => {
  const headerStyle = {
    padding: "20px 0",
    lineHeight: "1.5em",
  }

  return (
    <header style={headerStyle}>
      <h1
        style={{
          fontSize: "6rem",
          fontWeight: "600",
          marginBottom: "2rem",
          lineHeight: "1em",
          color: "#ececec",
          textTransform: "lowercase",
          textAlign: "center",
        }}
      >
        todos
      </h1>
    </header>
  )
}

export default Header

Zkontrolujte frontend, nebo zkontrolujte element header, abyste viděli deklaraci stylu CSS. V kódu jsme vytvořili objekt headerStyle s informacemi o stylingu a poté na něj odkazovali v atributu style elementu.

Aplikace Styling React s moduly CSS

Někdy bychom chtěli omezit přístup k šabloně stylů CSS tak, aby uchovával vaše globální styly a lokálně určoval rozsah vašich komponentních stylů.

CSS Modules nám to umožňují. Eliminuje se riziko konfliktů názvů spojených se selektorem CSS nebo některými dalšími problémy souvisejícími se stylem globálního rozsahu.

Například pokud pro komponentu TodoItem přidáte modul CSS, použité styly budou vymezeny pouze na tuto komponentu. Tímto způsobem můžete použít stejné názvy tříd v různých součástech bez obav z konfliktů s CSS.

Podívejme se, jak to funguje.

Chcete-li komponentu TodoItem upravit, přejděte do adresáře src/components a vytvořte soubor s názvem TodoItem.module.css. Potom přidejte následující styly:

.item {
  font-size: 1.2rem;
  list-style-type: none;
  padding: 17px 0px;
  border-bottom: 1px solid #eaeaea;
}

.checkbox {
  margin-right: 15px;
}

.item button {
  font-size: 13px;
  background: #f1f3f4;
  border: none;
  cursor: pointer;
  float: right;
  outline: none;
  border-radius: 100px;
  height: 50px;
  width: 50px;
  margin: -10px 0 0 10px;
}

Poté přejděte dovnitř souboru TodoItem.js a importujte soubor .css takto:

import styles from "./TodoItem.module.css"

Poté aktualizujte označení v příkazu return tak, aby zahrnovalo názvy tříd:

return (
  <li className={styles.item}>
    <input
      type="checkbox"
      className={styles.checkbox}
      checked={this.props.todo.completed}
      onChange={() => this.props.handleChangeProps(this.props.todo.id)}
    />
    <button onClick={() => this.props.deleteTodoProps(this.props.todo.id)}>
      Delete
    </button>
    {this.props.todo.title}
  </li>
)

Uložte si soubory a zkontrolujte rozhraní.

Co jsme tedy udělali?

Nejprve řekneme Reactu, aby zpracoval soubor CSS jako modul CSS připojením k souboru .module.css. Tento modul je poté importován do souboru TodoItem.js a deklarován jako objekt JavaScriptu s názvem styles.

Tento objekt obsahuje veškeré selektory třídy v souboru .css a odkazujeme  na ně v atributu JSX className pomocí styles.classSelector (například styles.checkbox).

Poznámka:

Objekt styles můžete pojmenovat, jak chcete. Všimněte si také, jak je pojmenovaná třída s více než jedním slovem (např. .new-class). K tomu se doporučuje použít camelCase (tj. .newClass). Ale pokud dáváte přednost pomlčce ve názvu tříd, měli byste použít notaci závorky (například styles['new-class']) souboru .js.

Nyní, pokud si prohlédnete seznam úkolů v nástrojích pro vývojáře prohlížeče, uvidíte, že modul CSS generuje jedinečné názvy tříd. Díky tomu se nemusíte starat o konflikty názvů selektorů.

Pokud bychom chtěli použít Sass k sestavení .scss souboru do běžného CSS. Vše, co se musí udělat, je nainstalovat node-sass:

npm install node-sass

To je vše.

Pokud chcete, můžete použít moduly CSS se Sass. Stačí změnit příponu souboru .css na .scss. A aktualizujte import v souboru TodoItem.js tak, aby měl odpovídající příponu.

Přidání stylů, když je některá z položek úkolů dokončena

Zde přidáme line-through k dokončenému úkolu v seznamu úkolů. To by mělo být přeškrtnuté písmo. V komponentě TodoItem přidejte do metody render() následující styly, ale nad příkaz return:

const completedStyle = {
  fontStyle: "italic",
  color: "#595959",
  opacity: 0.4,
  textDecoration: "line-through",
}

Poté aktualizujte return, abyste měli:

return (
  <li className={styles.item}>
    <input
      type="checkbox"
      className={styles.checkbox}
      checked={this.props.todo.completed}
      onChange={() => this.props.handleChangeProps(this.props.todo.id)}
    />
    <button onClick={() => this.props.deleteTodoProps(this.props.todo.id)}>
      Delete
    </button>
    <span style={this.props.todo.completed ? completedStyle : null}>
      {this.props.todo.title}
    </span>
  </li>
)

Do kódu jsme zavedli novou značku span a poté do ní přidali atribut style. Použili jsme také ternární operátor v atributu style k dynamické změně stylu CSS, pokud je některá z položek todos dokončena.

Zde použitý ternární operátor (nebo vložený příkaz if) zkontroluje, zda je některá položka v seznamu úkolů dokončena či nikoli.

Funguje to takto:

(condition) ? (true return value) : (false return value)

tj. pokud je podmínka true (v našem případě, pokud je úkol označen jako splněný), použijeme druhý příkaz completedStyle (tuto proměnnou jsme vytvořili jako objekt obsahující informace o stylu ve stejné komponentě), jinak použijeme null (tj. bez stylu).

Uložte soubor a zkontrolujte rozhraní.

Optimalizace pomocí destrukturalizace

Pokud jste se podíváte na komponentu TodoItem, tak vidíme, že k hodnotám stavu pole todos používáme zápis this.props.todo.id, stejně tak title completed. Pokud se vaše aplikace stane složitou, může se jednat zbytečně složitý zápis.

Místo toho můžete z objektu vytáhnout každou z proměnných todoChcete-li zničit idod this.props.todo.id, budete mít něco takového:

const { id } = this.props.todo

Totéž platí pro title completed.

Aplikujme to v komponentě TodoItem. Přidejte tento řádek kódu těsně nad return:

const { completed, id, title } = this.props.todo

Poté nahraďte všechny this.props.todo jejich odpovídajícími proměnnými. Například this.props.todo.completed by měl být nahrazen completed atd. Obsah return by mělo vypadat takto:

return (
  <li className={styles.item}>
    <input
      type="checkbox"
      className={styles.checkbox}
      checked={completed}
      onChange={() => this.props.handleChangeProps(id)}
    />
    <button onClick={() => this.props.deleteTodoProps(id)}>Delete</button>
    <span style={completed ? completedStyle : null}>{title}</span>
  </li>
)

Používání Bootstrapu s React

Co je Bootstrap?

  • Bootstrap je bezplatný front-end framework pro rychlejší a snadnější vývoj webu (rapidní prototypování).
  • Bootstrap obsahuje návrhové šablony založené na HTML a CSS pro typografii, formuláře, tlačítka, tabulky, navigaci, modální okna, obrazové kolotoče a mnoho dalších, stejně jako volitelné doplňky JavaScriptu.
  • Bootstrap vám také dává možnost snadno vytvářet responzivní návrhy stránek.

Laicky řečeno:

Bootstrap je obrovská sbírka užitečných, opakovaně použitelných fragmentů kódu napsaných v HTML, CSS a JavaScriptu. Je to také front-endový framework, který umožňuje vývojářům a návrhářům rychle vytvářet plně interaktivní webové stránky.

Bootstrap ušetří psaní spousty kódů CSS, což vám poskytne více času na navrh webových stránek.

Přidání bootstrapu do Reactu

Tři nejběžnější způsoby přidání Bootstrap do aplikace React jsou:

  1. Použijte BootstrapCDN.
  2. Importujte Bootstrap v React jako závislost.
  3. Nainstalujte balíček React Bootstrap (například nebo) bootstrap-reactreactstrap

1. Používání BootstrapCDN

BootstrapCDN je nejjednodušší způsob, jak přidat Bootstrap do vaší aplikace React. Nejsou nutné žádné instalace ani stahování. Jednoduše vložte  < link > do < head > části vaší aplikace, jak ukazuje následující.

<link rel = "stylesheet" href = "https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">

Máte-li zájem o použití komponent JavaScript, které se dodávají s Bootstrap, je třeba umístit následující značky < script > na konec vašich stránek, těsně před koncovou značku < /body >.

<script src = "https://code.jquery.com/jquery-3.3.1.slim.min.js" > </script>  

<script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" > </script>  

<script src = "https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" > </ script>  

Jak vidíte, Bootstrap 4 vyžaduje pro své komponenty JavaScriptu jQuery a Popper.js. Ve výše uvedeném fragmentu jsme použili štíhlou verzi jQuery, i když můžete použít i plnou verzi.

U vaší aplikace React budou tyto fragmenty kódu obvykle přidány na indexovou stránku vaší aplikace. 

2. Importujte Bootstrap jako závislost

Pokud používáte nástroj CLI pro instalaci aplikace Reactu, pak se jedná o upřednostňovanou možnost pro přidání Bootstrap do vaší aplikace. Budete muset nainstalovat Bootstrap jako závislost pro vaši aplikaci.

npm install bootstrap

Jakmile budete mít Bootstrap nainstalován, pokračujte a importujte jej do vstupního souboru JavaScriptu vaší aplikace. Měl by to být váš soubor umístěný v src/index.js

import 'bootstrap/dist/css/bootstrap.min.css';

Všimněte si, že jsme jako první závislost importovali Bootstrap minified CSS. S tímto můžeme pokračovat pomocí integrovaných tříd Bootstrap v našich komponentách aplikace React. Než však budete moci ve své aplikaci použít komponenty JavaScriptu Bootstrap, budete si muset nainstalovat jquery a popper.js

npm install jquery popper.js

Dále provedete další změny v souboru src/index.js a přidáte nové závislosti, jak je znázorněno v následujícím fragmentu.

import $ from 'jquery';
import Popper from 'popper.js';
import 'bootstrap/dist/js/bootstrap.bundle.min';

Zde jsme přidali import pro $Popper. Také jsme importovali soubor Bootstrap JavaScript minified bundle. Nyní můžete ve své aplikaci React používat komponenty JavaScriptu Bootstrap.

3. Nainstalujte balíček React Bootstrap

Třetím způsobem, jak přidat Bootstrap do aplikace React, je jako balíček, který přestavěl komponenty Bootstrap tak, aby fungovaly jako komponenty React. Dva nejoblíbenější balíčky jsou:

  1. react-bootstrap
  2. reactstrap

Oba balíčky jsou skvělou volbou pro použití Bootstrapu s aplikacemi React, i když od vás není nutně vyžadováno, abyste některý z nich používali. Sdílejí velmi podobné vlastnosti.

Používání integrovaných tříd a komponent Bootstrap

Bootstrap můžete použít přímo na prvky a komponenty ve vaší aplikaci React použitím vestavěných tříd stejně jako u jakékoli jiné třídy. Postavme jednoduchý přepínač motivů React, který předvede použití tříd a komponent Bootstrap.

Ukážeme si jednoduchý příklad, jak pracovat s balíčkem react-bootstrap. Příklad bude novou aplikací, vytvořenou pomocí nástroje CLI.

Příklad - Choose Theme

V příkazovém řádku se přesuňte do adresáře, kam budete chtít aplikaci nainstalovat. Následně zadejte příkaz:

npx create-react-app react-bootstrap-app  

Dojde k instalaci základní struktury aplikace.

Po vytvoření aplikace React, přejděte do složky aplikace, tj. react-bootstrap-app a spusťte následující příkaz:

npm install react-bootstrap bootstrap

V souboru index.js vše vymažeme a přidáme import kaskádových stylů bootstrapu.

import 'bootstrap/dist/css/bootstrap.min.css';

Ve složce src vytvořte nový soubor pod názvem ThemeSwitcher.js a přidejte do něj následující zdrojový kód:

import { useState } from "react";
import { Button, ButtonGroup, Dropdown } from "react-bootstrap";

const ThemeSwitcher = () => {
  const [theme, setTheme] = useState(null);

  const resetTheme = () => {
    setTheme(null);
  };

  return (
    <div className="mb-2">
     <h1 className={`h1 text-${theme ? theme : 'muted'}`}>SWITCHER</h1>
      <Dropdown as={ButtonGroup} size="lg">
        <Button
          className="text-capitalize"
          variant={theme ? theme : "secondary"}
        >
          {theme ? theme : "Default"}
        </Button>
        <Dropdown.Toggle
          split
          variant={theme ? theme : "secondary"}
          id="dropdown-split-basic"
        />
        <Dropdown.Menu>
          <Dropdown.Item eventKey="1" onClick={() => setTheme("primary")}>
            Primary
          </Dropdown.Item>
          <Dropdown.Item eventKey="2" onClick={() => setTheme("danger")}>
            Danger
          </Dropdown.Item>
          <Dropdown.Item eventKey="3" onClick={() => setTheme("success")}>
            Success
          </Dropdown.Item>
          <Dropdown.Divider />
          <Dropdown.Item eventKey="4" onClick={resetTheme}>
            Default Theme
          </Dropdown.Item>
        </Dropdown.Menu>
      </Dropdown>
    </div>
  );
};

export default ThemeSwitcher;

Všimněte si jak se importuje knihovna react-bootstrap. Import této knihovny, můžeme omezit na používané komponenty.

Následně inovujte souboru index.js.

import 'bootstrap/dist/css/bootstrap.min.css'; 
import React from 'react'; 
import ReactDOM from 'react-dom'; 
//import './App.scss'; 
import ThemeSwitcher from './ThemeSwitcher';

ReactDOM.render(
  <div className="App min-vh-100 d-flex justify-content-center align-items-center">
  <div>
    <ThemeSwitcher />
  </div>
</div>, 
document.getElementById('root'));

 

Aplikace by měla vypadat následovně:

switcher

Výběrem z menu se mění styl podle CSS knihovny Bootstrap.

Dokumentace ke knihovně react-bootstrap je na adrese https://react-bootstrap.github.io/