Khi viết CSS, điều quan trọng đầu tiên là chọn đúng phần tử HTML cần áp dụng style. Công việc này được thực hiện nhờ CSS selectors.
Nếu nắm vững selectors, bạn sẽ viết CSS gọn gàng, dễ bảo trì và tái sử dụng.
CSS selectors là gì?
CSS selectors là các mẫu cú pháp dùng để chọn và tác động lên các phần tử HTML cụ thể. Hiểu đơn giản, chúng giống như "địa chỉ" giúp CSS tìm đúng "ngôi nhà" (phần tử HTML) cần trang trí.
<style>
p {
color: green; /* Chọn tất cả thẻ <p> */
}
div {
background-color: blueviolet; /* Chọn tất cả thẻ <div> */
}
</style>
<p>Hôm nay là một ngày đẹp trời</p>
<div class="box"></div>
Trong ví dụ trên,
pvàdivchính là các CSS selector cơ bản nhất.
Tài liệu tham khảo: W3Schools CSS Selectors.
ID và Class là gì?
ID
Thuộc tính định danh duy nhất cho mỗi phần tử
<style>
#intro {
color: red;
}
</style>
<p id="intro">Đoạn văn duy nhất</p>
- Quy tắc sử dụng: Mỗi phần tử chỉ có 1 ID, mỗi ID là duy nhất trong trang
- Khi nào dùng: Cho các thành phần xuất hiện duy nhất trong trang
Class
Thuộc tính cho phép nhóm nhiều phần tử
<style>
.highlight {
color: blue;
}
</style>
<p class="highlight">Đoạn 1</p>
<p class="highlight">Đoạn 2</p>
- Quy tắc sử dụng: Có thể dùng nhiều class/phần tử, tái sử dụng class cho nhiều phần tử
- Khi nào dùng: Khi nhiều phần tử cần chung styles CSS
So sánh ID vs Class
- ID: Không thể dùng nhiều cho 1 phần tử, không tái sử dụng
- Class: Có thể dùng nhiều và tái sử dụng thoải mái
Quy tắc đặt tên ID & Class
- Ký tự hợp lệ: Bắt đầu bằng chữ cái, có thể chứa số, gạch ngang (-), gạch dưới (_)
- Không được: Bắt đầu bằng số, chứa ký tự đặc biệt (@, #, $, %, &...)
- Phân biệt hoa thường:
myClass≠myclass
Naming Convention phổ biến
- kebab-case:
primary-heading,nav-menu(phổ biến trong CSS) - camelCase:
primaryHeading,navMenu(thường dùng trong JavaScript) - snake_case:
primary_heading,nav_menu - BEM:
block__element--modifier(cho dự án lớn)
Simple selectors
element: chọn tất cả thẻ<p> → p { ... }#id: chọn phần tử có ID →#header { ... }.class: chọn tất cả phần tử có class →.title { ... }*: chọn tất cả phần tử →* { margin: 0 }element.class: chọn thẻ
có class intro →p.intro { ... }element, element: chọn nhiều loại thẻ →div, p { ... }.class1.class2: chọn phần tử có cả 2 class →.btn.primary { ... }
<style>
/* Chọn tất cả thẻ p */
p {
color: green;
}
/* Chọn theo ID */
#header {
background: lightblue;
}
/* Chọn theo class */
.title {
font-size: 20px;
color: purple;
}
/* Chọn tất cả phần tử */
* {
margin: 0;
padding: 0;
}
/* Chọn thẻ p có class intro */
p.intro {
font-style: italic;
}
/* Chọn nhiều loại thẻ cùng lúc */
h1,
p {
text-align: center;
}
/* Chọn phần tử có cả 2 class */
.btn.primary {
background: orange;
color: white;
}
</style>
<h1 id="header">Đây là header</h1>
<p class="title">Đoạn văn tiêu đề</p>
<p class="intro">Đoạn văn giới thiệu</p>
<button class="btn primary">Nút chính</button>
Combinator selectors
element element: chọn phần tử con bất kỳelement > element: chọn con trực tiếpelement + element: chọn phần tử ngay sauelement1 ~ element2: chọn tất cả phần tử cùng cấp sau đó
<style>
/* Chọn p nằm trong div */
div p {
color: green;
}
/* Chọn p là con trực tiếp của div */
div > p {
font-weight: bold;
}
/* Chọn p ngay sau div */
div + p {
color: red;
}
/* Chọn tất cả p đứng sau div */
div ~ p {
font-style: italic;
}
</style>
<div>
<p>Đoạn trong div</p>
</div>
<p>Đoạn ngay sau div</p>
<p>Đoạn khác sau div</p>
Pseudo-classes
:hover: áp dụng khi di chuột.:active: khi nhấn chuột.:link: liên kết chưa truy cập.:visited: liên kết đã truy cập.:empty: phần tử rỗng.:target: phần tử trùng với hash trên URL.
<style>
a:link {
color: blue;
}
a:visited {
color: purple;
}
a:hover {
color: red;
}
a:active {
color: green;
}
div:empty {
border: 2px dashed gray;
width: 100px;
height: 50px;
}
#home:target {
background: yellow;
}
</style>
<a href="#">Liên kết</a>
<div></div>
<p><a href="#home">Đi tới #home</a></p>
<p id="home">Đây là thẻ home</p>
Tra cứu các CSS Pseudo-classes: W3Schools CSS Pseudo-classes.
Child selectors
:first-child: phần tử con đầu tiên.:last-child: phần tử con cuối cùng.:nth-child(n): phần tử con thứ n.:nth-last-child(n): phần tử con thứ n từ cuối lên.:only-child: phần tử là con duy nhất.
<style>
p:first-child {
color: red;
}
p:last-child {
color: blue;
}
p:nth-child(2) {
font-weight: bold;
}
p:nth-last-child(2) {
text-decoration: underline;
}
p:only-child {
background: lightgreen;
}
</style>
<div>
<p>Đoạn con đầu tiên</p>
<p>Đoạn con thứ hai</p>
<p>Đoạn con cuối cùng</p>
</div>
<div>
<p>Đây là con duy nhất</p>
</div>
Type selectors
:first-of-type: phần tử đầu tiên của loại đó.:last-of-type: phần tử cuối cùng của loại đó.:nth-of-type(n): phần tử thứ n của loại đó.:nth-last-of-type(n): phần tử thứ n từ cuối lên.:only-of-type: phần tử duy nhất của loại đó.
<style>
p:first-of-type {
color: red;
}
p:last-of-type {
color: blue;
}
p:nth-of-type(2) {
font-weight: bold;
}
p:nth-last-of-type(2) {
text-decoration: underline;
}
p:only-of-type {
background: lightyellow;
}
</style>
<div>
<p>Đoạn 1</p>
<span>Không phải p</span>
<p>Đoạn 2</p>
<p>Đoạn 3</p>
</div>
Not selector
Loại trừ phần tử không mong muốn:
<style>
/* Chọn tất cả highlight nhưng không phải p */
.highlight:not(p) {
color: orange;
font-weight: bold;
}
</style>
<p class="highlight">Tôi là đoạn p (không bị áp dụng)</p>
<span class="highlight">Tôi là span (bị áp dụng)</span>
Độ ưu tiên của CSS
- Inline CSS > ID selector > Class selector > Element selector.
- Luôn nhớ: CSS viết sau sẽ ghi đè CSS viết trước nếu có cùng độ ưu tiên.
Tài liệu tham khảo: CSS Specificity.
<style>
/* Ưu tiên thấp */
p {
color: blue;
}
/* Cao hơn element */
.intro {
color: green;
}
/* Cao hơn class */
#special {
color: red;
}
</style>
<p id="special" class="intro">Ai sẽ thắng?</p>
Kết quả: chữ đỏ, vì ID có độ ưu tiên cao nhất.
Kết luận
- CSS selectors: dùng để chọn phần tử HTML áp dụng style.
- Có nhiều loại selectors:
simple,combinator,pseudo-class,child,type,not. - ID vs Class: ID duy nhất, class tái sử dụng linh hoạt.
- Độ ưu tiên: Inline > ID > Class > Element.
Thành thạo selectors giúp bạn viết CSS rõ ràng, dễ bảo trì và kiểm soát style tốt hơn.