Hướng dẫn css modules dynamic classes - các mô-đun css các lớp động

Tôi đang sử dụng các mô -đun CSS

import style from "./styles/question.module.css";

// status[0] could be 0,1,2,3,4
<p className={style[`difficulty_${status[0]}`]}>{difficulty}</p>,

Mã trên đang hoạt động, nhưng mã dưới đây không hoạt động.

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>

Chỉ có lớp

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
7 đang được áp dụng.

Các nhà phát triển web đã dành thời gian và nỗ lực to lớn để tạo ra các thành phần có thể tái sử dụng. Một trong những vấn đề là CSS và bản chất xếp tầng của nó. Ví dụ: nếu nhà phát triển tạo một thành phần hiển thị cấu trúc cây, làm thế nào cô ấy có thể đảm bảo rằng lớp CSS (giả sử, .leaf) được sử dụng trong thành phần sẽ không có tác dụng phụ trong các phần khác của ứng dụng. Các phương pháp và quy ước mới đã được tạo ra để giải quyết các vấn đề chọn. Cả BEM và SMACS đều là những phương pháp được sử dụng rộng rãi đã phục vụ tốt các nhà phát triển web, nhưng chúng là xa các giải pháp lý tưởng. Bài đăng trên blog này sẽ giải thích những gì phương pháp dựa trên quy ước đặt tên cho các mô -đun CSS là gì và làm thế nào các mô -đun này có thể được sử dụng trong ứng dụng React.

Vấn đề với việc xếp tầng

Tôi đang tạo một danh sách chọn có thể tái sử dụng (AKA Danh sách thả xuống) như một ví dụ về các vấn đề phong cách toàn cầu. Kiểu dáng phần tử

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
8 không cảm thấy đúng vì có thể cần có phần tử gốc không có kiểu dáng hoặc kiểu dáng hoàn toàn khác nhau trong các lĩnh vực khác của trang web. Thay vào đó, tôi sử dụng cú pháp BEM để xác định các lớp:

.select {}
.select__item {}
.select__item__icon {}
.select--loading {}

Nếu tôi đã tạo một lớp mới có tên là Mục mà không có hậu tố SELECT__, nhóm của tôi có thể gặp rắc rối nếu người khác muốn sử dụng mục tên chung. Sẽ không quan trọng liệu thư viện của bên thứ ba hay thành viên nhóm đang tạo khung CSS cho dự án. Sử dụng BEM giúp bạn tránh vấn đề này bằng cách chỉ ra ngữ cảnh chọn.

Cú pháp BEM đại diện cho một bước hướng tới các thành phần, vì "B" trong BEM là viết tắt của "khối" và các khối có thể được coi là các thành phần trọng lượng nhẹ. Chọn là một thành phần có trạng thái khác nhau (chọn-tải) và trẻ em (chọn__item).

Thật không may, sử dụng một quy ước đặt tên và suy nghĩ về các thành phần không giải quyết tất cả các vấn đề chọn. Tránh một vụ va chạm tên vẫn không được đảm bảo, và tính xác định của sơ đồ đặt tên làm tăng nguy cơ lỗi chính tả và yêu cầu một nhóm có kỷ luật nơi mọi người hiểu chính xác các quy ước 100%. Typo bao gồm có dấu gạch ngang đơn thay vì hai, trộn điều chỉnh (-) và block (__), v.v.

Các mô -đun CSS để giải cứu

Định nghĩa của "Mô -đun CSS" như sau:

Mô -đun CSS là tệp CSS trong đó tất cả các tên lớp và tên hoạt hình được phân chia cục bộ theo mặc định.

Điều quan trọng là phạm vi địa phương.

Để minh họa khái niệm này, hãy tạo các tệp JavaScript và CSS sẽ xác định một thành phần.

/* select.css */
.select {}
.loading {}
.item {}
.icon {}
/* select.js */
import styles from "./select.css";

console.log(styles.select, styles.loading);  

Ví dụ đơn giản, nhưng có nhiều điều xảy ra dưới mui xe.

Tệp CSS có tiếng ồn ít hơn nhiều so với phiên bản BEM vì nó không chứa hậu tố và các ký tự phụ để lặp lại ngữ cảnh. Tại sao tôi có thể loại bỏ một hậu tố như .Select-- mà không gây ra vấn đề?

Câu lệnh

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
9 trong tệp JavaScript tải tệp CSS và chuyển đổi nó thành một đối tượng. Trong chương tiếp theo, tôi sẽ chỉ cho bạn cách thiết lập môi trường xây dựng để hỗ trợ nhập các tệp CSS.

Mỗi tên lớp từ tệp CSS là một thuộc tính của đối tượng, trong ví dụ trên, style.select, style.icon, v.v.

Nếu tên thuộc tính là tên lớp, thì giá trị của thuộc tính đó là gì? Nó là một tên lớp độc đáo và tính độc đáo đảm bảo rằng các kiểu không rò rỉ vào các thành phần khác. Dưới đây là một ví dụ về tên lớp băm: _header__1ouvt.

Bạn có thể đang nghĩ, "Điều đó trông khủng khiếp." Điểm thay đổi tên lớp có ý nghĩa thành mã khó hiểu là gì?

Điểm chính là một định danh như vậy được đảm bảo là duy nhất trên toàn cầu. Sau đó trong hướng dẫn, chúng tôi sẽ sửa đổi tạo định danh để nó sẽ có một định danh có thể đọc được nhiều hơn nhưng vẫn là duy nhất.

Những lợi ích chính của việc có CSS ​​có phạm vi cục bộ:

  • một bước tới các thành phần mô -đun và có thể tái sử dụng sẽ không có tác dụng phụ
  • CSS sạch hơn
  • Tránh các tệp CSS nguyên khối, vì mỗi thành phần sẽ có tệp riêng

Disadvantages:

  • Không phải là con người có thể đọc được
  • Một chút chuẩn bị ban đầu để có bước xây dựng hoạt động

Các mô -đun CSS yêu cầu một bước xây dựng, nhưng tin tốt là các công cụ bó khác nhau hỗ trợ bước đó cho cả mã nguồn JavaScript máy khách và máy chủ. Bạn cũng có thể sử dụng các mô -đun CSS với hầu hết các thư viện UI.

Để giữ cho mọi thứ đơn giản, trong bài đăng trên blog này, tôi sẽ tập trung vào mô -đun WebPack và phản ứng.

Để bắt đầu mà không gặp rắc rối, tôi sử dụng ứng dụng Tạo React.

Bằng cách làm theo các hướng dẫn trong tài liệu, tôi nhận được một dự án mới và chạy ngay lập tức.

npm install -g create-react-app

create-react-app css-modules  
cd css-modules/  
npm start  

Lo và kìa, chúng tôi có một ứng dụng React đang chạy:

Trang bắt đầu nói rằng tôi nên chỉnh sửa tệp app.js.

import React, { Component } from 'react';  
import logo from './logo.svg';  
import './App.css';

class App extends Component {  
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit {gfm-js-extract-pre-1} and save to reload.
        </p>
      </div>
    );
  }
}

export default App;  

Là ứng dụng Created React sử dụng các mô -đun CSS? Tôi có thể xác minh rằng đó là bằng cách xem tệp app.js. Tệp CSS đang được nhập, nhưng nó không được gán cho bất kỳ biến nào và tất cả các định nghĩa ClassName đang sử dụng chuỗi thay vì các giá trị động.

Tại thời điểm này, ứng dụng Tạo React không hỗ trợ các mô -đun CSS, vì vậy tôi cần thay đổi cấu hình để hỗ trợ.

Định cấu hình ứng dụng Tạo React để hỗ trợ các mô -đun CSS

Để truy cập cấu hình xây dựng cơ bản, tôi cần chạy lệnh Eject. Lưu ý: Không có quay lại sau khi bạn làm điều này.

npm run eject  

Bây giờ tôi có thể xem thư mục cấu hình và tệp cấu hình webpack.

Ứng dụng Tạo React đang sử dụng webpack cho tất cả các tài sản, vì vậy WebPack.config.dev.js là tệp cấu hình chính xác để sửa đổi.

Tôi tìm kiếm một phần xác định những việc cần làm với các tệp CSS.

{
  test: /\.css$/,
  loader: 'style!css?importLoaders=1!postcss'
},

Thay đổi nó thành phần sau sẽ phá vỡ kiểu dáng của trang web trong giây lát vì cấu hình sẽ cho phép các mô -đun CSS, nhưng thành phần không được thay đổi để hỗ trợ các mô -đun CSS. Trong khi tôi đang sửa đổi cấu hình webpack, tôi đã thay đổi quy ước đặt tên thành cả phần có thể đọc được của con người trong đó và băm để giữ cho nó duy nhất:

{
  test: /\.css$/,
  loaders: [
    'style',
    'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]&sourceMap&-minimize'
  ]
},

Lưu ý rằng tôi đã thay đổi trình tải thành trình tải để cung cấp cho phần cấu hình một mảng thay vì một chuỗi.

Những người tải đang làm gì? Tệp webpack.config có phần bình luận mô tả các trình tải kiểu và CSS:

Trình tải "Kiểu" biến CSS thành các mô -đun JS để tiêm thẻ

.select {}
.select__item {}
.select__item__icon {}
.select--loading {}
0.

Trình tải "CSS" giải quyết các đường dẫn trong CSS và thêm tài sản làm phụ thuộc.

Từ khóa mô-đun bên cạnh trình tải CSS cho phép các mô-đun CSS. Cài đặt LocalidentName thay đổi tên lớp được tạo để nó chứa tên thành phần React, tên lớp và ID băm độc đáo. Thay đổi cấu hình này sẽ giúp gỡ lỗi dễ dàng hơn nhiều vì bạn sẽ có thể xác định thành phần có vấn đề.

Sử dụng các mô -đun CSS trong React

Tôi có thể xác minh rằng cấu hình hoạt động bằng cách thêm câu lệnh Console.log vào câu lệnh nhập.

Thay đổi

.select {}
.select__item {}
.select__item__icon {}
.select--loading {}
1 thành

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
0

Tôi nhận được đầu ra sau vào bảng điều khiển trình duyệt:

Hướng dẫn css modules dynamic classes - các mô-đun css các lớp động

Các lớp bây giờ là duy nhất, nhưng chúng không được sử dụng trong các thành phần React. Có hai bước mà tôi phải làm theo để áp dụng các kiểu cho các thành phần React. Đầu tiên, thay đổi tên của các kiểu thành vỏ lạc đà. Thứ hai, thay đổi các thuộc tính của ClassName để chúng sử dụng các lớp đã nhập.

Không bắt buộc phải sử dụng vốn hóa Camel Case, nhưng, khi truy cập các lớp theo chương trình, việc truy cập

.select {}
.select__item {}
.select__item__icon {}
.select--loading {}
2 sẽ dễ dàng hơn so với
.select {}
.select__item {}
.select__item__icon {}
.select--loading {}
3.

Đây là tệp kiểu ban đầu:

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
1

Không cần phải có tiền tố ứng dụng, vì vậy bây giờ cũng là thời điểm tốt để loại bỏ chúng.

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
2

Bước thứ hai là thay đổi cách sử dụng lớp. Kết quả trông như thế này:

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
3

Bây giờ tôi đã thực hiện tất cả các thay đổi cấu hình cần thiết và thay đổi thành phần để nó sử dụng các mô -đun CSS.

Cách phá vỡ ranh giới mô -đun CSS khi cần

Thiết lập được mô tả trong phần trước hoạt động như một cơ sở vững chắc cho một dự án React, nhưng các nhà phát triển có xu hướng sớm nhận ra rằng họ cần một cách để chia sẻ phong cách. Trong bối cảnh này, "chia sẻ" có nghĩa là chỉ ra rõ ràng rằng một thành phần nên kế thừa một cái gì đó từ các kiểu cơ sở.

Thông tin được chia sẻ có thể là các biến (màu sắc, kích thước phông chữ, v.v.), người trợ giúp (mixin) hoặc các lớp tiện ích.

Các mô -đun CSS có chức năng mở rộng có thể được sử dụng trên các tệp với từ khóa.

Trong ví dụ sau, tôi có hai tệp: một cho các kiểu cơ sở nút và một cho việc triển khai nút gửi. Tôi có thể nói rằng lớp con, nên bao gồm các kiểu nút cơ sở.

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
4

Ví dụ trước là về các lớp CSS. Nếu các biến là cần thiết, thì bạn có thể sử dụng bộ tiền xử lý như SASS hoặc ít hơn hoặc thêm hỗ trợ biến vào trang web của bạn.

Ví dụ trong tài liệu hỗ trợ biến:

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
5

Tôi sẽ thực hiện một thay đổi nhỏ đối với việc đặt tên biến: Sử dụng cú pháp SASS cho các tên biến được đi trước bởi một dấu hiệu đô la. Lý do cho thay đổi này là việc ghi đè các giá trị tiêu chuẩn như Blue làm cho tệp CSS không thể hiểu được vì bạn không bao giờ có thể chắc chắn liệu giá trị có bị ghi đè hay không.

Ví dụ thay đổi:

// tried to add more class
<p className={`${style.difficulty} ${style[`difficulty_${status[0]}`]}}`}>{difficulty}</p>
6

Sự kết luận

Trong hướng dẫn này, tôi đã bắt đầu với vấn đề với CSS toàn cầu và giải thích lý do tại sao các mô-đun CSS cải thiện tình hình bằng cách giới thiệu CSS phạm vi và đẩy chúng tôi hướng tới tư duy dựa trên thành phần. Ngoài ra, tôi đã đi qua con đường để dễ dàng bắt đầu thử nghiệm các mô -đun CSS bằng cách sử dụng bộ khởi động React.

Nếu các mô -đun CSS được sử dụng trong bước xây dựng phụ trợ, hỗ trợ trình duyệt không phải là vấn đề. Các trình duyệt nhận CSS thường xuyên từ máy chủ, do đó không có cách nào để ảnh hưởng tiêu cực đến trải nghiệm người dùng với các mô -đun CSS. Thay vào đó, chúng tôi cải thiện trải nghiệm người dùng bằng cách giảm nguy cơ bố cục bị hỏng. Trang web với các trình tải được cấu hình để chấp nhận các mô -đun CSS không gây ra bất kỳ vấn đề nào, vì vậy tôi sẽ đưa nó lên mà không do dự.

Nếu bạn đã thử các mô -đun CSS, tôi muốn nghe những trải nghiệm của bạn!

Thảo luận về tin tức tin tức