Hiểu trọng lượng của bộ chọn CSS. Bí mật tồi tệ nhất. Tại sao điều này là cần thiết?

Tại sử dụng CSS Rất thường xuyên, bạn có thể quan sát thấy tình huống trong đó các kiểu được chỉ định vì lý do nào đó không hoạt động, mặc dù mọi thứ đều được viết không có lỗi. Ví dụ: kích thước phông chữ, màu liên kết hoặc bất kỳ thông số nào khác của phần tử HTML không bị thay đổi. Trong trường hợp này, chúng ta chỉ có thể nói về một điều - ở đâu đó trong biểu định kiểu đã tồn tại một bộ chọn (có thể nhiều hơn một) ảnh hưởng đến phần tử này và chứa cùng một thuộc tính CSS mà bạn không muốn vận hành. Bộ chọn này do bạn tạo trước đó và có thể bạn đã quên hoặc không quên mà chỉ đơn giản là không tính đến các quy tắc ưu tiên về kiểu dáng.

Ưu tiên kiểu dáng là điều chúng ta sẽ nói đến trong hướng dẫn này, nơi bạn sẽ tìm hiểu về một số quy tắc mà trình duyệt sử dụng khi xử lý CSS của bạn. Đầu tiên, chúng ta sẽ xem xét riêng từng yếu tố ảnh hưởng đến kết quả cuối cùng, sau đó kết hợp tất cả thành một bức tranh tổng thể.

Quan trọng! Các bạn, tôi nhắc lại một lần nữa - các phép tính ưu tiên chỉ được thực hiện bởi trình duyệt trong các tình huống khi vào cùng một phần tử HTMLảnh hưởng một số Thuộc tính CSS từ bảng định kiểu của bạn, cố gắng thay đổi cùng một tham số, chẳng hạn như màu của khung hoặc văn bản. Những tài sản đó của phần tử này không bị trùng lặp, chúng chỉ đơn giản được áp dụng cho nó và thế là xong.

Ưu tiên kiểu tùy thuộc vào loại bộ chọn

Đúng, Bộ chọn CSS cũng ảnh hưởng đến mức độ ưu tiên của kiểu và không chỉ các bộ chọn đơn giản (lớp, bộ chọn thẻ, thuộc tính, v.v.) được tính đến mà còn cả các bộ chọn tổng hợp (bộ chọn con, bộ lân cận, bộ chọn con cháu, v.v.).

Để tính mức độ ưu tiên (độ đặc hiệu) của bộ chọn, trình duyệt sử dụng một thuật toán nhất định, trong đó mỗi loại được trao một số điểm nhất định, xác định trọng số của bộ chọn. Các kiểu của bộ chọn có trọng số cao nhất cuối cùng sẽ được áp dụng cho phần tử. Nếu hóa ra một số bộ chọn ảnh hưởng đến cùng một phần tử HTML sẽ gõ số tương tựđiểm, thì các thuộc tính kiểu của thuộc tính trong mã bên dưới sẽ được sử dụng.

Bây giờ hãy xem cách trình duyệt tính toán những điểm số này.

  1. Bộ chọn phổ quát- số điểm được thưởng là 0 (0).
  2. Bộ chọn thẻphần tử giả- mỗi người một (1) điểm.
  3. Bộ chọn thuộc tính, các lớp họclớp giả- mười (10) điểm cho mỗi phần.
  4. Số nhận dạng- một trăm (100) điểm cho mỗi mã định danh trong bộ chọn.
  5. Thuộc tính kiểu - kiểu tích hợp không sử dụng bộ chọn mà được chỉ định trực tiếp bên trong thẻ phần tử, nhưng đồng thời chúng có mức độ ưu tiên cao nhất, được tính bằng một nghìn (1000) điểm.

Để giúp bạn hiểu rõ hơn về cách tính điểm ảo này, đây là một số ví dụ đơn giản.

* ( ) /* 0 điểm */ em ( ) /* 1 điểm */ p::first-letter ( ) /* 2 điểm (một bộ chọn thẻ và một phần tử giả) */ p ( ) /* 11 điểm (một mỗi thẻ và bộ chọn thuộc tính) */ div.fine .one ( ) /* 21 điểm (hai lớp và một bộ chọn thẻ) */ #header a:hover ( ) /* 111 điểm (mã định danh, bộ chọn thẻ và lớp giả) */

Như bạn có thể thấy, mọi thứ khá đơn giản. Đừng sợ hãi trước khi nghĩ rằng bạn sẽ phải liên tục tính toán những điểm này khi tạo biểu định kiểu của mình. Trên thực tế, không ai từng nghĩ về họ như vậy. Thông thường mọi người chỉ nghĩ đến mức độ ưu tiên của bộ chọn khi một số kiểu không muốn hoạt động. Đây là nơi bắt đầu cuộc “khiêu vũ với tambourine” và cuộc tìm kiếm thủ phạm. :)

Một ví dụ thể hiện mức độ ưu tiên của bộ chọn

Ưu tiên của bộ chọn

Đoạn thông thường.

Ghi chú.

Kết quả trên trình duyệt

Đoạn thông thường.

Ghi chú.

Trong ví dụ này, màu văn bản ghi chú là màu đen, giống như các đoạn văn còn lại, mặc dù nó được đặt thành màu xanh lá cây và thuộc tính được sử dụng thấp hơn trong mã. Tuy nhiên, kiểu đường viền và phần đệm đã được thêm vào ghi chú. Tại sao điều này xảy ra, tôi nghĩ, là rõ ràng. Giải pháp trong tình huống này là đặt thêm mã định danh #content trước lớp ghi chú, điều này sẽ làm tăng trọng số của bộ chọn hoặc áp dụng quy tắc !important mà bạn sẽ đọc bên dưới.

Chương này giải thích chi tiết tại sao Cascading Style Sheets (CSS) được gọi là Cascading Style Sheets. Trước tiên, hãy nhớ cách bạn có thể thêm kiểu vào một trang web:

  • kết nối một bảng định kiểu bên ngoài;
  • thêm biểu định kiểu nội bộ vào tài liệu HTML thông qua thẻ. Kết quả là màu sắc của thẻ

    Nó sẽ có màu đỏ.

    Đây là một cách để kiểm soát tầm quan trọng của phong cách. Một cách khác để tăng mức độ ưu tiên là tăng trọng lượng của bộ chọn một cách cụ thể, chẳng hạn bằng cách thêm ID hoặc lớp vào nó.

    Thông báo!quan trọng

    Nếu bạn gặp phải khẩn cấp và bạn cần tăng tầm quan trọng của một thuộc tính, bạn có thể thêm một khai báo!important vào nó:

    P (màu: đỏ !quan trọng;) p (màu: xanh lá cây;)

    Ngoài ra!quan trọng sẽ ghi đè các kiểu nội tuyến. Nhiều nhà phát triển không khuyến khích việc sử dụng!important quá thường xuyên. Hầu hết, thông báo này Theo thông lệ, chỉ sử dụng nó khi xung đột về phong cách không thể khắc phục được bằng các biện pháp khác.

    Đặt lại kiểu bằng reset.css

    Trong chương trước, chúng tôi đã đề cập rằng mỗi trình duyệt đều có các kiểu tài liệu HTML tích hợp riêng được thiết kế để cải thiện khả năng đọc. Có thể bạn đã từng thấy một trang web trần trụi trông như thế nào trong trình duyệt: các liên kết được gạch chân màu xanh lam, phông chữ màu đen, tiêu đề in đậm, v.v.

    Mỗi trình duyệt có sự khác biệt riêng về kiểu dáng tích hợp: ví dụ: IE không có thụt lề từ cạnh trên của cửa sổ, nhưng Firefox thì có. Có rất nhiều sự khác biệt như vậy. Để chúng không ảnh hưởng đến khả năng tương thích giữa nhiều trình duyệt khi bạn viết Kiểu CSS, bạn có thể sử dụng phương pháp đặt lại kiểu dựng sẵn.

    Công cụ reset style về cơ bản là giống nhau bảng CSS, mô tả các quy tắc đặt lại kiểu tích hợp của trình duyệt về giá trị thuộc tính mặc định. Bảng này được gọi là reset.css và được sử dụng để bạn có thể bắt đầu tạo kiểu từ đầu. Đây là một ví dụ bảng tiêu chuẩn cài lại:

    Html, nội dung, div, span, applet, đối tượng, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, từ viết tắt, địa chỉ, lớn, trích dẫn, mã, del, dfn, em, img, ins, kbd, q, s, samp, nhỏ, đình công, mạnh mẽ, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, hình thức, nhãn, huyền thoại, bàn, Chú thích, tbody, tfoot, thead, tr, th, td, bài báo, sang một bên, Tranh sơn dầu, chi tiết, Nhúng, nhân vật, Figcaption, Chân trang, Tiêu đề, hgroup, menu, Nav, Đầu ra, Ruby, phần, tóm tắt, thời gian, dấu, âm thanh, video ( lề: 0; đệm: 0; viền: 0; cỡ chữ: 100%; phông chữ: kế thừa; căn chỉnh dọc: đường cơ sở; ) /* Đặt lại vai trò hiển thị HTML5 cho các trình duyệt cũ hơn */ bài viết, sang một bên, chi tiết, figcaption, hình, chân trang, tiêu đề, hgroup, menu, điều hướng, phần ( display: block; ) body ( line-height: 1; ) ol, ul ( list-style: none; ) blockquote, q ( dấu ngoặc kép: không có; ) blockquote:trước, blockquote:after, q:trước, q:after ( nội dung: ""; nội dung: không có; ) bảng ( border-collapse: thu gọn; khoảng cách đường viền: 0; )

    Giả sử bạn có một số bộ chọn tham chiếu đến cùng một phần tử:

    Khai mạc trang HTML phần tử ở đâu nhịp nằm bên trong phần tử div chúng ta sẽ thấy đoạn văn bản được gạch chân. Và nếu chúng ta tiến xa hơn và sử dụng plugin con bọ lửa Hãy nhìn vào style của phần tử lồng nhau, chúng ta sẽ thấy như sau:

    Khoảng Div ( văn bản-trang trí: gạch dưới; ) khoảng ( văn bản trang trí: không có; )

    Câu hỏi ngay lập tức được đặt ra về lý do của hành vi này. Cuối cùng, bộ chọn thứ hai phải chồng lên bộ chọn thứ nhất, dựa trên các kiểu xếp tầng. Ví dụ này cho thấy rõ tính đặc hiệu của bộ chọn là gì.

    Quy tắc cụ thể

    Tính đặc hiệu của bộ chọn xác định mức độ ưu tiên của chúng trong biểu định kiểu. Bộ chọn càng cụ thể thì mức độ ưu tiên của nó càng cao.

    Đặc tả CSS 2.1 dành một phần nhỏ cho chủ đề này. Có 4 quy tắc để tính độ đặc hiệu của bộ chọn:

    1. Thuộc tính có mức độ ưu tiên cao nhất phong cách. Quy tắc này ghi đè tất cả các bộ chọn được mô tả trong style.
    2. Vị trí thứ hai thuộc về sự hiện diện NHẬN DẠNG trong bộ chọn (#some-id).
    3. Tiếp theo là tất cả các thuộc tính (bao gồm cả thuộc tính lớp học) và các lớp giả trong bộ chọn.
    4. Bộ chọn có tên phần tử và phần tử giả có mức độ ưu tiên thấp nhất.

    Tất cả 4 quy tắc được kết hợp thành một hệ thống A B C D(nơi một - mức ưu tiên cao nhất) và tính đặc hiệu của hình thức.

    Bộ chọnTính đặc hiệu a-b-c-dQuy tắc không.
    * 0-0-0-0 -
    0-0-0-1 4
    li:dòng đầu tiên0-0-0-2 4
    ulli0-0-0-2 4
    ul ol+li0-0-0-3 4
    biểu mẫu + *0-0-1-1 3, 4
    bảng tr td.second0-0-1-3 3, 4
    h2.block.title.0-0-2-1 3, 4
    #XYZ0-1-0-0 2
    phong cách=" "1-0-0-0 1

    Ví dụ về tính đặc hiệu - quy tắc số 1:

    nội dung

    Văn bản bên trong phần tử P sẽ được hiển thị màu xanh lam bất kể bộ chọn có id (id), trong đó thuộc tính cũng được chỉ định màu sắc có ý nghĩa màu đỏ. Quy tắc số 1 luôn ghi đè tất cả các bộ chọn và có mức độ ưu tiên cao nhất.

    Quy tắc số 2:

    • Đầu tiên
    • thứ hai

    Mặc dù bộ chọn là nhận dạngđược biểu thị trong các kiểu ở trên cùng, chính điều này sẽ ảnh hưởng đến việc hiển thị tài liệu, vì nó cụ thể hơn bộ chọn có một lớp thứ hai.

    Quy tắc số 3:

    Văn bản bên trong trường nhập sẽ được in đậm và bộ chọn thứ hai sẽ chỉ tạo kiểu cho nút gửi yêu cầu.

    Hãy quay lại ví dụ đầu tiên của bài viết này - quy tắc số 4:

    div span ( văn bản-trang trí: gạch dưới; ) khoảng ( văn bản-trang trí: không có; )

    Bộ chọn đầu tiên đánh bại bộ chọn thứ hai vì nó bao gồm 2 quy tắc cụ thể cuối cùng, trong khi bộ chọn thứ hai chỉ có một quy tắc. Để loại bỏ trang trí văn bản trong trong trường hợp này bạn nên sử dụng một lớp hoặc một bộ chọn cụ thể hơn:

    Khoảng Div ( text-trang trí: gạch chân; ) khoảng nội dung ( text-trang trí:none; )

    Bộ chọn hiện có trọng số bằng nhau (0-0-0-2 = 0-0-0-2) về độ đặc hiệu. Bộ chọn thứ hai sẽ chỉ ghi đè thuộc tính của bộ chọn thứ nhất như được mô tả bên dưới.

    Tôi chắc chắn rằng hầu hết các nhà thiết kế bố cục đều biết chính xác 2 quy tắc đầu tiên về tính đặc hiệu của bộ chọn về nhận dạngphong cách và bài viết này không phải là điều gì mới mẻ đối với họ. Nhưng đừng quên hai điều còn lại, vì điều này có thể làm chậm đáng kể quá trình tạo bố cục và tăng thời gian xác định lỗi.

    Đó là tất cả những gì tôi muốn nói đến. Tôi hy vọng bạn thấy bài viết thú vị.

    --
    Dao cạo Vladislav Chapyuk, tháng 4 năm 2009

    TRONG dự án lớn khi lớn lên CSS các tập tin, tình hình không được vui cho lắm. Bởi vì số lượng lớn quy tắc, việc xác định kiểu nào sẽ được áp dụng cho một phần tử cụ thể sẽ trở nên khó khăn. Một số kiểu được kế thừa, một số kiểu khác được xác định thông qua toàn bộ chuỗi các bộ chọn khác nhau và được sử dụng ở đâu đó .lớp học, một vài nơi #nhận dạng, và ở đâu đó nói chung kiểu nội tuyến.

    Để thay đổi kiểu cho một phần tử, chúng ta phải thử nghiệm với các trọng số của bộ chọn. Để làm cho công việc của chúng tôi dễ dàng hơn, chúng tôi có thể làm theo một số nguyên tắc:

    1. Không bao giờ sử dụng NHẬN DẠNG bộ chọn trong CSS. Họ không có lợi thế hơn lớp học.
      • Mọi thứ bạn có thể làm với NHẬN DẠNG, có thể được thực hiện với lớp học.
      • NHẬN DẠNG không thể tái sử dụng được.
      • Cân nặng NHẬN DẠNG rất lớn. Ngắt NHẬN DẠNG thậm chí không có một trăm dây chuyền các lớp học.
    2. Đừng tạo các bộ chọn không cần thiết. Nếu như .header-nav() hoạt động tốt, sau đó không sử dụng định nghĩa .header .header-nav(). Trong trường hợp này, sẽ không có gì thay đổi và sẽ không có lợi ích gì từ nó.
    3. Đừng tạo các bộ chọn cụ thể cho đến khi bạn thực sự cần. Nếu như .nav() có tác dụng thì đừng dùng ul.nav(). Ký hiệu như vậy sẽ chỉ làm giảm các tùy chọn sử dụng lớp này. .nav và cũng sẽ làm tăng trọng lượng của bộ chọn mà không mang lại lợi ích rõ ràng.
    4. Buộc bản thân phải sử dụng .lớp học, bởi vì đây là những bộ chọn lý tưởng.

    Không bao giờ sử dụng bộ chọn nặng hơn mức cần thiết.

    Tất cả đều rất quy tắc đơn giản và theo dõi họ không quá khó khăn.

    giảm trọng lượng ID

    Giả sử bạn có một tiện ích trên trang của mình và bạn muốn tạo kiểu cho nó:

    ...

    Và, ví dụ, chúng ta không thể thay đổi HTML mã widget để loại bỏ NHẬN DẠNG. Vì vậy, chúng tôi làm điều này:

    #tiện ích ( ... )

    Kết quả là chúng ta có định nghĩa cho NHẬN DẠNG V. CSS tập tin, điều này không tốt chút nào. Thay vào đó chúng ta có thể làm như sau:

    { ... }

    Đây là một bộ chọn thuộc tính. Trong trường hợp này, đây không còn là định nghĩa cho NHẬN DẠNG, và cho phần tử. Nói chính xác hơn, bộ chọn đang nói: “Này, hãy tìm cho tôi một phần tử có thuộc tính nhận dạng có ý nghĩa tiện ích».

    Cái hay của phương pháp này là chúng ta đã giảm được trọng lượng NHẬN DẠNG lên đến trọng lượng lớp. Nhưng đây là một hack.

    Tăng cân an toàn

    Chúng ta có thể tăng trọng số của bộ chọn như thế này:

    Btn.btn.btn.btn ( ... )

    Nhưng tôi hy vọng rằng tôi sẽ không bao giờ phải sử dụng cách ghi âm như vậy trong các dự án.

    Ở đây chúng ta thấy rằng màu được chỉ định trong .box a(), ghi đè màu của văn bản nút. Kết quả là văn bản sẽ hợp nhất với nền của nút.

    Tất nhiên chúng ta có thể khắc phục điều này nếu chúng ta đặt !quan trọng(jsfiddle.net/csswizardry/3N53n/1) nhưng không, cảm ơn, hãy loại bỏ điều đó!

    Chúng ta có thể thêm một bộ chọn bổ sung vào phần .btn()(dòng 23) jsfiddle.net/csswizardry/3N53n/2 , nhưng đây không phải là nhiều nhất Quyết định tốt nhất. Điều gì sẽ xảy ra nếu vấn đề với nút không chỉ .hộp, và bất cứ nơi nào khác? Thêm một bộ chọn mới mỗi lần là một lựa chọn tồi.

    Vì vậy chúng tôi sẽ nhân đôi .btn.btn: http://jsfiddle.net/csswizardry/3N53n/3

    Đây cũng không phải là giải pháp tốt nhất, nhưng chúng tôi vẫn tăng trọng lượng của bộ chọn và màu sắc trên nút bây giờ vẫn như cũ.

    Bây giờ chúng ta đã biết 2 cách để thay đổi trọng số của bộ chọn, nhưng hãy nhớ rằng đây vẫn là những cách hack và bạn không nên quá lo lắng về chúng.