12/08/2018, 13:54

Lợi dụng từ CSS tạo ra nội dung và bộ đếm

Generated content đầu tiền được giới thiệu trong đặc điểm của CSS2. Nhiều năm qua, tính năng này được sử dụng bởi một số tác giả Web do trình duyệt hỗ trợ phù hợp. Với IE8 trong năm 2009, Generated content được phát hiện và một số thực hiện thú vị được áp dụng lần đầu. Trong bài này sẽ giới thiệu ...

Generated content đầu tiền được giới thiệu trong đặc điểm của CSS2. Nhiều năm qua, tính năng này được sử dụng bởi một số tác giả Web do trình duyệt hỗ trợ phù hợp. Với IE8 trong năm 2009, Generated content được phát hiện và một số thực hiện thú vị được áp dụng lần đầu. Trong bài này sẽ giới thiệu một số sử dụng có thể của generated content.

1. Thế nào là generated content?

Trong từ kỹ thuật, generated content là một trừu tượng thông thường tạo bởi CSS trong cây document. Trong thực tế, generated content chỉ tồn tạo trong layout của Web document.

Generated content có thể truy cập qua JavaScript bằng đọc textual value của thuộc tính content.

var test = document.querySelector("#test");
var result = getComputedStyle(test, ":before").content;
var output = document.querySelector("#output");
outpu.innerHTML = result;
  • Xem ví dụ

2. Chèn generated content

Generated content có thể chèn trước hoặc sau nội dung thật của một element, sử dụng :before và :after pseudo-elements tương tự. Để thể hiện pseudo-elements chúng ta có thể dùng pseudo-markup sau.

<p>
    <before>Start</before>
        Actual content
    <after>End</after>
</p>

và CSS sẽ là:

p:before {
   content: "Start";
}

p:after {
   content: "End";
}
  • Xem ví dụ

Chú ý rằng nếu bạn validate CSS file với đặc điểm của CSS3, :before và :after pseudo-elements được viết thành ::before và ::after. Còn không thì CSS validator sẽ bảo lỗi.

Như đã thấy thuộc tính chèn hai string là content. Thuộc tính này chập nhận các giá trị sau:

  • none, normal pseudo-content không được sinh ra.
  • <string> sẽ là một texual string đóng trong ngoặc kép
  • url() function này cho chúng ta có thể chèn nguồn ngoài (thường là ảnh) với thuộc tính background-image.
  • counter(), counters() các function chèn bộ đếm.
  • attr(attribute) function này cho phép chèn giá trị của thuộc tính attribute của một element cho trước.
  • opent-quote, close-quote, no-open-quote, no-close-quote các giá trị này tự động sinh các dấu ngoặc kép.

Chú ý rằng generated content chiếm khoảng trống trên page và sự hiện diện của nó ảnh hưởng đến tính toán của trình duyệt của element cha.

3. Chèn các string

Trong ví dụ trước, chúng ta chèn thêm hai string thường trước và sau nội dung thật của element. Generated content cũng cho phép chúng ta chèn thêm các ký hiệu phức tạp hơn thông qua thoát:

p:before {
   content: "0A7";
   padding-right: 0.2em;
}
  • Xem ví dụ

Dãy thoát giữa ngoặc kép là giá trị Unicode thập lục phân của ký hiệu đoạn văn. Chúng ta có thể kết hợp string thường với ký hiệu Unicode:

p:before {
   content: "( " "0A7" " )";
   padding-right: 0.2em;
}
  • Xem ví dụ

Chú ý tất cả textual content bên trong thuộc tính content được coi là chữ. Vậy các khoảng cách trống và tabs chèn qua bàn phím cũng được chèn vào page.

4. Chèn các Icon sử dụng Web Fonts

Web Fonts có thể dùng để chèn các graphical icon qua generated content. Dựa vào Web font family, bạn có thể chèn cả các chữ bình thường hoặc các dãy Unicode:

@import url(http://weloveiconfonts.com/api/?family=brandico);

p:before {
   content: "f303";
   padding-right: 0.3em;
   font-family: 'brandico', sans-serif;
   font-size: 22px;
}
  • Xem ví dụ

Trong ví dụ này chúng ta chèn một icon Twitter. Code có thể viết lại như sau:

.icon-twitter:before {
   content: "f303";
   padding-right: 0.3em;
   font-family: 'brandico', sans-serif;
   font-size: 22px;
}
  • Xem ví dụ

5. Chèn các ảnh

Chúng ta có thể chèn các ảnh quả function url()

a:before {
   content: url(link.png);
   padding-right: 0.2em;
}

Như đã thầy function này có cú pháp giốn thuộc tính background-image.

6. Chèn các giá trị của thuộc tính

Một giá trị thuộc tính của một element có thể chèn qua function attr().

a[href]:after {
   content: "( " attr(href) " )";
   padding-left: 0.2em;
   color: #000;
   font: small "Courier New", Courier, monospace;
}
  • Xem ví dụ

Chúng ta vừa chèn giá trị của thuộc tính href đó là văn bản string đơn giản.

7. Chèn Counters

Tự động đánh số của CSS được quản lý bởi hại thuộc tính đó là counter-reset và counter-increment. Counters được định nghĩa bởi các thuộc tính này sau đó sử dụng với các function counter() và counters() của thuộc tính content.

Thuộc tính counter-reset có thể chứa một hoặc nhiều tên của các counters(ví dụ "identifiers") tùy chọn kèm theo một số nguyên. Số nguyên xét giá trị mà sẽ tăng bởi thuộc tính counter-increment với bấy kỳ sự tồn tại của element cho trước. Giá trị mặc định là 0. Các giá trị âm được phép dùng.

Thuộc tính counter-increment là giống nhau. Điểm khác nhau cơ bản là cái này tăng một counter. Mặc định tăng là 1, giá trị âm được cho phép.

Theo dõi ví sau:

<dl>
   <dt>term</dt>
   <dd>description</dd>
   <dt>term</dt>
   <dd>description</dd>
   <dt>term</dt>
   <dd>description</dd>
</dl>

Chúng ta muốn đánh số (1,2,3, vv..) cho mỗi thẻ (dt) trong danh sách.

dl {
   counter-reset: term;
}
dt:before {
   counter-increment: term;
   content: counter(term);
}
  • Xem ví dụ

Nguyên tắc thứ nhất đặt một counter cho định nghĩa danh sách. Cái này gọi là một scope. Tên (định danh) của counter là term. Bất cứ điều gì tên chúng ta chọn cho counter phải trùng với một trong các thuộc tính counter-increment.

Nguyên tắc thứ hai chúng ta đính kèm :before pseudo-element cho dt element, bởi vì chúng ta muốn chèn counter chính xác trước nội dung thật của element. Nếu chúng ta xem kỹ với khái báo thứ 2 function counter() chập nhận định danh (term) là đối số của nó và thuộc tính content sinh ra counter.

dt:before {
   content: counter(term) ". ";
}
  • Xem ví dụ

Chú ý string ở giữa dấu ngoặc kép được coi là chữ do vậy khoảng cách trống cũng được chèn vào như chúng ta nhập từ bàn phím. Trong thực tế thuộc tính content có thể coi là đối tác CSS của phương thức JavaScript document.write() trừ khi không thêm nội dung thực vào document. Đơn giản thuộc tính content tạo ra một khái niệm trừu tượng chỉ trong cây document nhưng không sửa đổi nó.

Trong trường hợp nghi ngờ, chúng ta có thêm style cho counter bằng áp dụng các thuộc tính khác để đính kèm pseudo-element. Ví dụ

dt:before {
   content: counter(term);
   padding: 1px 2px;
   margin-right: 0.2em;
   background: #ffc;
   color: #000;
   border: 1px solid #999;
   font-weight: bold;
}
  • Xem ví dụ

Chúng ta vừa đặt background-color, thêm padding và right margin, kiểu font đậm và viên ngoài cho các counter với viên giới liên mỏng.

Hơn nữa các counter có thể âm. Để giải quyết các counter âm, chúng ta cần thêm phương pháp toán-đặt tên, cộng trừ số âm và dương. Ví dụ nếu chúng ta cần tiến hành đánh số bắt đầu từ 0, chúng ta có thể viết:

dl {
   counter-reset: term -1;
}
dt:before {
   counter-increment: term;
   content: counter(term) ". ";
}
  • Xem ví dụ

Bằng cách đặt thuộc tính counter-reset về 1 và tăng nó 1, giá trị của kết quả ra 0 và việc đánh dấu sẽ bắt đầu từ số đó. Các counter âm có thê kết hợp với các counter dương để có hiệu ứng thú vị. Xem xét ví dụ sau:

  • Xem ví dụ

Như đã thấy, cộng trừ số âm và dương mang lại một loạt các kết hợp giữa các counter. Chỉ với một cách tính toán đơn giản chúng ta có thể điều khiển hoàn toàn tự động đánh số.

Một tính năng thú vị của quầy CSS nằm trong khả năng của các counter đó là lồng nhau. Trong thực tế, số cũng có thể được sắp xếp theo các cấp dưới tiến bộ, chẳng hạn như 1.1, 1.1.1, 2.1 và vv.. Để thêm một cấp phụ đến các yếu tố trong danh sách, có thể viết như sau:

dl {
   counter-reset: term definition;
}
dt:before {
   counter-increment: term;
   content: counter(term) ". ";
}
dd:before {
   counter-increment: definition;
   content: counter(term) "." counter(definition) " ";
}
  • Xem ví dụ

Ví dụ này là tương tự như ví dụ đầu tiên, nhưng trong trường hợp này có hai counter, term và định nghĩa. Scope của cả hai counter được thiết lập bởi các quy tắc đầu tiên và "sống" trong các element dl. Nguyên tắc thứ hai chèn counter đầu tiên trước mỗi định danh định nghĩa trong danh sách. Quy tắc này không phải là đặc biệt thú vị bởi vì hiệu quả của nó đã biết. Thay vào đó, quy tắc này là lõi cho mã bởi vì nó như sau:

  • Tăng counter thứ hai (định nghĩa) trên các element dd;
  • Chèn counter đầu tiên (định danh), sau một khoảng thời gian;
  • Chèn counter thứ hai (định nghĩa), sau một không trống. Lưu ý rằng các bước 2 và 3 đều được thực hiện bởi các thuộc tính content sử dụng :before pseudo-element gắn vào các định nghĩa của định danh.

8. Điểm thúc vị khác của các counter "self-nested"

Theo nghĩa là đặt một counter vào phần tử con (hoặc pseudo-element) sẽ tự động tạo một biến mới của counter. Việc này rất có ích trong trường hợp của các danh sách (X)HTML mà các phần tử có thể lồng vào nhau với độ sâu tùy ý. Tuy nhiên quy định cụ thể một counter cho mỗi danh sách không phải lúc nào cũng có thể vfi nó có thể tạo ra mã dư thừa. Vì lý do này function counters() rất có ích, với function này tạo một string chứa tất cả các counter với tên giống nhau mà đã cho trước trong scope. Các counter sau đó được tách bởi một string. Xem ví dụ sau:

<ol>
   <li>item</li>
   <li>item
      <ol>
         <li>item</li>
         <li>item</li>
         <li>item
            <ol>
               <li>item</li>
               <li>item</li>
            </ol>
         </li>
      </ol>
   </li>
</ol>

CSS sau đây sẽ đánh số danh sách lồng các mục 1, 1.1, 1.1.1, etc.

ol {
   counter-reset: item;
   list-style: none;
}
li {
   display: block;
}
li:before {
   counter-increment: item;
   content: counters(item, ".") " ";
}
  • Xem ví dụ

Chúng ta chỉ có mục counter cho mỗi cập lồng. Thay vì viết ba counter khác nhau (như item1, item2, item3) và tạo 3 scope cho mỗi element ol, chúng ta có thể dựa vào function counters() để đặt được mục tiêu này. Quý tắc thứ hai là quan trọng và đáng giải thích thêm. Bởi vì danh sách có thứ dấu mặc định chúng ta sẽ bỏ bằng cho danh sách vào các element block có cập bậc. Chỉ với element có display: list-items mới có dấu.

Bây giờ chúng ta xem xét quy tắc thứ ba mà hoạt động hiệu quả. Khái báo đầu tiền tăng counter trước đặt trên danh sách ngoài cùng. Tiếp đến với khai báo thứ hai, function counters tạo các counter tức thời cho danh sách trong cùng. Cấu trúc của chức năng này như sau:

  • Đối số đầu tiền là tên của counter cho trước, ngày lập tức có dấu phải kèm sau.

  • Đối số thứ hai là một khoảng thời gian giữa hai dấu ngoặc kép.

Chú ý chúng ta chèn thêm khoảng trống sau function counters() để giữa khoảng cách giữa nội dung thật của danh mục.

Counters có kiểu mặc định là số thực. Tuy nhiên, styles của thuộc tính list-style-type cũng có cho counters. Các ký hiệu mặc định counter(name) hoặc counter(name, 'list-style-type') để thay đổi định dạng mặc định. Trong thực tế, các phong cách được đề nghị là những:

  • decimal
  • decimal-leading-zero
  • lower-roman
  • upper-roman
  • lower-greek
  • lower-latin
  • upper-latin
  • lower-alpha
  • upper-alpha

Đừng quên rằng chúng ta đang làm việc với các hệ thống số. Cũng nên nhớ rằng các đặc điểm kỹ thuật không xác định làm thế nào để làm cho một hệ thống chữ cái ngoài một bảng chữ cái. Ví dụ, việc vẽ của lower-latin sau 26 mục danh sách là không xác định. Như vậy, chữ số được khuyến cáo cho các danh sách dài:

dl {
   counter-reset: term definition;
}
dt:before {
   counter-increment: term;
   content: counter(term, upper-latin) ". ";
}
dd:before {
   counter-increment: definition;
   content: counter(definition, lower-latin) ". ";
}
  • Xem ví dụ

Chúng ta cũng có thể thêm style cho function counters():

  • Xem ví dụ

Lưu ý rằng các function counters() cũng chấp nhận một đối số thứ ba (lower-roman) là mục cuối cùng trong danh sách đối số của nó, tách ra từ kỳ trước bởi một dấu phẩy thứ hai. Tuy nhiên, function counters() không cho phép chúng ta xác định các styles khác nhau cho mỗi cấp độ của tổ.

9. Kết luận

Với thế hệ mới của các trình duyệt, chúng ta có thể sử dụng CSS-generated content để tạo bố cục của chúng với chuỗi và đồ họa. Sau này Generated content chắc chắn là một công cụ tuyệt vời mà mỗi lập trình viên nên tìm hiểu.

0