Porównanie metod stylizacji w Next.js

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ Next.js nazwał się między innymi: The React Framework for Static Websites . Ale tak jak w przypadku każdego innego frameworka, którego celem jest pomoc w budowaniu tego, co ważne, poprzez wyabstrahowanie typowych, zbędnych zadań, często musisz nauczyć się czegoś nowego i opiniotwórczego. W przypadku Next.js jedną z rzeczy, które musisz wiedzieć, jest integracja różnych metod CSS z jego interfejsem API i to jest główny temat tego samouczka.

Jak być może wiesz, istnieje wiele różnych punktów widzenia na CSS-in-JS i wszyscy mamy opinię na ten temat w taki czy inny sposób, która może być zupełnie inna od opinii autorów frameworka.

Next.js jest jednym z zalecanych łańcuchów narzędzi podczas tworzenia nowej aplikacji React. Narzędzia takie jak Next mają prosty cel, jakim jest oddzielenie często zbędnych zadań podczas pisania aplikacji React. Pomaga to programistom bardziej skoncentrować się na pisaniu kodu niż na odkrywaniu koła na nowo. Chociaż zwykle jest to dobra rzecz, rozpoczęcie pracy może być również trochę nużące. Po pierwsze, istnieje przeszkoda do pokonania, poznając abstrakcje, i chociaż jest ich mnóstwo w sekcji Next (Routing, Data Fetching…), często pomijaną jest stylizacja.

Aby służyć szerszej publiczności, Next.js obsługuje niezliczone sposoby stylizowania komponentów. Niezależnie od tego, czy należysz najpierw do Utility, czy do CSS-in-JS, Next nie przejmuje się zbytnio tym, jak wprowadzasz swój wybór do interfejsu API.

Celem tego artykułu jest pomoc w zrozumieniu, jak skonfigurować styl w aplikacji Next. Do porównania będziemy używać różnych metod. Zaimplementujemy różne rodzaje stylizacji w skonfigurowanej przeze mnie aplikacji książkowej. Metody stylizacji, którym będziemy się przyglądać, obejmują:

  1. Globalny CSS,
  2. SASS/SCSS,
  3. SASS/SCSS na poziomie komponentów,
  4. CSS na poziomie komponentów (moduły CSS),
  5. Styled-Components,
  6. Stylizowany JSX,
  7. Emocja.

Warunek wstępny

Zanim zaczniemy naszą trasę stylizacyjną, jest kilka niuansów Next, z którymi musisz się zapoznać.

  1. _app.js
    Jest to niestandardowy komponent, który znajduje się w folderze stron. Next.js używa tego komponentu do inicjowania stron.
  2. _document.js
    Podobnie jak _app.js , _document.js jest niestandardowym komponentem, którego Next.js używa do rozszerzania tagów <html> i <body> aplikacji. Jest to konieczne, ponieważ strony Next.js pomijają definicję znaczników otaczającego dokumentu.
  3. _.babelrc
    Kiedy jest obecny, Next.js używa tego pliku jako jedynego źródła prawdy dla niektórych wewnętrznych konfiguracji i daje ci pozwolenie na jego rozszerzenie.

Pamiętaj, że jeśli masz uruchomiony serwer przed dodaniem pliku _app.js , musisz go ponownie uruchomić.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Tworzenie następnej aplikacji za pomocą create-next-app

Tworzenie następnej aplikacji za pomocą funkcji create-next-app jest tak proste, jak wykonanie poniższych kroków:

  • Zainstaluj globalnie create-next-app .
 yarn global add create-next-app // Installs create-next-app globally
  • Utwórz nową aplikację Next o nazwie styling-in-next .
 create-next-app styling-in-next // Creates a new Next app named styling-in-next
  • Zmień katalog na nową witrynę.
 cd styling-in-next // Switch directory into the new Next app
  • Uruchom witrynę.
 yarn dev -p 3000 // Instruct Next to run on port 3000

Zapoznaj się z dokumentacją, aby uzyskać więcej informacji na temat tworzenia i uruchamiania aplikacji Next.

Aplikacja powinna teraz działać na https://localhost:3000 .

Zrzut ekranu domyślnej strony indeksu startera Next.js
Domyślna strona indeksu startera Next.js. (duży podgląd)

Repozytorium demonstracyjne

Idąc dalej, będziemy budować wymyślną półkę na książki , stosując różne metody stylizacji do każdej książki . Efekt końcowy będzie wyglądał następująco:

Zrzut ekranu ostatniej półki na książki w stylu demo
Regał w stylu końcowym. (duży podgląd)

Powyższy obrazek przedstawia 6 książek; każda księga będzie miała swoje własne komponenty, a następnie zastosujemy określony typ stylu do każdej konkretnej księgi, tj. Księga 1 użyje stylu globalnego, podczas gdy Księga 2 użyje innego. W ten sposób zobaczymy, jak działa każdy z tych stylów i jak można ich używać. Pomoże Ci to w podjęciu lepszej decyzji, jaką opcję wybrać.

Aby uprościć sprawę, przygotowałem repozytorium GitHub, które możesz śledzić. Możesz go pobrać tutaj.

Wprowadzono również pewne zmiany w domyślnym starterze generowanym przez create-next-app . Foldery takie jak emotion , global , modules , styled-components itp. zostały dodane do folderu styles — wraz z odpowiadającymi im plikami stylów — a także do katalogu components z wieloma komponentami.

Zrzut ekranu z początkowymi zmianami wprowadzonymi w stylach repozytorium demonstracyjnego i katalogu komponentów
Zmiany w folderach stylów i komponentów. (duży podgląd)

Plik index.js został zmodyfikowany w celu import i render potrzebnych components , a każdy z komponentów ma podobną strukturę, jak pokazano na poniższym obrazku.

Zrzut ekranu z początkowymi zmianami wprowadzonymi w BookTwo.js, BookOne.js i index.js
Zmiany w poszczególnych komponentach i plikach indeksu. (duży podgląd)

Jeśli sklonowałeś i uruchomiłeś repozytorium demo, oto jak powinna wyglądać Twoja strona:

Zrzut ekranu domyślnej strony indeksu z repozytorium demo
Domyślna strona indeksu z repozytorium demonstracyjnego. (duży podgląd)

Pomijając to wszystko, przejdźmy do stylizacji.

Globalny styl

Jedną z typowych rzeczy, które zwykle robisz, rozpoczynając nowy projekt internetowy, jest zresetowanie lub normalizacja CSS, aby zapewnić jednolitą pozycję początkową wśród przeglądarek. To doskonały przykład korzystania z globalnego CSS bez martwienia się o zakres.

  • Zaktualizuj styles/global/globals.css za pomocą tego rozszerzonego minimalnego resetowania CSS.
 /* styles/global/globals.css */ html { box-sizing: border-box; font-size: 16px; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; } *, *:before, *:after { box-sizing: inherit; } body, h1, h2, h3, h4, h5, h6, p, ol, ul { margin: 0; padding: 0; font-weight: normal; } h1, h2, h3, h4, h5, h6 { font-weight: bold; } ol, ul { list-style: none; } img { max-width: 100%; height: auto; } a { color: inherit; text-decoration: none; }
  • Zaimportuj styles/global/globals.css w pages/_app.js .
 // pages/_app.js import "../styles/global/globals.css"; function MyApp({Component, pageProps}) { return <Component {...pageProps} />; } export default MyApp;

Style globalne można importować tylko w pages/_app.js . Jest to wprost logiczne, ponieważ te style będą miały zastosowanie do wszystkich pages i components w Twojej aplikacji — niezależnie od tego, gdzie je zaimportujesz — więc lepiej jest mieć jedno źródło prawdy [importu], aby wszystko było proste i/lub jeśli coś pójdzie zło.

W tym momencie nie wprowadziliśmy wielu zmian wizualnych na naszej półce z książkami, ponieważ wprowadziliśmy tylko zmiany normalizacyjne . Jedną z rzeczy, które możesz zauważyć, są zmiany czcionki i odstępów.

Zrzut ekranu przedstawiający zmianę w demo Bookshelf po dodaniu resetu CSS
Zmiany na stronie indeksu po dodaniu resetu CSS. (duży podgląd)

SASS/SCSS

Next.js umożliwia również stylizację za pomocą SASS z rozszerzeniem .sass lub .scss . Instalacja Sassa jest wymagana. Podobnie jak style globalne, można je importować tylko w pages/_app.js .

  • Zainstaluj pakiet Sass.
 yarn add sass
  • Zaktualizuj styles/scss/bookshelf.scss .
 // styles/scss/bookshelf.scss .the-bookshelf { width: 100vw; height: 100vh; background-color: #e3e3e3; display: flex; justify-content: center; align-items: center; .bookshelf-wrap { > .bookshelf { box-shadow: inset 0 -20px #7b5019; padding-bottom: 20px; display: flex; align-items: flex-end; } [class*="book"] { font-size: 32px; letter-spacing: -0.045em; display: flex; transition: 0.2s; &:hover { transform: none; } } .book-info { text-transform: uppercase; writing-mode: sideways-rl; display: flex; justify-content: space-around; flex: 1; align-items: center; font-weight: bold; padding: 16px 0; .title { font-weight: inherit; font-size: 20px; } .author { font-weight: inherit; font-size: 15px; } } } }
  • Zaktualizuj także styles/sass/bookone.sass i styles/sass/booktwo.sass sposób:
 // styles/sass/bookone.sass .book-one color: #f00 width: 78px height: 350px transform: rotate(-4deg) margin-left: 16px margin-right: 23px background-color: black
 // styles/sass/booktwo.sass .book-two color: #781e0b width: 38px height: 448px margin-right: 23px background-color: #ffab44

SASS ( .sass ) opiera się na wcięciach. Aby ułatwić formatowanie, możesz zainstalować rozszerzenie VSCode do obsługi plików SASS (formatowanie, podświetlanie składni…)

  • Zaimportuj trzy pliki stylów — styles/scss/bookshelf.scss , styles/sass/bookone.sass i styles/sass/booktwo.sass — w pages/_app.js .
 // pages/_app.js import "../styles/globals.css"; import "../styles/scss/bookshelf.scss"; import "../styles/sass/bookone.sass"; import "../styles/sass/booktwo.sass"; function MyApp({Component, pageProps}) { return ; } export default MyApp; // pages/_app.js import "../styles/globals.css"; import "../styles/scss/bookshelf.scss"; import "../styles/sass/bookone.sass"; import "../styles/sass/booktwo.sass"; function MyApp({Component, pageProps}) { return ; } export default MyApp;

Nasza biblioteczka zaczyna nabierać kształtu. Po zastosowaniu stylów pierwsza i druga książka powinny być stylizowane i wyświetlane zgodnie z przeznaczeniem.

Zrzut ekranu zmiany w demo Bookshelf po stylizacji pierwszej i drugiej książki za pomocą SASS
BookOne i BookTwo stylizowane na SASS. (duży podgląd)

Moduły CSS

Moduły CSS to CSS na poziomie komponentów, który jest wbudowany w Next i można go aktywować, nazywając pliki stylów rozszerzeniem .module.css . Możliwe jest również użycie modułów CSS z SASS/SCSS z rozszerzeniem .module.sass lub .module.scss .

Stylizujmy za jego pomocą składnik components/BookThree.js .

  • Zaktualizuj styles/modules/BookThree.module.css .
 /* styles/modules/BookThree.module.css */ .book-three { color: #df66c3; width: 106px; height: 448px; margin-right: 23px; background-color: #153086; transform: rotate(-4deg); }
  • Zaimportuj styles/modules/BookThree.module.css w components/BookThree.js i zastosuj klasę .book-three .
 // components/BookThree.js import BookThreeStyles from "../styles/modules/BookThree.module.css"; export default function BookThree() { return ( <div className={BookThreeStyles["book-three"]}> <div className="book-info"> <p className="title">the revolt of the public</p> <p className="author">Martin Gurri</p> </div> </div> ); }

Uzyskiwanie dostępu do nazw klas w modułach CSS jest podobne do akcesorów właściwości w JavaScript — za pomocą notacji z kropką lub nawiasem kwadratowym. Tutaj importujemy BookThreeStyles , a następnie używamy notacji nawiasów, aby zastosować styl, który mamy w pliku styles/modules/BookThree.module.css .

Jeśli selektor (w tym przypadku nazwa klasy) był prawidłowo dostępny, należy teraz nadać styl trzeciej księdze.

Zrzut ekranu przedstawiający zmianę w demo Bookshelf po stylizacji trzeciej książki za pomocą modułów CSS
BookThree stylizowany za pomocą modułów CSS. (duży podgląd)

Emocja

Emotion to biblioteka CSS w JS i jak każdy inny CSS w JS, pozwala pisać style CSS za pomocą JavaScript.

Stylizujmy za jego pomocą składnik components/BookFour.js .

  • Zainstaluj pakiety: @emotion/core , @emotion/styled , emotion , emotion-server .
 yarn add @emotion/core @emotion/styled emotion emotion-server
  • Zaktualizuj styles/emotion/StyledBookFour.js .
 // styles/emotion/StyledBookFour.js import styled from "@emotion/styled"; export const StyledBookFour = styled.div` color: white; width: 38px; height: 400px; margin-left: 20px; margin-right: 10px; background-color: #2faad2; transform: rotate(4deg); `;

Po zaimportowaniu styled z @emotion/styled eksportujemy składnik StyledBookFour — nie mylić z innym składnikiem styled CSS-in-JS — wzbogacony o metodę styled emotion, jak w styled.div . Następnie możemy użyć <StyledBookFour/> jak w następnym kroku poniżej.

Dowiedz się więcej o stylizowanej funkcji emocji.

  • Używanie <StyledBookFour/> jest podobne do używania innych komponentów React. Zaimportuj styles/emotion/StyledBookFour.js w components/BookFour.js i zastosuj składnik StyledBookFour .
 // components/BookFour.js import {StyledBookFour} from "../styles/emotion/StyledBookFour"; export default function BookFour() { return ( <StyledBookFour className="book-four"> <div className="book-info"> <p className="title">the man died</p> <p className="author">wole soyinka</p> </div> </StyledBookFour> ); }

Z odpowiednią dawką emocji należy w ten sposób wystylizować czwartą książkę.

Zrzut ekranu przedstawiający zmianę w demo Bookshelf po stylizacji czwartej książki za pomocą Emotion
BookFour stylizowany na emocje. (duży podgląd)

Stylizowany JSX

Podobnie jak Global CSS i CSS-Modules, Styled-JSX współpracuje z Next.js bez dodatkowej konfiguracji. Jeśli to pomaga, Styled-JSX jest również ofertą Vercela opartego na komponentach CSS, tych samych twórców Next.js.

Stylizujmy za jego pomocą składnik components/BookFive.js .

Aby uprościć sprawę, używamy tutaj wewnętrznego trybu styled-jsx. Przekazując właściwość jsx do komponentu <style/> , jesteśmy w stanie napisać tyle CSS, ile chcemy, tak jak zrobiliśmy to w przypadku .book-five , z dodatkową korzyścią polegającą na lokalizacji stylu w komponencie <BookFive/> .

 // components/BookFive.js export default function BookFive() { return ( <div className="book-five"> <div className="book-info"> <p className="title">there was a country</p> <p className="author">Chinua Achebe</p> </div> <style jsx>{` .book-five { color: #fff; width: 106px; height: 448px; margin-right: 23px; background-color: #000; transform: rotate(4deg); } `}</style> </div> ); }

I tak po prostu, piąta książka nabiera swojej stylizacji.

Zrzut ekranu zmiany w demo Bookshelf po stylizacji piątej książki za pomocą Styled JSX
BookFive w stylu Styled JSX. (duży podgląd)

Stylizowane komponenty

Styled-Component, podobnie jak Emotion, jest również biblioteką CSS-in-JS, która umożliwia pisanie stylów CSS za pomocą JavaScript. Konfiguracja jest trochę skomplikowana.

  • Najpierw zainstaluj babel-plugin-styled-components i styled-components .
 yarn add babel-plugin-styled-components styled-components
  • Utwórz plik .babelrc w katalogu głównym aplikacji oraz plik pages/_document.js , jak pokazano na obrazku przed (po lewej) i po (po prawej) poniżej.
Zrzut ekranu przedstawiający zmianę w demo Regał po dodaniu dwóch nowych plików - <code>_.document.js</code> i <code>.babelrc</code>
Dodano nowe pliki: _document.js i .babelrc . (duży podgląd)
  • Zaktualizuj plik .babelrc , aby zawierał ustawienia next/babel i zawierał wtyczkę styled-components z włączonym renderowaniem po stronie serwera (ssr).
 // .babelrc { "presets": ["next/babel"], "plugins": [ [ "styled-components", { "ssr": true } ] ] }
  • Zaktualizuj pages/_document.js , wstrzykując style renderowane po stronie serwera do <head> .

Pamiętaj, że poniższy fragment ( pages/_document.js ) jest wymaganą logiką, aby styled-components działały z Next.js. Niemal nie musisz nic robić, tylko kopiować logikę, jak wskazano w dokumentacji styled-components.

 // pages/_document.js import Document from "next/document"; import {ServerStyleSheet} from "styled-components"; export default class MyDocument extends Document { static async getInitialProps(ctx) { const sheet = new ServerStyleSheet(); const originalRenderPage = ctx.renderPage; try { ctx.renderPage = () => originalRenderPage({ enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />), }); const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> {initialProps.styles} {sheet.getStyleElement()} </> ), }; } finally { sheet.seal(); } } }

Po aktualizacji .babelrc i pages/_document.js możemy teraz zacząć używać styled-components.

  • Zaktualizuj styles/styled-components/StyledBookSix.js .

styled to wewnętrzna metoda narzędziowa, która przekształca stylizację z JavaScript na rzeczywisty CSS. <StyledBookSix/> jest i może być używany jako dowolny inny komponent React.

 // styles/StyledBookSix.js import styled from "styled-components"; const StyledBookSix = styled.div` color: #fff; width: 106px; height: 448px; margin-right: 23px; background-color: rebeccapurple; `; export default StyledBookSix;

Dowiedz się więcej o tym, jak używać Styled-Components w React.

  • Importuj styles/styled-components/StyledBookSix.js w components/BookSix.js , używając zaimportowanych styled-components <StyledBookSix/> .
 // components/BookSix.js import StyledBookSix from "../styles/styled-components/StyledBookSix"; export default function BookSix() { return ( <StyledBookSix className="book-six"> <div className="book-info"> <p className="title">purple hibiscus</p> <p className="author">chimamanda ngozi adichie</p> </div> </StyledBookSix> ); }

Po ukończeniu pierwszego do szóstego kroku, szósty powinien być wystylizowany, a regał z książkami gotowy:

Zrzut ekranu przedstawiający zmianę w demo Bookshelf po stylizacji szóstej książki za pomocą Styled Components
BookSix stylizowany za pomocą Styled Components. (duży podgląd)

Otóż ​​to.

Jeśli wszystko poszło dobrze, powinieneś mieć kompletną półkę z książkami czekającymi na przeczytanie.

  • Możesz pobrać cały kod na GitHub →

Wniosek

W moim własnym użyciu z Next.js, style globalne i styled-components były często wystarczające. Ale nie ma wątpliwości, że wszystkie te metody mają swoje plusy i minusy. A kiedy ustalisz, jakiej metody użyć, pamiętaj: w końcu to wszystko CSS. W tym momencie wierzę, że możesz dowiedzieć się, który wzór najlepiej służy ci w następnym projekcie.

Zasoby

Uważam, że nie ma lepszego miejsca do nauki konfigurowania metod stylizacji za pomocą Next.js niż jego oficjalna dokumentacja.

Ale są też specjalne repozytoria dla różnych metod stylizacji. Możesz przejrzeć różne repozytorium, aby dowiedzieć się więcej, lub sprawdzić aktualizacje, ponieważ rzeczy mogą się zmienić w trybie incognito.

  1. CSS Tailwind
  2. Moduły CSS
  3. Mniej
  4. Rysik
  5. CSS Tailwind z emocjami
  6. Styletron
  7. Przepych
  8. CXS
  9. Afrodyta
  10. Fela
  11. Styled-JSX