Mô-đun CSS Nextjs

Xuất thân từ Khu vực Vịnh San Francisco, Alexander Dubovoy là một lập trình viên và nhạc sĩ có trụ sở tại Berlin. Anh ấy tốt nghiệp Đại học Yale vào tháng 5 năm 2016, nơi anh ấy … Thông tin thêm về Alexander ↬

Bản tin email

Email (đập vỡ) của bạn

Mẹo hàng tuần về front-end & UX
Được hơn 200.000 người tin cậy

  • Mô-đun CSS Nextjs
    Giao diện người dùng SmashingConf 2023

  • Mô-đun CSS Nextjs
    Các mẫu thiết kế giao diện Đào tạo UX

  • Mô-đun CSS Nextjs
    Chuẩn bị cho các vai trò giao tiếp ngày nay Thạc sĩ Thiết kế Thông tin của Northwestern

  • Mô-đun CSS Nextjs
    Quảng cáo trên tạp chí Smashing

  • Mô-đun CSS Nextjs
    SmashingConf Freiburg 2023

Kế tiếp. js có ý kiến ​​mạnh mẽ về cách tổ chức JavaScript chứ không phải CSS. Làm cách nào chúng ta có thể phát triển các mẫu khuyến khích các phương pháp CSS tốt nhất đồng thời tuân theo logic của khung?

Tôi đã có trải nghiệm tuyệt vời khi sử dụng Next. js để quản lý các dự án front-end phức tạp. Kế tiếp. js có quan điểm về cách tổ chức mã JavaScript, nhưng nó không có ý kiến ​​tích hợp về cách tổ chức CSS

Sau khi làm việc trong khuôn khổ, tôi đã tìm thấy một loạt các mô hình tổ chức mà tôi tin rằng cả hai đều phù hợp với các triết lý chỉ đạo của Next. js và thực hiện các phương pháp CSS tốt nhất. Trong bài viết này, chúng ta sẽ xây dựng một trang web (một quán trà. ) cùng nhau để chứng minh những mẫu này

Ghi chú. Bạn có thể sẽ không cần Next trước. js, mặc dù sẽ rất tốt nếu bạn có hiểu biết cơ bản về React và sẵn sàng học một số kỹ thuật CSS mới

Viết CSS “kiểu cũ”

Khi lần đầu tiên nhìn vào Tiếp theo. js, chúng ta có thể cân nhắc sử dụng một số loại thư viện CSS-in-JS. Mặc dù có thể có những lợi ích tùy thuộc vào dự án, nhưng CSS-in-JS đưa ra nhiều cân nhắc kỹ thuật. Nó yêu cầu sử dụng một thư viện bên ngoài mới, làm tăng thêm kích thước gói. CSS-in-JS cũng có thể có tác động đến hiệu suất bằng cách tạo ra các kết xuất bổ sung và phụ thuộc vào trạng thái chung

đề nghị đọc. “Chi phí hiệu suất chưa từng thấy của các thư viện CSS-in-JS hiện đại trong ứng dụng React)” của Aggelos Arvanitakis

Hơn nữa, toàn bộ điểm của việc sử dụng một thư viện như Next. js là hiển thị nội dung tĩnh bất cứ khi nào có thể, do đó, việc viết JS cần được chạy trong trình duyệt để tạo CSS sẽ không có ý nghĩa gì nhiều

Có một số câu hỏi chúng ta phải xem xét khi sắp xếp phong cách trong Next. js

Làm thế nào chúng ta có thể phù hợp với các quy ước/thực tiễn tốt nhất của khuôn khổ?

Làm cách nào chúng ta có thể cân bằng mối quan tâm về kiểu dáng “toàn cầu” (phông chữ, màu sắc, bố cục chính, v.v.) với kiểu dáng “cục bộ” (kiểu dáng liên quan đến các thành phần riêng lẻ)?

Câu trả lời tôi đã đưa ra cho câu hỏi đầu tiên là chỉ cần viết CSS thời trang tốt. Không chỉ tiếp theo. js hỗ trợ làm như vậy mà không cần thiết lập bổ sung;

Để giải quyết vấn đề thứ hai, tôi thực hiện một cách tiếp cận có thể được tóm tắt trong bốn phần

  1. Thiết kế mã thông báo
  2. phong cách toàn cầu
  3. lớp học tiện ích
  4. phong cách thành phần

Tôi mang ơn ý tưởng của Andy Bell về CUBE CSS (“Thành phần, Tiện ích, Khối, Ngoại lệ”) tại đây. Nếu bạn chưa từng nghe về nguyên tắc tổ chức này trước đây, tôi khuyên bạn nên xem trang web chính thức hoặc tính năng của nó trên Smashing Podcast. Một trong những nguyên tắc chúng tôi sẽ lấy từ CUBE CSS là ý tưởng rằng chúng ta nên nắm lấy thay vì sợ hãi dòng thác CSS. Hãy học những kỹ thuật này bằng cách áp dụng chúng vào một dự án trang web

Bắt đầu

Chúng tôi sẽ xây dựng một cửa hàng trà bởi vì, trà rất ngon. Chúng tôi sẽ bắt đầu bằng cách chạy

import '../styles/design_tokens.css'
8 để tạo một Tiếp theo mới. dự án js. Sau đó, chúng tôi sẽ xóa mọi thứ trong
import '../styles/design_tokens.css'
9 (tất cả đều là mã mẫu)

Ghi chú. Nếu bạn muốn theo dõi dự án đã hoàn thành, bạn có thể xem tại đây

Mã thông báo thiết kế

Trong hầu hết mọi thiết lập CSS, có một lợi ích rõ ràng khi lưu trữ tất cả các giá trị được chia sẻ toàn cầu trong các biến. Nếu một khách hàng yêu cầu thay đổi màu sắc, việc thực hiện thay đổi chỉ là một việc đơn giản chứ không phải là một mớ hỗn độn tìm và thay thế lớn. Do đó, một phần quan trọng trong Tiếp theo của chúng tôi. js Thiết lập CSS sẽ lưu trữ tất cả các giá trị trên toàn trang web dưới dạng mã thông báo thiết kế

Chúng tôi sẽ sử dụng Thuộc tính tùy chỉnh CSS có sẵn để lưu trữ các mã thông báo này. (Nếu bạn không quen với cú pháp này, bạn có thể xem “Hướng dẫn chiến lược cho thuộc tính tùy chỉnh CSS”. ) Tôi nên đề cập rằng (trong một số dự án) tôi đã chọn sử dụng các biến SASS/SCSS cho mục đích này. Tôi chưa tìm thấy bất kỳ lợi thế thực sự nào, vì vậy tôi thường chỉ đưa SASS vào một dự án nếu tôi thấy mình cần các tính năng khác của SASS (trộn, lặp, nhập tệp, v.v.). Ngược lại, các thuộc tính tùy chỉnh CSS cũng hoạt động với tầng và có thể được thay đổi theo thời gian thay vì biên dịch tĩnh. Vì vậy, hôm nay, hãy gắn bó với CSS đơn giản

Trong thư mục

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
0 của chúng ta, hãy tạo một design_tokens mới. tập tin css

:root {
  --green: #3FE79E;
  --dark: #0F0235;
  --off-white: #F5F5F3;

  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;

  --font-size-sm: 0.5rem;
  --font-size-md: 1rem;
  --font-size-lg: 2rem;
}

Tất nhiên, danh sách này có thể và sẽ phát triển theo thời gian. Khi chúng tôi thêm tệp này, chúng tôi cần chuyển đến các trang/_app của chúng tôi. jsx, đây là bố cục chính cho tất cả các trang của chúng tôi và thêm

import '../styles/design_tokens.css'

Tôi thích nghĩ về các mã thông báo thiết kế như chất keo duy trì tính nhất quán trong toàn bộ dự án. Chúng tôi sẽ tham chiếu các biến này trên quy mô toàn cầu, cũng như trong các thành phần riêng lẻ, đảm bảo ngôn ngữ thiết kế thống nhất

Thêm sau khi nhảy. Tiếp tục đọc bên dưới ↓

Gặp gỡ Hội thảo trực tuyến Smashing về giao diện người dùng & giao diện người dùng, với các bài học thực tế, phiên trực tiếp, bản ghi video và phần Hỏi & Đáp thân thiện. Trên các hệ thống thiết kế, UX, hiệu suất web và CSS/JS. Với Brad Frost, Stephanie Troeth và rất nhiều người khác

Chuyển đến hội thảo ↬

phong cách toàn cầu

Tiếp theo, hãy thêm một trang vào trang web của chúng tôi. Hãy nhảy vào các trang / chỉ mục. jsx (đây là trang chủ của chúng tôi). Chúng tôi sẽ xóa tất cả các bản soạn sẵn và thêm một cái gì đó như

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}

Thật không may, nó sẽ trông khá đơn giản, vì vậy hãy thiết lập một số kiểu toàn cầu cho các thành phần cơ bản, v.v. g.

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
1 thẻ. (Tôi thích coi những phong cách này là “mặc định toàn cầu hợp lý”. ) Chúng tôi có thể ghi đè chúng trong các trường hợp cụ thể, nhưng chúng là một dự đoán tốt về những gì chúng tôi sẽ muốn nếu chúng tôi không

Tôi sẽ đặt cái này trong style/globals. css (theo mặc định từ Next. js)

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

body {
  color: var(--off-white);
  background-color: var(--dark);
}

h1 {
  color: var(--green);
  font-size: var(--font-size-lg);
}

p {
  font-size: var(--font-size-md);
}

p, article, section {
  line-height: 1.5;
}

:focus {
  outline: 0.15rem dashed var(--off-white);
  outline-offset: 0.25rem;
}
main:focus {
  outline: none;
}

img {
  max-width: 100%;
}

Tất nhiên, phiên bản này khá cơ bản, nhưng toàn cầu của tôi. tệp css thường không thực sự cần quá lớn. Ở đây, tôi tạo kiểu cho các phần tử HTML cơ bản (tiêu đề, nội dung, liên kết, v.v.). Không cần phải bọc các phần tử này trong các thành phần React hoặc liên tục thêm các lớp chỉ để cung cấp kiểu cơ bản

Tôi cũng bao gồm mọi thiết lập lại kiểu trình duyệt mặc định. Thỉnh thoảng, tôi sẽ có một số kiểu bố cục trên toàn trang web để cung cấp "chân trang dính", nhưng chúng chỉ thuộc về đây nếu tất cả các trang chia sẻ cùng một bố cục. Nếu không, nó sẽ cần được đặt trong phạm vi bên trong các thành phần riêng lẻ

Tôi luôn bao gồm một số loại kiểu dáng

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
2 để biểu thị rõ ràng các yếu tố tương tác cho người dùng bàn phím khi tập trung. Tốt nhất là biến nó thành một phần không thể thiếu trong DNA thiết kế của trang web

Bây giờ, trang web của chúng tôi đang bắt đầu hình thành

Mô-đun CSS Nextjs
Hình ảnh của trang web đang làm việc. Nền trang bây giờ có màu xanh đậm và dòng tiêu đề 'Trà làm dịu' có màu xanh lá cây. Trang web không có bố cục/khoảng cách và do đó mở rộng hoàn toàn theo chiều rộng của cửa sổ trình duyệt. (Xem trước lớn)

lớp học tiện ích

Một lĩnh vực mà trang chủ của chúng tôi chắc chắn có thể cải thiện là văn bản hiện luôn kéo dài sang các cạnh của màn hình, vì vậy hãy giới hạn chiều rộng của nó. Chúng tôi cần bố cục này trên trang này, nhưng tôi tưởng tượng rằng chúng tôi cũng có thể cần nó trên các trang khác. Đây là một trường hợp sử dụng tuyệt vời cho một lớp tiện ích

Tôi cố gắng sử dụng các lớp tiện ích một cách tiết kiệm hơn là thay thế cho việc chỉ viết CSS. Tiêu chí cá nhân của tôi về thời điểm hợp lý để thêm một dự án là

  1. Tôi cần nó nhiều lần;
  2. Nó làm tốt một việc;
  3. Nó áp dụng trên một loạt các thành phần hoặc trang khác nhau

Tôi nghĩ trường hợp này đáp ứng cả ba tiêu chí, vì vậy hãy tạo một kiểu/tiện ích tệp CSS mới. css và thêm

.lockup {
  max-width: 90ch;
  margin: 0 auto;
}

Sau đó, hãy thêm import

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
3 vào pages/_app của chúng ta. jsx. Cuối cùng, hãy thay đổi thẻ
export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
4 trong các trang/chỉ mục của chúng tôi. jsx đến
export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
5

Bây giờ, trang của chúng tôi đang đến với nhau nhiều hơn nữa. Vì chúng tôi đã sử dụng thuộc tính

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
6 nên chúng tôi không cần bất kỳ truy vấn phương tiện nào để làm cho bố cục của chúng tôi phản hồi nhanh trên thiết bị di động. Và, bởi vì chúng tôi đã sử dụng đơn vị đo lường
export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
7 — tương đương với chiều rộng của một ký tự — kích thước của chúng tôi linh hoạt đối với kích thước phông chữ trình duyệt của người dùng

Mô-đun CSS Nextjs
Trang web giống như trước đây, nhưng bây giờ văn bản được kẹp ở giữa và không quá rộng. (Xem trước lớn)

Khi trang web của chúng tôi phát triển, chúng tôi có thể tiếp tục thêm nhiều lớp tiện ích hơn. Tôi có một cách tiếp cận khá thực dụng ở đây. Nếu tôi đang làm việc và thấy mình cần một lớp khác cho màu sắc hoặc thứ gì đó, tôi sẽ thêm nó vào. Tôi không thêm mọi lớp có thể dưới ánh nắng mặt trời - nó sẽ làm tăng kích thước tệp CSS và làm cho mã của tôi khó hiểu. Đôi khi, trong các dự án lớn hơn, tôi muốn chia nhỏ mọi thứ thành một thư mục

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
8 với một vài tệp khác nhau;

Chúng ta có thể coi các lớp tiện ích là bộ công cụ gồm các lệnh tạo kiểu phổ biến, lặp đi lặp lại được chia sẻ trên toàn cầu. Chúng giúp ngăn chúng tôi liên tục viết lại cùng một CSS giữa các thành phần khác nhau

Kiểu thành phần

Chúng tôi đã hoàn thành trang chủ của mình vào lúc này, nhưng chúng tôi vẫn cần xây dựng một phần trang web của mình. cửa hàng trực tuyến. Mục tiêu của chúng tôi ở đây là hiển thị một lưới thẻ gồm tất cả các loại trà mà chúng tôi muốn bán, vì vậy chúng tôi sẽ cần thêm một số thành phần vào trang web của mình

Hãy bắt đầu bằng cách thêm một trang mới tại pages/shop. jsx

export default function Shop() {
  return 

Shop Our Teas

}

Sau đó, chúng ta sẽ cần một số loại trà để hiển thị. Chúng tôi sẽ bao gồm tên, mô tả và hình ảnh (trong thư mục công cộng/) cho mỗi loại trà

const teas = [
  { name: "Oolong", description: "A partially fermented tea.", image: "/oolong.jpg" },
  // ...
]

Ghi chú. Đây không phải là bài viết về tìm nạp dữ liệu, vì vậy chúng tôi đã chọn cách dễ dàng và xác định một mảng ở đầu tệp

Tiếp theo, chúng tôi sẽ cần xác định một thành phần để hiển thị các loại trà của chúng tôi. Hãy bắt đầu bằng cách tạo một thư mục

export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
9 (Tiếp theo. js không làm điều này theo mặc định). Sau đó, hãy thêm một thư mục
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  color: var(--off-white);
  background-color: var(--dark);
}

h1 {
  color: var(--green);
  font-size: var(--font-size-lg);
}

p {
  font-size: var(--font-size-md);
}

p, article, section {
  line-height: 1.5;
}

:focus {
  outline: 0.15rem dashed var(--off-white);
  outline-offset: 0.25rem;
}
main:focus {
  outline: none;
}

img {
  max-width: 100%;
}
0. Đối với bất kỳ thành phần nào cần nhiều hơn một tệp, tôi thường đặt tất cả các tệp liên quan vào một thư mục. Làm như vậy sẽ ngăn thư mục
export default function Home() {
  return 

Soothing Teas

Welcome to our wonderful tea shop.

We have been open since 1987 and serve customers with hand-picked oolong teas.

}
9 của chúng tôi không thể điều hướng được

Bây giờ, hãy thêm các thành phần của bạn/RealList/RealList. tập tin jsx

import TeaListItem from './TeaListItem'

const TeaList = (props) => {
  const { teas } = props

  return 
    {teas.map(tea => )}
} export default TeaList

Mục đích của thành phần này là lặp lại các loại trà của chúng ta và hiển thị một mục danh sách cho từng loại, vì vậy bây giờ hãy xác định các thành phần của chúng ta/TeaList/TeaListItem. thành phần jsx

import Image from 'next/image'

const TeaListItem = (props) => {
  const { tea } = props

  return 
  • {tea.name}

    {tea.description}

  • } export default TeaListItem

    Lưu ý rằng chúng tôi đang sử dụng Tiếp theo. thành phần hình ảnh tích hợp của js. Tôi đặt thuộc tính

    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    2 thành một chuỗi trống vì hình ảnh hoàn toàn mang tính chất trang trí trong trường hợp này;

    Cuối cùng, hãy tạo một components/TeaList/index. js để các thành phần của chúng ta dễ dàng nhập từ bên ngoài

    import TeaList from './TeaList'
    import TeaListItem from './TeaListItem'
    
    export { TeaListItem }
    
    export default TeaList

    Và sau đó, hãy kết hợp tất cả lại với nhau bằng cách thêm nhập TeaList từ

    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    3 và một thành phần
    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    4 vào trang Cửa hàng của chúng tôi. Bây giờ, các loại trà của chúng ta sẽ hiển thị trong một danh sách, nhưng nó sẽ không đẹp lắm

    Định vị phong cách với các thành phần thông qua các mô-đun CSS

    Hãy bắt đầu bằng cách tạo kiểu cho thẻ của chúng ta (thành phần

    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    5). Bây giờ, lần đầu tiên trong dự án của chúng tôi, chúng tôi sẽ muốn thêm kiểu chỉ dành riêng cho một thành phần. Hãy tạo một file mới components/TeaList/TeaListItem. mô-đun. css

    Bạn có thể thắc mắc về mô-đun trong phần mở rộng tệp. Đây là một mô-đun CSS. Kế tiếp. js hỗ trợ các mô-đun CSS và bao gồm một số mô-đun trên chúng. Khi chúng ta viết một tên lớp từ một mô-đun CSS, chẳng hạn như

    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    6, nó sẽ tự động được chuyển đổi thành một cái gì đó giống như
    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    7 với một loạt các ký tự bổ sung được thêm vào. Do đó, chúng tôi có thể sử dụng bất kỳ tên lớp nào chúng tôi muốn mà không cần lo lắng rằng nó sẽ xung đột với các tên lớp khác ở nơi khác trong trang web của chúng tôi

    Một ưu điểm khác của các mô-đun CSS là hiệu suất. Kế tiếp. js bao gồm tính năng nhập động. next/dynamic cho phép chúng ta tải chậm các thành phần để mã của chúng chỉ được tải khi cần, thay vì thêm vào toàn bộ kích thước gói. Nếu chúng ta nhập các kiểu cục bộ cần thiết vào các thành phần riêng lẻ, thì người dùng cũng có thể lười tải CSS cho các thành phần được nhập động. Đối với các dự án lớn, chúng tôi có thể chọn lười tải các đoạn mã quan trọng của mình và chỉ tải trả trước JS/CSS cần thiết nhất. Do đó, tôi thường tạo một tệp Mô-đun CSS mới cho mọi thành phần mới cần tạo kiểu cục bộ

    Hãy bắt đầu bằng cách thêm một số kiểu ban đầu vào tệp của chúng tôi

    import '../styles/design_tokens.css'
    0

    Sau đó, chúng tôi có thể nhập kiểu từ

    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    8 trong thành phần
    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    body {
      color: var(--off-white);
      background-color: var(--dark);
    }
    
    h1 {
      color: var(--green);
      font-size: var(--font-size-lg);
    }
    
    p {
      font-size: var(--font-size-md);
    }
    
    p, article, section {
      line-height: 1.5;
    }
    
    :focus {
      outline: 0.15rem dashed var(--off-white);
      outline-offset: 0.25rem;
    }
    main:focus {
      outline: none;
    }
    
    img {
      max-width: 100%;
    }
    9 của chúng tôi. Biến kiểu xuất hiện giống như một đối tượng JavaScript, vì vậy chúng ta có thể truy cập lớp này giống như ___9_______0

    Ghi chú. Tên class của chúng ta không cần viết hoa. Tôi nhận thấy rằng một quy ước về tên lớp viết hoa bên trong các mô-đun (và chữ thường bên ngoài) phân biệt giữa địa phương và địa phương. tên lớp toàn cầu trực quan

    Vì vậy, hãy lấy lớp cục bộ mới của chúng ta và gán nó cho ___9_______1 trong thành phần ___9_______2 của chúng ta

    import '../styles/design_tokens.css'
    1

    Có thể bạn đang thắc mắc về đường màu nền (i. e.

    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    3). Ý nghĩa của đoạn mã này là theo mặc định, nền sẽ là giá trị
    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    4 của chúng tôi. Tuy nhiên, nếu chúng tôi đặt thuộc tính tùy chỉnh
    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    5 trên thẻ, nó sẽ ghi đè và chọn giá trị đó thay thế

    Lúc đầu, chúng tôi muốn tất cả các thẻ của mình là

    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    4, nhưng chúng tôi có thể muốn thay đổi giá trị cho các thẻ riêng lẻ sau này. Điều này hoạt động rất giống với props trong React. Chúng tôi có thể đặt giá trị mặc định nhưng tạo một vị trí nơi chúng tôi có thể chọn các giá trị khác trong các trường hợp cụ thể. Vì vậy, tôi khuyến khích chúng ta nghĩ về các thuộc tính tùy chỉnh của CSS giống như phiên bản đạo cụ của CSS

    Phong cách vẫn không đẹp mắt vì chúng tôi muốn đảm bảo rằng hình ảnh nằm trong vùng chứa của chúng. Kế tiếp. Thành phần Hình ảnh của js với giá trị

    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    7 nhận được
    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    8 từ khung, vì vậy chúng tôi có thể giới hạn kích thước bằng cách đặt vào một vùng chứa có vị trí. liên quan đến;

    Hãy thêm một lớp mới vào TeaListItem của chúng ta. mô-đun. css

    import '../styles/design_tokens.css'
    2

    Và sau đó, hãy thêm

    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    9 vào
    export default function Shop() {
      return 

    Shop Our Teas

    }
    0 có chứa
    export default function Shop() {
      return 

    Shop Our Teas

    }
    1 của chúng ta. Tôi sử dụng các tên tương đối “đơn giản” chẳng hạn như
    export default function Shop() {
      return 

    Shop Our Teas

    }
    2 vì chúng tôi đang ở trong một mô-đun CSS, vì vậy chúng tôi không phải lo lắng về việc xung đột với phong cách bên ngoài

    Cuối cùng, chúng tôi muốn thêm một chút khoảng đệm vào các cạnh của văn bản, vì vậy, hãy thêm một lớp cuối cùng và dựa vào các biến khoảng cách mà chúng tôi đã thiết lập làm mã thông báo thiết kế

    import '../styles/design_tokens.css'
    3

    Chúng ta có thể thêm lớp này vào

    export default function Shop() {
      return 

    Shop Our Teas

    }
    0 chứa tên và mô tả của chúng ta. Bây giờ, thẻ của chúng tôi trông không tệ lắm

    Mô-đun CSS Nextjs
    Thẻ đang hiển thị cho 3 loại trà khác nhau đã được thêm làm dữ liệu hạt giống. Họ có hình ảnh, tên và mô tả. Chúng hiện hiển thị trong một danh sách dọc không có khoảng cách giữa chúng. (Xem trước lớn)

    Kết hợp phong cách toàn cầu và địa phương

    Tiếp theo, chúng tôi muốn thẻ của mình hiển thị theo bố cục dạng lưới. Trong trường hợp này, chúng tôi chỉ ở ranh giới giữa phong cách địa phương và toàn cầu. Chúng tôi chắc chắn có thể viết mã bố cục của mình trực tiếp trên thành phần

    export default function Shop() {
      return 

    Shop Our Teas

    }
    4. Tuy nhiên, tôi cũng có thể tưởng tượng rằng việc có một lớp tiện ích biến danh sách thành bố cục dạng lưới có thể hữu ích ở một số nơi khác

    Hãy thực hiện cách tiếp cận toàn cầu tại đây và thêm một lớp tiện ích mới trong các kiểu/tiện ích của chúng tôi. css

    import '../styles/design_tokens.css'
    4

    Bây giờ, chúng ta có thể thêm lớp

    export default function Shop() {
      return 

    Shop Our Teas

    }
    5 vào bất kỳ danh sách nào và chúng ta sẽ nhận được bố cục dạng lưới phản hồi tự động. Chúng ta cũng có thể thay đổi thuộc tính tùy chỉnh
    export default function Shop() {
      return 

    Shop Our Teas

    }
    6 (theo mặc định là
    export default function Shop() {
      return 

    Shop Our Teas

    }
    7) để thay đổi chiều rộng tối thiểu của mỗi phần tử

    Ghi chú. Hãy nhớ nghĩ về các thuộc tính tùy chỉnh như đạo cụ. Nếu cú ​​pháp này có vẻ lạ, bạn có thể xem “Lưới CSS đáp ứng nội tại với

    export default function Shop() {
      return 

    Shop Our Teas

    }
    8 và
    export default function Shop() {
      return 

    Shop Our Teas

    }
    9” của Chris Coyier

    Vì chúng tôi đã viết phong cách này trên toàn cầu, nên không yêu cầu bất kỳ sự sáng tạo nào để thêm

    const teas = [
      { name: "Oolong", description: "A partially fermented tea.", image: "/oolong.jpg" },
      // ...
    ]
    0 vào thành phần
    export default function Shop() {
      return 

    Shop Our Teas

    }
    4 của chúng tôi. Tuy nhiên, giả sử chúng tôi muốn kết hợp phong cách toàn cầu này với một số cửa hàng địa phương bổ sung. Ví dụ: chúng tôi muốn mang thêm một chút “thẩm mỹ uống trà” vào và làm cho mọi thẻ khác có nền màu xanh lá cây. Tất cả những gì chúng ta cần làm là tạo một components/TeaList/TeaList mới. mô-đun. tập tin css

    import '../styles/design_tokens.css'
    5

    Hãy nhớ cách chúng tôi tạo một thuộc tính

    const teas = [
      { name: "Oolong", description: "A partially fermented tea.", image: "/oolong.jpg" },
      // ...
    ]
    2 trên thành phần
    .lockup {
      max-width: 90ch;
      margin: 0 auto;
    }
    2 của chúng tôi? . Lưu ý rằng chúng ta vẫn có thể sử dụng các bộ chọn con trong các mô-đun CSS và việc chúng ta chọn một phần tử được tạo kiểu bên trong một mô-đun khác không quan trọng. Vì vậy, chúng ta cũng có thể sử dụng các kiểu thành phần cục bộ của mình để tác động đến các thành phần con. Đây là một tính năng chứ không phải lỗi, vì nó cho phép chúng tôi tận dụng lợi thế của tầng CSS. Nếu chúng tôi cố gắng tái tạo hiệu ứng này theo một cách khác, chúng tôi có thể sẽ nhận được một số loại súp JavaScript hơn là ba dòng CSS

    Sau đó, làm thế nào chúng ta có thể giữ lớp

    export default function Shop() {
      return 

    Shop Our Teas

    }
    5 toàn cầu trên thành phần
    export default function Shop() {
      return 

    Shop Our Teas

    }
    4 của mình đồng thời thêm lớp
    const teas = [
      { name: "Oolong", description: "A partially fermented tea.", image: "/oolong.jpg" },
      // ...
    ]
    6 cục bộ?

    Một tùy chọn sẽ là sử dụng phép nội suy chuỗi để có được thứ gì đó như

    import '../styles/design_tokens.css'
    6

    Trong trường hợp nhỏ này, điều này có thể đủ tốt. Nếu chúng tôi trộn và kết hợp nhiều lớp hơn, tôi thấy rằng cú pháp này khiến não tôi hơi nổ tung, vì vậy đôi khi tôi sẽ chọn sử dụng thư viện tên lớp. Trong trường hợp này, chúng tôi kết thúc với một danh sách hợp lý hơn

    import '../styles/design_tokens.css'
    7

    Bây giờ, chúng tôi đã hoàn thành trang Cửa hàng của mình và chúng tôi đã làm cho thành phần

    export default function Shop() {
      return 

    Shop Our Teas

    }
    4 của mình tận dụng cả phong cách toàn cầu và địa phương

    Mô-đun CSS Nextjs
    Thẻ trà của chúng tôi hiện hiển thị trong một lưới. Các mục sự kiện có màu xanh lục, trong khi các mục lẻ có màu trắng. (Xem trước lớn)

    Đạo luật cân bằng

    Bây giờ chúng tôi đã xây dựng quán trà của mình chỉ bằng CSS đơn giản để xử lý kiểu dáng. Bạn có thể nhận thấy rằng chúng tôi không phải mất nhiều thời gian để xử lý các thiết lập Webpack tùy chỉnh, cài đặt các thư viện bên ngoài, v.v. Đó là do các mẫu mà chúng tôi đã sử dụng hoạt động với Next. js ra khỏi hộp. Hơn nữa, họ khuyến khích các phương pháp CSS tốt nhất và phù hợp một cách tự nhiên với Tiếp theo. kiến trúc khung js

    Tổ chức CSS của chúng tôi bao gồm bốn phần chính

    1. Thiết kế mã thông báo,
    2. phong cách toàn cầu,
    3. Các lớp tiện ích,
    4. phong cách thành phần

    Khi chúng tôi tiếp tục xây dựng trang web của mình, danh sách mã thông báo thiết kế và lớp tiện ích của chúng tôi sẽ tăng lên. Bất kỳ kiểu dáng nào không hợp lý để thêm dưới dạng một lớp tiện ích, chúng ta có thể thêm vào các kiểu thành phần bằng cách sử dụng các mô-đun CSS. Kết quả là, chúng ta có thể tìm thấy sự cân bằng liên tục giữa các mối quan tâm về phong cách địa phương và toàn cầu. Chúng tôi cũng có thể tạo mã CSS trực quan, hiệu quả, phát triển tự nhiên cùng với Tiếp theo của chúng tôi. trang js

    CSS nào là tốt nhất cho Nextjs?

    Tailwind CSS là một trong những khung CSS nổi tiếng nhất hiện có và đặc biệt được sử dụng với React. js và Tiếp theo. js. Đây là khung CSS ưu tiên tiện ích được đóng gói với các lớp như flex flex-start pt-4 items-center có thể được tạo để xây dựng bất kỳ thiết kế nào, trực tiếp trong phần đánh dấu của bạn.

    Làm cách nào để áp dụng CSS trong nextjs?

    Để thêm biểu định kiểu vào ứng dụng của bạn, hãy nhập tệp CSS trong pages/_app. js . Tạo một trang/_ứng dụng. js nếu chưa có. Sau đó, nhập các kiểu. tập tin css. Những phong cách này ( phong cách. css ) sẽ áp dụng cho tất cả các trang và thành phần trong ứng dụng của bạn.

    Sự khác biệt giữa các mô-đun CSS và kiểu

    Với các thành phần được tạo kiểu, bạn đính kèm các kiểu ngay vào thành phần đó và không thực sự đặt tên cho bất kỳ thứ gì. Với các mô-đun css, bạn chỉ áp dụng các kiểu trực tiếp cho một phần tử HTML . Với các thành phần được tạo kiểu, bạn có thể áp dụng các kiểu cho các thành phần tùy chỉnh và nó sẽ áp dụng các kiểu đó bằng cách truyền bá các đạo cụ sau này.

    Tôi có thể sử dụng các mô-đun CSS với Sass không?

    Mô-đun CSS hoạt động trơn tru với các bộ xử lý trước như SASS, LESS và Stylus . Nó cũng hoạt động với PostCSS.