Tạo kiểu bằng CSS

Các ứng dụng Blockly được tạo từ các phần tử HTML và SVG. Các phần tử này được gắn nhãn bằng các lớp CSS xác định những gì chúng đại diện (ví dụ: blocklyBlock, blocklyField) cũng như trạng thái của chúng (ví dụ: blocklyEditing, blocklySelected). Blockly cũng cung cấp một bộ quy tắc CSS mặc định.

Bạn có thể dùng CSS để tạo kiểu cho ứng dụng:

  • Ghi đè các quy tắc CSS của Blockly bằng các quy tắc của riêng bạn.
  • Thêm các lớp CSS của riêng bạn vào các thành phần Blockly để có thêm độ đặc hiệu.
  • Sử dụng các quy tắc và lớp CSS để tạo kiểu cho các thành phần tuỳ chỉnh.

Lớp CSS

Các ứng dụng Blockly sử dụng các lớp CSS để xác định những phần tử cần được tạo kiểu. Điều này mang lại khả năng kiểm soát chi tiết hơn so với bộ chọn kiểu (phần tử).

Các lớp CSS của Blockly

Blockly sử dụng các lớp CSS để cung cấp những loại thông tin sau đây về các phần tử HTML và SVG mà nó sử dụng.

  • Loại. Hầu hết các lớp CSS của Blockly đều xác định những gì mà một phần tử đại diện. Ví dụ: phần tử gốc của một khối được gắn nhãn blocklyBlock. Một số phần tử được gắn nhãn bằng nhiều lớp, mỗi lớp cụ thể hơn lớp trước. Ví dụ: phần tử gốc của một trường nhập văn bản được gắn nhãn blocklyField, blocklyInputFieldblocklyTextInputField. Các lớp kiểu vẫn giữ nguyên trong suốt vòng đời của một thành phần.

  • Tiểu bang. Blockly cũng sử dụng các lớp CSS để chỉ định trạng thái của một thành phần. Ví dụ: khi con trỏ ở trên một trường nhập văn bản, phần tử gốc của trường này sẽ được gắn nhãn bằng lớp blocklyEditing. Khi con trỏ di chuyển ra xa, lớp này sẽ bị xoá.

  • Thông tin bổ sung. Blockly sử dụng một số lớp CSS để cung cấp thông tin bổ sung. Ví dụ: quá trình chèn <div> có các lớp cung cấp tên của trình kết xuất và giao diện hiện tại của không gian làm việc. Các lớp này thường vẫn giữ nguyên trong suốt thời gian hoạt động của ứng dụng.

Cách dễ nhất để khám phá những lớp CSS mà Blockly sử dụng là mở công cụ dành cho nhà phát triển của trình duyệt và kiểm tra các phần tử mà ứng dụng của bạn sử dụng.

Lớp CSS tuỳ chỉnh

Bạn có thể sử dụng các lớp CSS tuỳ chỉnh để cung cấp thông tin cụ thể hơn cho các thành phần Blockly.

Không gian làm việc

Để thêm hoặc xoá một lớp CSS khỏi <div> của một không gian làm việc, hãy gọi WorkspaceSvg.addClass hoặc WorkspaceSvg.removeClass.

Hộp công cụ

Để thêm một lớp CSS vào nút hoặc nhãn trong hộp công cụ, hãy dùng khoá web-class trong định nghĩa JSON của hộp công cụ. Để biết thêm thông tin, hãy xem phần Nút và nhãn.

Để ghi đè các lớp CSS được dùng cho nhiều phần của một danh mục, hãy dùng khoá cssConfig trong định nghĩa JSON của danh mục. Nhờ đó, bạn có thể tạo kiểu cho từng danh mục. Để biết thêm thông tin, hãy xem phần CSS danh mục.

Chặn bóng

Để thêm các lớp CSS vào một khối tuỳ chỉnh, hãy truyền một chuỗi hoặc mảng chuỗi vào khoá classes.

Blockly.common.defineBlocksWithJsonArray([{
  "type": "string_length",
  "message0": 'length of %1',
  "args0": [
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "String",
    }
  ],
  "classes": "myStringLengthBlock",
  "output": "Number",
  "colour": 160,
}]);

Bạn cũng có thể thêm hoặc xoá một lớp CSS khỏi phần tử <g> của một khối bằng cách gọi BlockSvg.addClass hoặc BlockSvg.removeClass.

Trường nhãn

Để thêm hoặc xoá một lớp CSS khỏi phần tử <text> mà trường nhãn hoặc trường nhãn có thể chuyển đổi tuần tự sử dụng, hãy gọi FieldLabel.setClass. Bạn cũng có thể truyền tên lớp đến hàm khởi tạo của nhãn.

Các lớp CSS và thành phần tuỳ chỉnh

Khi tạo một thành phần tuỳ chỉnh, hãy sử dụng một trong các phương thức sau để thêm các lớp CSS tuỳ chỉnh:

  • Nếu thành phần của bạn là một lớp con của Field hoặc Icon, hãy ghi đè phương thức initView. Ví dụ:

    class MyCustomField extends Blockly.FieldTextInput {
      ...
    
      initView() {
        super.initView();
    
        // Add custom CSS class so we can style the field.
        if (this.fieldGroup_) {
          Blockly.utils.dom.addClass(this.fieldGroup_, 'myCustomField');
        }
      }
    }
    

    Để biết thêm thông tin, hãy xem phần Tuỳ chỉnh các trường bằng CSS hoặc Tạo khung hiển thị của biểu tượng.

  • Khi tạo một phần tử SVG, hãy truyền lớp của bạn đến Blockly.utils.dom.createSvgElement:

    this.svgRoot = Blockly.utils.dom.createSvgElement(Svg.G, {'class': 'myCustomComponent'});
    
  • Khi tạo một phần tử HTML, hãy sử dụng Blockly.utils.dom.addClass:

    const myDiv = document.createElement('div');
    Blockly.utils.dom.addClass(myDiv, 'myInformation');
    

Để thêm hoặc xoá các lớp sau khi tạo, hãy sử dụng Blockly.utils.dom.addClass hoặc Blockly.utils.dom.removeClass.

setMyHighlight(highlight) {
  if (highlight) {
    Blockly.utils.dom.addClass(this.svgRoot, 'myHighlight');
  } else {
    Blockly.utils.dom.removeClass(this.svgRoot, 'myHighlight');
  }
}

Nền tảng quy tắc CSS

Nếu hiểu rõ các thuộc tính tạo kiểu SVG và tầng CSS, bạn có thể bỏ qua phần này.

Các thuộc tính tạo kiểu SVG so với các thuộc tính CSS

Các phần tử SVG được tạo kiểu bằng thuộc tính tạo kiểu SVG. Bạn có thể dùng các thuộc tính này trên các phần tử SVG (còn gọi là thuộc tính trình bày) hoặc trong các quy tắc CSS. Do đó, tất cả các thao tác sau đều có cùng một chức năng.

<!-- SVG file with presentation attributes. -->
<circle fill="red" ... />
<!-- SVG file with <style> tag. -->
<style>
  circle {fill:red;}
</style>
<circle ... />
/* External CSS file.*/
circle {fill:red;}
<!-- SVG file with inline style. -->
<circle style="fill:red;" ... />

Danh sách các thuộc tính tạo kiểu SVG có liên quan nhưng khác với danh sách các thuộc tính CSS:

  • Cùng một khái niệm, cùng một tên. Ví dụ: cả SVG và CSS đều sử dụng direction để chỉ định xem văn bản là LTR hay RTL.
  • Cùng một khái niệm, nhưng tên gọi khác. Ví dụ: SVG sử dụng fill để chỉ định màu tô; CSS sử dụng background-color.
  • Chỉ CSS. CSS có nhiều thuộc tính không có trong SVG, chẳng hạn như marginpadding.
  • Chỉ SVG. SVG có một số thuộc tính không có trong CSS, chẳng hạn như xy.

Do đó, nếu bạn đang tạo kiểu cho một phần tử SVG, hãy sử dụng các thuộc tính tạo kiểu SVG. Nếu bạn đang tạo kiểu cho một phần tử HTML, hãy sử dụng các thuộc tính CSS.

CSS cascade

CSS cascade (CSS xếp tầng) xác định mức độ ưu tiên của các quy tắc CSS. Mức độ ưu tiên này xác định quy tắc nào sẽ được sử dụng nếu có nhiều quy tắc áp dụng cho một thuộc tính và phần tử nhất định. Tệp CSS đơn giản hoá sau đây bao gồm những phần thường được Blockly sử dụng nhất và có thể giúp bạn giải quyết câu hỏi "Tại sao CSS của tôi không hoạt động?"

Thác nước đơn giản

Để xác định quy tắc nào áp dụng cho một phần tử và thuộc tính cụ thể, hãy làm theo các bước sau và dừng lại khi chỉ còn một quy tắc:

  1. Thu thập tất cả các quy tắc áp dụng cho tài sản và phần tử.
  2. Nếu có quy tắc nào có chú thích !important, hãy loại bỏ tất cả các quy tắc không có chú thích !important.
  3. Chọn các quy tắc có tính cụ thể cao nhất.

    • Thuộc tính trình bày SVG có độ đặc hiệu bằng 0.
    • Các quy tắc trong thẻ <style> hoặc biểu định kiểu bên ngoài sẽ được tính toán độ đặc hiệu một cách bình thường.
    • Kiểu nội dòng (kiểu do thuộc tính style đặt) có độ đặc hiệu cao hơn bất kỳ bộ chọn nào.
  4. Chọn quy tắc xuất hiện cuối cùng trong tài liệu.

  5. Nếu không có quy tắc nào áp dụng, hãy kế thừa giá trị của thuộc tính từ phần tử mẹ của phần tử.

Thuật toán này không xem xét các phần sau của thác:

  • Thuộc tính transition có mức độ ưu tiên cao nhất. Blockly sử dụng một số thành phần trong số này.
  • Quy tắc @media. Blockly sử dụng một trong những cách này.
  • Các quy tắc do trình duyệt hoặc người dùng chỉ định.
  • Các quy tắc @scope@layer cũng như thuộc tính animation không được Blockly sử dụng.

Quy tắc CSS

Các quy tắc CSS chỉ định cách tạo kiểu cho ứng dụng của bạn. Blockly cung cấp một bộ quy tắc mặc định mà bạn có thể thay thế bằng các quy tắc của riêng mình.

Quy tắc CSS của Blockly

Blockly cung cấp một bộ quy tắc CSS mặc định. Cách thức và vị trí thêm các quy tắc này sẽ ảnh hưởng đến mức độ ưu tiên của chúng.

Thẻ kiểu

Phần lớn các quy tắc CSS của Blockly được chỉ định trong 2 thẻ <style>. Vì các thẻ này xuất hiện gần đầu trang, nên các quy tắc trong thẻ có mức độ ưu tiên thấp hơn so với các quy tắc có cùng độ cụ thể xuất hiện sau trong trang.

Quy tắc Blockly.css.register

Khi được chèn, Blockly sẽ thêm thẻ <style> làm thẻ con của thẻ <head>. Các quy tắc trong thẻ này là từ:

  • Vùng chứa tên Blockly.css. Để xem các quy tắc này, hãy mở core/css.ts và tìm let content.
  • Các thành phần riêng lẻ, gọi Blockly.css.register để thêm các quy tắc CSS dành riêng cho thành phần. Vì css.register thêm các quy tắc này vào cuối chuỗi content, nên các quy tắc này có mức độ ưu tiên cao hơn các quy tắc có độ cụ thể tương tự đã được thêm trước đó. Để xem các quy tắc này, hãy xem các lệnh gọi đến Blockly.css.register.

Nếu bạn không muốn sử dụng các quy tắc này, hãy đặt lựa chọn cấu hình css thành false. Trong trường hợp này, bạn có trách nhiệm cung cấp một bộ quy tắc CSS thay thế.

Quy tắc của trình kết xuất

Khi được khởi tạo, trình kết xuất sẽ thêm thẻ <style> chứa các quy tắc CSS dành riêng cho trình kết xuất làm phần tử con của thẻ <head>. Xin lưu ý rằng các quy tắc này luôn được thêm vào và không chịu ảnh hưởng của lựa chọn cấu hình css. Để xem các quy tắc này, hãy tìm phương thức getCss_ trong trình kết xuất.

Kiểu cùng dòng

Kiểu nội tuyến được chỉ định bằng thuộc tính style và thường được tạo khi DOM cho một thành phần được tạo. Để xem danh sách một phần, hãy xem truy vấn này trên GitHub.

Kiểu nội tuyến áp dụng trực tiếp cho phần tử mà chúng xuất hiện và có độ cụ thể cao hơn bất kỳ bộ chọn nào. Vì lý do này, việc ghi đè các thành phần này thường yêu cầu bạn sử dụng chú thích !important.

Thuộc tính trình bày SVG

Thuộc tính trình bày SVG là các thuộc tính tạo kiểu SVG được dùng làm thuộc tính của các phần tử SVG. Chúng có độ đặc hiệu bằng 0 và không thể chứa chú thích !important, vì vậy, chúng có mức độ ưu tiên thấp nhất trong tất cả các quy tắc của Blockly. Blockly thường tạo các khối này trong lệnh gọi đến createSvgElement.

Thêm quy tắc CSS của riêng bạn

Bạn có thể thêm các quy tắc CSS của riêng mình bằng các phương thức tương tự như Blockly:

  • Gọi Blockly.css.register trước khi chèn Blockly. Các quy tắc của bạn sẽ được thêm sau các quy tắc của Blockly và có mức độ ưu tiên cao hơn các quy tắc của Blockly có cùng độ cụ thể.
  • Thêm thẻ <style> hoặc liên kết đến một biểu định kiểu bên ngoài dưới dạng thành phần con sau này của thẻ <head>. Vì Blockly thêm các quy tắc của mình làm hai phần tử con đầu tiên của thẻ <head>, nên các quy tắc của bạn sẽ có mức độ ưu tiên cao hơn các quy tắc của Blockly có cùng độ đặc hiệu.
  • Sử dụng kiểu nội tuyến để thêm kiểu vào các phần tử trong một thành phần tuỳ chỉnh. Các quy tắc này sẽ có độ cụ thể cao hơn bất kỳ quy tắc nào có bộ chọn.
  • Sử dụng các thuộc tính trình bày trên các phần tử SVG trong một thành phần tuỳ chỉnh. Các quy tắc này sẽ có độ cụ thể thấp hơn so với mọi quy tắc có bộ chọn.

Khắc phục sự cố

Nếu CSS của bạn không hoạt động, thì có thể là do một số nguyên nhân sau:

  • Bạn đang sử dụng các thuộc tính CSS trên một phần tử SVG hoặc các thuộc tính tạo kiểu SVG trên một phần tử HTML. Xem các thuộc tính tạo kiểu SVG so với các thuộc tính CSS.

  • Quy tắc của bạn có mức độ ưu tiên thấp hơn một quy tắc khác. Điều này thường là do độ đặc hiệu thấp hơn. Sau đây là những cách có thể giúp bạn khắc phục vấn đề này:

    • Sử dụng bộ chọn lớp thay vì bộ chọn kiểu (phần tử).
    • Sử dụng nhiều bộ chọn.
    • Nếu có thể, hãy thêm một lớp tuỳ chỉnh vào phần tử đích và sử dụng lớp này trong quy tắc của bạn.
    • Nếu không còn cách nào khác, hãy thêm chú thích !important vào quy tắc của bạn. Đây là lựa chọn duy nhất của bạn nếu một quy tắc cạnh tranh được chỉ định bằng cách sử dụng kiểu nội tuyến (thuộc tính style).
  • Quy tắc của bạn có độ đặc hiệu giống như một quy tắc khác, nhưng xuất hiện sớm hơn trong trang. Nếu không thể tăng độ cụ thể của quy tắc, hãy di chuyển quy tắc đó xuống dưới trong trang.

Có hai loại quy tắc CSS mà bạn không thể ghi đè:

  • Các thuộc tính được đặt trong quy tắc transition.
  • Quy tắc !important do trình duyệt chỉ định.