Tìm Hiểu CSS: Định Hình và Tô Điểm Giao Diện Web

1. Giới thiệu tổng quan về CSS

CSS, viết tắt của Cascading Style Sheets, là một ngôn ngữ máy tính được thiết kế để mô tả cách trình bày của một tài liệu được viết bằng ngôn ngữ đánh dấu như HTML hoặc XML. CSS cho phép nhà phát triển định dạng các yếu tố như phông chữ, màu sắc, khoảng cách, kích thước, hình ảnh nền và vị trí của các thành phần trên trang web.

Sự ra đời của CSS đã mang lại nhiều lợi ích đáng kể:

  • Phân tách nội dung và trình bày: CSS giúp tách biệt cấu trúc (HTML) khỏi phong cách (CSS), làm cho code gọn gàng, dễ quản lý hơn.
  • Đồng nhất và dễ chỉnh sửa: Thay đổi phong cách tại một chỗ có thể áp dụng cho nhiều trang, giúp việc cập nhật giao diện trở nên nhanh chóng.
  • Đa dạng hóa phong cách: Cung cấp nhiều tùy chọn phong phú để thiết kế bố cục và hiệu ứng trực quan.
  • Giảm dung lượng và tăng tốc độ tải trang: Sử dụng file CSS bên ngoài giúp giảm lượng code lặp lại trong HTML, tiết kiệm băng thông và cải thiện hiệu suất tải trang.
  • Cải thiện SEO: Code HTML "sạch" hơn, dễ đọc hơn cho các công cụ tìm kiếm.

1.1. Cú pháp cơ bản của CSS

Một quy tắc CSS bao gồm một bộ chọn (selector) và một hoặc nhiều khai báo (declaration). Mỗi khai báo gồm một thuộc tính (property) và giá trị (value), kết thúc bằng dấu chấm phẩy (;), được đặt trong cặp dấu ngoặc nhọn {}.

selector {
    property1: value1;
    property2: value2;
    /* ... các khai báo khác ... */
}

Ví dụ:

h1 {
    color: blue;
    font-size: 24px;
}

1.2. Các cách nhúng CSS vào tài liệu HTML

Có ba phương pháp chính để áp dụng CSS cho tài liệu HTML:

1.2.1. Kiểu nội tuyến (Inline Styles)

Sử dụng thuộc tính style trực tiếp trong thẻ HTML. Phương pháp này chỉ áp dụng cho một phần tử cụ thể.

<h1 style="color: red; font-family: Arial;">Tiêu đề Trang Web</h1>
<p style="font-size: 16px; color: green;">Đoạn văn này có kiểu riêng.</p>

Ưu điểm: Nhanh chóng cho các thay đổi nhỏ. Nhược điểm: Không khuyến khích vì làm lẫn lộn nội dung và trình bày, khó bảo trì và không tận dụng được lợi ích của CSS.

1.2.2. Kiểu nội bộ (Internal Stylesheet)

Đặt mã CSS trong cặp thẻ <style>, thường nằm trong phần <head> của tài liệu HTML.

<head>
    <meta charset="UTF-8">
    <title>Trang Web với CSS nội bộ</title>
    <style>
        h1 {
            color: green;
        }
        p {
            font-size: 18px;
            text-align: center;
        }
    </style>
</head>

Ưu điểm: Dễ dàng chỉnh sửa phong cách cho một trang cụ thể. Nhược điểm: Không thể tái sử dụng kiểu cho nhiều trang khác nhau, vẫn chưa tách biệt hoàn toàn nội dung và phong cách.

1.2.3. Kiểu ngoại bộ (External Stylesheet)

Mã CSS được viết trong một tệp riêng biệt có phần mở rộng .css. Tệp này sau đó được liên kết với tài liệu HTML bằng thẻ <link> trong phần <head>.

Ví dụ tệp styles.css:

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f4f4f4;
}
h1 {
    color: #333;
    text-align: center;
}

Ví dụ tệp HTML liên kết đến styles.css:

<head>
    <meta charset="UTF-8">
    <title>Trang Web với CSS ngoại bộ</title>
    <link rel="stylesheet" href="styles.css">
</head>

Ưu điểm: Tách biệt hoàn toàn nội dung và trình bày, dễ dàng tái sử dụng và bảo trì cho nhiều trang. Đây là phương pháp được khuyến nghị và sử dụng phổ biến nhất.

1.2.4. Ưu tiên của các kiểu CSS

Khi có nhiều quy tắc CSS áp dụng cho cùng một phần tử, trình duyệt sẽ áp dụng quy tắc có độ ưu tiên cao nhất. Thứ tự ưu tiên (từ thấp đến cao) như sau:

  1. Trình duyệt mặc định
  2. Kiểu ngoại bộ
  3. Kiểu nội bộ
  4. Kiểu nội tuyến

Quy tắc chung là "càng gần phần tử, càng ưu tiên cao".

1.3. Các bộ chọn CSS cơ bản

1.3.1. Bộ chọn phần tử (Element Selector)

Chọn tất cả các phần tử HTML có cùng tên thẻ.

p {
    color: #4a4a4a;
    line-height: 1.6;
}
a {
    text-decoration: none;
    color: #007bff;
}

1.3.2. Bộ chọn lớp (Class Selector)

Chọn các phần tử có cùng thuộc tính class. Một lớp có thể được sử dụng cho nhiều phần tử.

<p class="highlight">Đoạn văn nổi bật.</p>
<div class="highlight">Một khối nổi bật khác.</div>
.highlight {
    background-color: yellow;
    border: 1px solid orange;
}

1.3.3. Bộ chọn ID (ID Selector)

Chọn một phần tử duy nhất có thuộc tính id cụ thể. Giá trị id phải là duy nhất trong một tài liệu HTML.

<div id="main-header">Tiêu đề Chính</div>
#main-header {
    font-size: 32px;
    font-weight: bold;
    color: #0056b3;
}

1.3.4. Thứ tự ưu tiên của bộ chọn cơ bản

Thứ tự ưu tiên của các bộ chọn cơ bản (từ thấp đến cao) là: Bộ chọn phần tử < Bộ chọn lớp < Bộ chọn ID.

1.4. Các bộ chọn CSS nâng cao

1.4.1. Bộ chọn tổ hợp (Combinators)

  • Bộ chọn hậu duệ (Descendant Selector - khoảng trắng): Chọn tất cả các phần tử là con cháu của một phần tử khác.

    ul li {
        list-style-type: square;
        color: #555;
    }
    
  • Bộ chọn con trực tiếp (Child Selector - >): Chọn tất cả các phần tử là con trực tiếp của một phần tử khác.

    div > p {
        margin-bottom: 5px;
    }
    
  • Bộ chọn anh em liền kề (Adjacent Sibling Selector - +): Chọn phần tử đứng ngay sau một phần tử khác và có cùng cấp độ.

    h2 + p {
        text-indent: 20px;
    }
    
  • Bộ chọn anh em chung (General Sibling Selector - ~): Chọn tất cả các phần tử là anh em của một phần tử khác (không nhất thiết phải liền kề) và có cùng cấp độ.

    div ~ p {
        background-color: #e0f7fa;
    }
    

1.4.2. Bộ chọn giả lớp cấu trúc (Structural Pseudo-classes)

Chọn phần tử dựa trên vị trí của chúng trong cấu trúc tài liệu.

<ul>
    <li>Mục 1</li>
    <li>Mục 2</li>
    <li>Mục 3</li>
</ul>
<div>
    <p>Đoạn A</p>
    <span>Văn bản A</span>
    <p>Đoạn B</p>
</div>
/* Chọn mục li đầu tiên trong ul */
ul li:first-child {
    font-weight: bold;
}
/* Chọn mục li cuối cùng trong ul */
ul li:last-child {
    background-color: #fce4ec;
}
/* Chọn phần tử p là con thứ 2 của bất kỳ phần tử cha nào (không phân biệt loại thẻ) */
div :nth-child(2) { /* Chọn span trong ví dụ trên */
    border: 1px dashed blue;
}
/* Chọn phần tử p thứ 2 CÓ CÙNG LOẠI thẻ là con của div */
div p:nth-of-type(2) { /* Chọn đoạn B trong ví dụ trên */
    color: purple;
}

Lưu ý: :nth-child(n) đếm tất cả các phần tử con của cha mà không quan tâm đến loại thẻ. :nth-of-type(n) đếm chỉ những phần tử con cùng loại thẻ với bộ chọn.

1.4.3. Bộ chọn thuộc tính (Attribute Selectors)

Chọn phần tử dựa trên sự tồn tại của thuộc tính hoặc giá trị thuộc tính.

  • E[attr]: Chọn phần tử E có thuộc tính attr.

    a[target] { /* Chọn tất cả các thẻ a có thuộc tính target */
        text-decoration: underline;
    }
    
  • E[attr=val]: Chọn phần tử E có thuộc tính attr với giá trị chính xác là val.

    input[type="submit"] {
        background-color: #4CAF50;
        color: white;
    }
    
  • E[attr*=val]: Chọn phần tử E có thuộc tính attr chứa chuỗi val bất kể vị trí.

    a[href*="example"] { /* Chọn thẻ a có href chứa "example" */
        border-bottom: 1px dotted blue;
    }
    
  • E[attr^=val]: Chọn phần tử E có thuộc tính attr bắt đầu bằng chuỗi val.

    a[href^="https"] { /* Chọn thẻ a có href bắt đầu bằng "https" */
        font-weight: bold;
    }
    
  • E[attr$=val]: Chọn phần tử E có thuộc tính attr kết thúc bằng chuỗi val.

    img[src$=".png"] { /* Chọn thẻ img có src kết thúc bằng ".png" */
        border: 2px solid lightgray;
    }
    

2. Làm đẹp các phần tử trang web

Việc sử dụng CSS để tô điểm các phần tử trang web không chỉ tạo ra giao diện đẹp mắt, thu hút người dùng mà còn giúp truyền tải thông tin hiệu quả và nâng cao trải nghiệm người dùng.

Thẻ <span> là một thẻ nội tuyến (inline) thường được sử dụng để áp dụng kiểu cho một phần nhỏ của văn bản hoặc một nhóm từ mà không làm thay đổi cấu trúc bố cục.

<p>Học tập chăm chỉ, <span class="highlight-text">tiến bộ mỗi ngày</span>.</p>

2.1. Kiểu phông chữ (Font Styles)

2.1.1. Họ phông chữ (font-family)

Xác định phông chữ cho văn bản. Nên cung cấp nhiều phông chữ thay thế (fallback) để đảm bảo trình duyệt hiển thị một phông phù hợp nếu phông đầu tiên không có sẵn.

p {
    font-family: 'Open Sans', Arial, sans-serif;
}
h1 {
    font-family: 'Merriweather', 'Times New Roman', serif;
}

2.1.2. Kích thước phông chữ (font-size)

Đặt kích thước văn bản. Các đơn vị phổ biến gồm px (pixel), em (tương đối với kích thước phông chữ của phần tử cha), rem (tương đối với kích thước phông chữ gốc của tài liệu).

body { font-size: 16px; } /* Kích thước cơ bản */
h1 { font-size: 2em; } /* Gấp đôi kích thước của body */
p { font-size: 1rem; } /* Bằng kích thước của body */
span { font-size: 14pt; } /* Điểm (point) */

2.1.3. Kiểu phông chữ (font-style)

Xác định kiểu chữ như in nghiêng.

  • normal: Chữ thường (mặc định)
  • italic: Chữ in nghiêng
  • oblique: Chữ nghiêng (tương tự italic nhưng có thể ít được hỗ trợ hơn)

2.1.4. Độ đậm phông chữ (font-weight)

Xác định độ đậm của văn bản (ví dụ: normal, bold, hoặc các giá trị số từ 100 đến 900).

2.1.5. Thuộc tính viết tắt font

Kết hợp nhiều thuộc tính phông chữ vào một dòng duy nhất theo thứ tự: font-style font-weight font-size/line-height font-family.

p.summary {
    font: italic bold 1.2em/1.5 Arial, sans-serif;
    /* Tương đương với:
    font-style: italic;
    font-weight: bold;
    font-size: 1.2em;
    line-height: 1.5;
    font-family: Arial, sans-serif;
    */
}

2.2. Kiểu văn bản (Text Styles)

2.2.1. Màu sắc văn bản (color)

Đặt màu sắc cho văn bản. Có nhiều định dạng màu:

  • Hexadecimal: #RRGGBB (ví dụ: #FF0000 cho màu đỏ)
  • RGB: rgb(red, green, blue) (ví dụ: rgb(255, 0, 0))
  • RGBA: rgba(red, green, blue, alpha) (thêm kênh alpha cho độ trong suốt, 0 là trong suốt, 1 là mờ đục)
  • Tên màu: red, blue, green, v.v.
body {
    color: #333333; /* Màu xám đen */
}
.error-message {
    color: rgb(200, 50, 50); /* Màu đỏ */
}
.transparent-text {
    color: rgba(0, 0, 255, 0.7); /* Màu xanh với độ trong suốt 70% */
}

2.2.2. Canh lề văn bản (text-align)

Xác định cách văn bản được căn chỉnh theo chiều ngang (left, right, center, justify).

2.2.3. Thụt lề dòng đầu tiên (text-indent)

Thụt lề cho dòng đầu tiên của một khối văn bản (ví dụ: 20px, 2em).

2.2.4. Chiều cao dòng (line-height)

Đặt chiều cao của mỗi dòng văn bản, thường là một số không có đơn vị (tương đối với font-size) hoặc đơn vị px.

2.2.5. Trang trí văn bản (text-decoration)

Thêm hoặc loại bỏ các đường trang trí như gạch chân, gạch ngang (ví dụ: none, underline, overline, line-through).

2.2.6. Canh lề dọc (vertical-align)

Thiết lập canh lề dọc cho các phần tử nội tuyến hoặc nội tuyến-khối (ví dụ: baseline, top, middle, bottom).

2.3. Bóng văn bản (text-shadow)

Tạo hiệu ứng đổ bóng cho văn bản. Giá trị gồm: horizontal-offset vertical-offset blur-radius color.

h1 {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}

2.4. Giả lớp liên kết (Hyperlink Pseudo-classes)

CSS cung cấp các giả lớp để tạo kiểu cho các trạng thái khác nhau của liên kết:

  • a:link: Liên kết chưa được truy cập.
  • a:visited: Liên kết đã được truy cập.
  • a:hover: Liên kết khi con trỏ chuột di qua.
  • a:active: Liên kết khi được nhấp.
a:link { color: blue; }
a:visited { color: purple; }
a:hover { color: red; text-decoration: underline; }
a:active { color: orange; }

Trong thực tế, :link và :visited thường được đặt màu gần giống nhau, trong khi :hover là trạng thái quan trọng nhất để cung cấp phản hồi cho người dùng.

2.5. Kiểu danh sách (List Styles)

Các thuộc tính CSS để định dạng danh sách (<ul>, <ol>):

  • list-style-type: Kiểu dấu đầu dòng (ví dụ: disc, circle, square, decimal, none).
  • list-style-image: Sử dụng một hình ảnh tùy chỉnh làm dấu đầu dòng.
  • list-style-position: Vị trí của dấu đầu dòng (inside, outside).
  • list-style: Thuộc tính viết tắt cho ba thuộc tính trên.
ul {
    list-style: none; /* Bỏ dấu đầu dòng mặc định */
    padding-left: 0;
}
ul li {
    background: url('bullet.png') no-repeat left center; /* Dùng ảnh làm dấu đầu dòng */
    padding-left: 20px;
    margin-bottom: 5px;
}
ol {
    list-style-type: upper-roman; /* Số La Mã viết hoa */
}

2.6. Kiểu nền (Background Styles)

2.6.1. Màu nền (background-color)

Đặt màu nền cho phần tử.

body {
    background-color: #f0f8ff; /* Màu xanh aliceblue */
}

2.6.2. Hình ảnh nền (background-image)

Sử dụng một hình ảnh làm nền. Đường dẫn phải nằm trong url().

body {
    background-image: url('bg-pattern.png');
}

2.6.3. Lặp lại nền (background-repeat)

Kiểm soát cách hình ảnh nền lặp lại (repeat, repeat-x, repeat-y, no-repeat).

2.6.4. Vị trí nền (background-position)

Đặt vị trí của hình ảnh nền (ví dụ: top center, 20px 30px).

2.6.5. Kích thước nền (background-size)

Điều chỉnh kích thước hình ảnh nền (ví dụ: cover, contain, 50%, 200px).

2.6.6. Thuộc tính viết tắt background

Kết hợp nhiều thuộc tính nền: background-color background-image background-repeat background-attachment background-position.

.header-banner {
    background: #e0e0e0 url('banner.jpg') no-repeat center / cover;
}
/* Tương đương với:
background-color: #e0e0e0;
background-image: url('banner.jpg');
background-repeat: no-repeat;
background-position: center;
background-size: cover;
*/

2.7. Hiệu ứng chuyển màu (CSS Gradients)

CSS3 cho phép tạo các hiệu ứng chuyển màu mà không cần dùng hình ảnh. Có hai loại chính:

  • Chuyển màu tuyến tính (Linear Gradients): Màu sắc chuyển đổi dọc theo một đường thẳng.

    .linear-gradient-div {
        background-image: linear-gradient(to right, red, orange, yellow); /* Từ trái sang phải */
        background-image: linear-gradient(135deg, #e66465, #9198e5); /* Theo góc 135 độ */
    }
    
  • Chuyển màu tỏa tròn (Radial Gradients): Màu sắc tỏa ra từ một điểm trung tâm.

    .radial-gradient-div {
        background-image: radial-gradient(circle at center, white, lightgray, gray);
    }
    

Để đảm bảo tương thích với các trình duyệt cũ, cần sử dụng các tiền tố nhà cung cấp (vendor prefixes) như -webkit-, -moz-, -o-, -ms-.

.gradient-box {
    background-image: -webkit-linear-gradient(left, #f00, #ff0); /* Chrome, Safari */
    background-image: -moz-linear-gradient(left, #f00, #ff0); /* Firefox */
    background-image: -o-linear-gradient(left, #f00, #ff0); /* Opera */
    background-image: linear-gradient(to right, #f00, #ff0); /* Chuẩn */
}

3. Mô hình hộp (Box Model)

Mô hình hộp CSS coi mỗi phần tử HTML là một hộp hình chữ nhật, bao gồm nội dung (content), lớp đệm (padding), đường viền (border) và lề (margin). Việc hiểu rõ mô hình này là rất quan trọng để bố cục và sắp xếp các phần tử trên trang web.

Sơ đồ mô hình hộp CSS
  • Nội dung (Content): Khu vực hiển thị nội dung thực tế của phần tử (văn bản, hình ảnh, video). Kích thước của nó được xác định bởi width và height.
  • Lớp đệm (Padding): Khoảng trống giữa nội dung và đường viền. Padding làm tăng kích thước hiển thị của phần tử.
  • Đường viền (Border): Đường bao quanh padding và nội dung.
  • Lề (Margin): Khoảng trống bên ngoài đường viền, dùng để tạo khoảng cách giữa các phần tử khác nhau. Margin không làm tăng kích thước hiển thị của phần tử.

3.1. Đường viền (Border)

3.1.1. Màu đường viền (border-color)

Đặt màu cho đường viền. Có thể đặt cho tất cả các cạnh hoặc từng cạnh riêng lẻ theo thứ tự: trên, phải, dưới, trái.

.my-box {
    border-color: red green blue yellow; /* Trên đỏ, phải xanh lá, dưới xanh dương, trái vàng */
    border-top-color: black;
}

3.1.2. Độ dày đường viền (border-width)

Đặt độ dày cho đường viền (ví dụ: 1px, medium, thick).

.my-box {
    border-width: 2px 4px; /* Trên/Dưới 2px, Trái/Phải 4px */
    border-left-width: 5px;
}

3.1.3. Kiểu đường viền (border-style)

Đặt kiểu cho đường viền (ví dụ: solid, dotted, dashed, double, none).

.my-box {
    border-style: solid dotted dashed double; /* Các kiểu khác nhau cho 4 cạnh */
    border-top-style: hidden;
}

3.1.4. Thuộc tính viết tắt border

Kết hợp border-width, border-style và border-color vào một dòng duy nhất.

.my-box {
    border: 1px solid #3a6587;
    /* Tương đương:
    border-width: 1px;
    border-style: solid;
    border-color: #3a6587;
    */
}

3.2. Lề và lớp đệm (Margin và Padding)

3.2.1. Lề (margin)

Tạo khoảng trống bên ngoài đường viền của phần tử. Giá trị có thể là số pixel, phần trăm hoặc auto.

.element-a {
    margin: 10px 20px 15px 5px; /* Trên, phải, dưới, trái */
    margin-top: 5px;
    margin-bottom: 15px;
    margin-left: 20px;
    margin-right: 20px;
}
.center-div {
    width: 80%;
    margin: 0 auto; /* Canh giữa khối theo chiều ngang */
}

Để canh giữa một phần tử khối theo chiều ngang, bạn có thể đặt margin-left và margin-right thành auto, đồng thời phần tử phải có một width cố định.

3.2.2. Lớp đệm (padding)

Tạo khoảng trống giữa nội dung và đường viền. Padding cũng có thể được đặt cho từng cạnh hoặc tất cả các cạnh theo thứ tự: trên, phải, dưới, trái.

.element-b {
    padding: 10px; /* Padding 10px cho tất cả các cạnh */
    padding: 5px 10px; /* Trên/Dưới 5px, Trái/Phải 10px */
    padding-left: 15px;
}

3.3. Kích thước mô hình hộp (Box-sizing)

Thuộc tính box-sizing kiểm soát cách tính toán tổng chiều rộng và chiều cao của một phần tử.

  • content-box (mặc định): width và height chỉ bao gồm kích thước của nội dung. Padding và border sẽ được thêm vào bên ngoài, làm tăng tổng kích thước của phần tử.

    div {
        width: 100px;
        height: 100px;
        padding: 10px;
        border: 5px solid black;
        box-sizing: content-box; /* Tổng kích thước thực tế sẽ là 100 + 2*10 + 2*5 = 130px */
    }
    
  • border-box: width và height bao gồm cả nội dung, padding và border. Padding và border sẽ được tính vào bên trong kích thước đã chỉ định, không làm tăng tổng kích thước của phần tử.

    div {
        width: 100px;
        height: 100px;
        padding: 10px;
        border: 5px solid black;
        box-sizing: border-box; /* Tổng kích thước thực tế vẫn là 100px */
    }
    

Sử dụng box-sizing: border-box; thường giúp bố cục dễ dàng và trực quan hơn, đặc biệt khi làm việc với các hệ thống lưới.

3.4. Đường viền bo góc (Border-radius)

Thuộc tính border-radius cho phép tạo các góc bo tròn cho các phần tử. Có thể đặt một giá trị duy nhất cho tất cả các góc hoặc bốn giá trị cho từng góc theo thứ tự: trên-trái, trên-phải, dưới-phải, dưới-trái.

.round-corners {
    border-radius: 10px; /* Bo tròn tất cả 4 góc với bán kính 10px */
}
.custom-radius {
    border-radius: 20px 0 30px 5px; /* Mỗi góc một bán kính khác nhau */
}

3.4.1. Tạo hình tròn

Để tạo một hình tròn, phần tử phải có chiều rộng và chiều cao bằng nhau, và border-radius phải là 50% hoặc bằng một nửa kích thước của cạnh.

<div class="circle"></div>
.circle {
    width: 100px;
    height: 100px;
    background-color: #6699ff;
    border-radius: 50%;
}

3.4.2. Tạo hình bán nguyệt hoặc góc phần tư

Bằng cách điều chỉnh width, height và các giá trị border-radius riêng lẻ, có thể tạo ra các hình dạng đặc biệt như bán nguyệt hoặc góc phần tư hình tròn.

<div class="half-circle-top"></div>
<div class="quarter-circle-bottom-right"></div>
.half-circle-top {
    width: 100px;
    height: 50px;
    background-color: #ff6666;
    border-radius: 50px 50px 0 0; /* Tạo bán nguyệt phía trên */
}
.quarter-circle-bottom-right {
    width: 50px;
    height: 50px;
    background-color: #66ff66;
    border-radius: 0 0 50px 0; /* Tạo góc phần tư dưới bên phải */
}

3.5. Bóng hộp (Box-shadow)

Thuộc tính box-shadow thêm hiệu ứng đổ bóng cho phần tử. Giá trị bao gồm: horizontal-offset vertical-offset blur-radius spread-radius color inset (tùy chọn, để tạo bóng bên trong).

.shadow-box {
    width: 150px;
    height: 100px;
    background-color: white;
    margin: 30px;
    border-radius: 8px;
    box-shadow: 5px 5px 15px 2px rgba(0, 0, 0, 0.3); /* Bóng ngoài */
}
.inner-shadow-box {
    width: 150px;
    height: 100px;
    background-color: #eee;
    margin: 30px;
    border-radius: 8px;
    box-shadow: inset 3px 3px 8px rgba(0, 0, 0, 0.4); /* Bóng trong */
}

4. Bố cục với Float

4.1. Luồng tài liệu chuẩn (Standard Document Flow)

Luồng tài liệu chuẩn là cách các phần tử HTML được trình duyệt sắp xếp mặc định: từ trên xuống dưới cho các phần tử khối (block-level) và từ trái sang phải cho các phần tử nội tuyến (inline-level).

  • Phần tử khối (Block-level elements): Luôn bắt đầu trên một dòng mới và chiếm toàn bộ chiều rộng có sẵn (ví dụ: <h1>, <p>, <div>, <ul>).

  • Phần tử nội tuyến (Inline-level elements): Không bắt đầu trên một dòng mới và chỉ chiếm đủ chiều rộng cần thiết cho nội dung của nó (ví dụ: <span>, <a>, <img>, <strong>).

4.2. Thuộc tính display

Thuộc tính display kiểm soát cách một phần tử được hiển thị trong luồng tài liệu.

  • display: block;: Biến phần tử thành phần tử khối. Luôn bắt đầu trên một dòng mới, có thể đặt width và height.

  • display: inline;: Biến phần tử thành phần tử nội tuyến. Không bắt đầu trên dòng mới, không thể đặt width và height (chỉ chiếm đủ chỗ cho nội dung).

  • display: inline-block;: Kết hợp đặc tính của cả khối và nội tuyến. Các phần tử xếp hàng ngang như nội tuyến nhưng có thể đặt width, height và lề dọc như khối.

  • display: none;: Ẩn hoàn toàn phần tử khỏi trang, không chiếm bất kỳ không gian nào.

.menu-item {
    display: inline-block; /* Để các mục menu xếp hàng ngang */
    padding: 10px 15px;
    background-color: #f0f0f0;
    margin-right: 5px;
}

4.3. Thuộc tính float

Thuộc tính float được sử dụng để đẩy một phần tử sang trái hoặc phải của phần tử chứa nó, cho phép các phần tử khác (thường là văn bản) bao quanh nó. Khi một phần tử được float, nó sẽ bị loại bỏ khỏi luồng tài liệu chuẩn.

  • float: left;: Dịch phần tử sang trái.
  • float: right;: Dịch phần tử sang phải.
  • float: none;: Mặc định, không float.
<div class="container">
    <img src="image.jpg" alt="Description" class="floated-image">
    <p>Đoạn văn này sẽ bao quanh hình ảnh được float.</p>
    <p>Nội dung tiếp theo.</p>
</div>
.floated-image {
    float: left;
    margin-right: 15px;
}

4.4. Xóa float (Clearing Floats) và vấn đề sập khung cha

Khi các phần tử con được float, phần tử cha sẽ không "nhận biết" được chiều cao của chúng, dẫn đến việc phần tử cha bị sập khung (parent collapse) và các phần tử tiếp theo trong luồng tài liệu có thể bị tràn lên trên các phần tử float.

4.4.1. Thuộc tính clear

Thuộc tính clear được dùng để loại bỏ ảnh hưởng của float từ các phần tử trước đó. Nó không phải là để "xóa" float khỏi một phần tử, mà là để đảm bảo rằng phần tử được áp dụng clear sẽ bắt đầu bên dưới các phần tử float.

  • clear: left;: Phần tử bắt đầu bên dưới các phần tử float trái.
  • clear: right;: Phần tử bắt đầu bên dưới các phần tử float phải.
  • clear: both;: Phần tử bắt đầu bên dưới cả các phần tử float trái và phải.
<div class="box-left"></div>
<div class="box-right"></div>
<p class="clear-floats">Đoạn văn này sẽ nằm dưới các box.</p>
.box-left { float: left; width: 100px; height: 100px; background: lightblue; }
.box-right { float: right; width: 100px; height: 100px; background: lightcoral; }
.clear-floats { clear: both; background: lightgreen; }

4.4.2. Các phương pháp khắc phục sập khung cha

Để phần tử cha bao bọc đúng chiều cao của các phần tử con được float, có một số kỹ thuật phổ biến:

  1. Thêm phần tử <div> trống với clear: both;: Thêm một <div> trống ngay sau các phần tử float và áp dụng clear: both;. Phương pháp này đơn giản nhưng thêm mã HTML không ngữ nghĩa.

    <div class="parent-container">
        <div class="item-a" style="float: left;"></div>
        <div class="item-b" style="float: right;"></div>
        <div style="clear: both;"></div> <!-- Phần tử trống để xóa float -->
    </div>
    
  2. Đặt chiều cao cố định cho phần tử cha: Đơn giản nhưng hạn chế, vì phần tử cha sẽ không tự động điều chỉnh chiều cao nếu nội dung con thay đổi.

    .parent-container {
        height: 150px; /* Chiều cao cố định */
        border: 1px solid gray;
    }
    
  3. Áp dụng overflow cho phần tử cha: Đặt overflow: hidden; (hoặc auto) cho phần tử cha. Phương pháp này thường hiệu quả và ít có tác dụng phụ, trừ khi bạn cần nội dung tràn ra ngoài hiển thị.

    .parent-container {
        overflow: hidden; /* Sẽ chứa các phần tử float con */
        border: 1px solid gray;
    }
    
  4. Sử dụng giả lớp ::after (Kỹ thuật Clearfix): Đây là phương pháp phổ biến và được khuyến nghị nhất. Nó sử dụng giả lớp ::after để thêm một "phần tử ảo" không hiển thị vào cuối phần tử cha và áp dụng clear: both; cho nó.

    .parent-container::after {
        content: ""; /* Nội dung trống */
        display: block; /* Biến thành phần tử khối */
        clear: both; /* Xóa float cho phần tử ảo */
    }
    

    Kỹ thuật này là tối ưu vì không thêm mã HTML thừa, không giới hạn chiều cao và không gây ra vấn đề với nội dung tràn.

4.5. So sánh inline-block và float

  • display: inline-block;:

    • Ưu điểm: Giúp các phần tử xếp hàng ngang, hỗ trợ width và height, vẫn nằm trong luồng tài liệu chuẩn.
    • Nhược điểm: Khoảng trắng giữa các phần tử HTML có thể tạo ra khoảng cách không mong muốn giữa các inline-block. Khó kiểm soát vị trí chính xác hơn float.
  • float:

    • Ưu điểm: Giúp các phần tử xếp hàng ngang và có thể đẩy chúng sang trái/phải một cách linh hoạt. Thường dùng cho bố cục nhiều cột.
    • Nhược điểm: Phần tử bị loại khỏi luồng tài liệu chuẩn, có thể gây ra hiện tượng sập khung cha và ảnh hưởng đến các phần tử lân cận nếu không được xử lý bằng clear.

5. Định vị phần tử (Positioning)

Thuộc tính position trong CSS cho phép bạn kiểm soát vị trí chính xác của một phần tử trên trang web, vượt ra ngoài luồng tài liệu chuẩn.

5.1. Các loại định vị

5.1.1. position: static;

Đây là giá trị mặc định cho tất cả các phần tử. Phần tử sẽ được định vị theo luồng tài liệu chuẩn. Các thuộc tính top, right, bottom, left không có tác dụng.

5.1.2. position: relative; (Định vị tương đối)

Một phần tử được định vị tương đối sẽ dịch chuyển khỏi vị trí ban đầu của nó trong luồng tài liệu chuẩn. Tuy nhiên, nó vẫn chiếm không gian ban đầu của nó và không ảnh hưởng đến vị trí của các phần tử xung quanh.

  • Dịch chuyển so với vị trí gốc của chính nó.
  • Vẫn nằm trong luồng tài liệu chuẩn.
  • Không gian ban đầu của nó vẫn được bảo toàn.
  • Thường được dùng làm ngữ cảnh định vị cho các phần tử con được định vị tuyệt đối.
.relative-box {
    position: relative;
    top: 20px;
    left: 30px; /* Dịch chuyển xuống 20px và sang phải 30px so với vị trí ban đầu */
    background-color: lightblue;
    width: 100px;
    height: 100px;
}

5.1.3. position: absolute; (Định vị tuyệt đối)

Một phần tử được định vị tuyệt đối sẽ bị loại bỏ hoàn toàn khỏi luồng tài liệu chuẩn và được định vị so với phần tử cha được định vị gần nhất (có position khác static). Nếu không có phần tử cha nào được định vị, nó sẽ được định vị so với cửa sổ trình duyệt (viewport).

  • Dịch chuyển so với phần tử cha được định vị gần nhất (hoặc viewport).
  • Bị loại khỏi luồng tài liệu chuẩn, không chiếm không gian.
  • Các phần tử khác sẽ bỏ qua không gian mà nó từng chiếm.
<div class="parent-relative">
    <div class="child-absolute">Nội dung</div>
</div>
.parent-relative {
    position: relative; /* Tạo ngữ cảnh định vị cho phần tử con */
    width: 300px;
    height: 200px;
    border: 2px solid gray;
    margin: 50px;
}
.child-absolute {
    position: absolute;
    top: 10px;
    right: 10px; /* Nằm cách cạnh trên và phải của parent-relative 10px */
    width: 80px;
    height: 50px;
    background-color: lightgreen;
}

5.1.4. position: fixed; (Định vị cố định)

Một phần tử được định vị cố định sẽ bị loại bỏ khỏi luồng tài liệu chuẩn và được định vị so với cửa sổ trình duyệt (viewport). Nó sẽ giữ nguyên vị trí ngay cả khi trang được cuộn.

  • Dịch chuyển so với cửa sổ trình duyệt (viewport).
  • Bị loại khỏi luồng tài liệu chuẩn, không chiếm không gian.
  • Giữ nguyên vị trí khi cuộn trang.
  • Thường dùng cho thanh điều hướng dính, nút "lên đầu trang".
.fixed-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    background-color: #333;
    color: white;
    padding: 10px 0;
    text-align: center;
    z-index: 1000; /* Đảm bảo nó luôn nằm trên các phần tử khác */
}

5.2. Thứ tự chồng lớp (z-index)

Thuộc tính z-index kiểm soát thứ tự xếp chồng của các phần tử được định vị (có position khác static). Phần tử có z-index cao hơn sẽ nằm trên các phần tử có z-index thấp hơn.

  • Giá trị là số nguyên, mặc định là auto (tương đương 0).
  • Chỉ áp dụng cho các phần tử có position được đặt (relative, absolute, fixed, sticky).
<div class="box-a">A</div>
<div class="box-b">B</div>
.box-a {
    position: absolute;
    top: 50px;
    left: 50px;
    width: 100px;
    height: 100px;
    background-color: red;
    z-index: 1; /* Nằm dưới box-b */
}
.box-b {
    position: absolute;
    top: 70px;
    left: 70px;
    width: 100px;
    height: 100px;
    background-color: blue;
    z-index: 2; /* Nằm trên box-a */
}

6. Tạo hoạt ảnh với CSS (Animations)

CSS3 cung cấp các module mạnh mẽ để tạo hiệu ứng chuyển động và hoạt ảnh trực tiếp trong trình duyệt, giảm sự phụ thuộc vào JavaScript hoặc Flash.

6.1. Biến đổi (CSS Transforms)

Các hàm transform cho phép bạn xoay, di chuyển, co giãn hoặc nghiêng các phần tử trong không gian 2D hoặc 3D.

  • Di chuyển (translate()): Dịch chuyển phần tử dọc theo trục X và Y.

    .move-element:hover {
        transform: translate(20px, 10px); /* Dịch chuyển 20px sang phải, 10px xuống dưới */
    }
    
  • Co giãn (scale()): Thay đổi kích thước của phần tử.

    .scale-element:hover {
        transform: scale(1.2); /* Phóng to 120% */
    }
    
  • Xoay (rotate()): Xoay phần tử quanh tâm của nó.

    .rotate-element:hover {
        transform: rotate(45deg); /* Xoay 45 độ theo chiều kim đồng hồ */
    }
    
  • Nghiêng (skew()): Nghiêng phần tử dọc theo trục X và Y.

    .skew-element:hover {
        transform: skew(10deg, 5deg); /* Nghiêng 10 độ theo X, 5 độ theo Y */
    }
    

Có thể kết hợp nhiều biến đổi trong một thuộc tính transform.

.combined-transform:hover {
    transform: translateX(10px) rotate(5deg) scale(1.1);
}

6.2. Chuyển tiếp (CSS Transitions)

Transitions cho phép các thay đổi thuộc tính CSS diễn ra một cách mượt mà trong một khoảng thời gian nhất định, thay vì thay đổi đột ngột.

  • transition-property: Thuộc tính CSS sẽ được chuyển tiếp (ví dụ: background-color, width, all).

  • transition-duration: Thời gian chuyển tiếp tính bằng giây (s) hoặc mili giây (ms).

  • transition-timing-function: Tốc độ chuyển tiếp (ví dụ: ease (mặc định), linear, ease-in, ease-out, ease-in-out, cubic-bezier()).

  • transition-delay: Thời gian chờ trước khi chuyển tiếp bắt đầu.

Thuộc tính viết tắt transition:

.button {
    background-color: #007bff;
    color: white;
    padding: 10px 20px;
    transition: background-color 0.3s ease-in-out; /* Chỉ chuyển tiếp màu nền */
}
.button:hover {
    background-color: #0056b3;
}

.box-transition {
    width: 100px;
    height: 100px;
    background-color: blue;
    transition: all 0.5s linear 0.1s; /* Áp dụng cho tất cả thuộc tính, 0.5s, tốc độ linear, trễ 0.1s */
}
.box-transition:hover {
    width: 150px;
    height: 150px;
    background-color: red;
    transform: rotate(90deg);
}

Transitions thường được kích hoạt bởi các giả lớp như :hover, :active hoặc bởi JavaScript.

6.3. Hoạt ảnh (CSS Animations)

CSS Animations cho phép bạn tạo ra các chuỗi hoạt ảnh phức tạp hơn bằng cách định nghĩa các "khung hình chính" (keyframes) và sau đó áp dụng chúng cho một phần tử.

6.3.1. Định nghĩa Keyframes (@keyframes)

Sử dụng quy tắc @keyframes để xác định các kiểu CSS tại các điểm khác nhau trong hoạt ảnh. Các điểm này được biểu thị bằng phần trăm (từ 0% đến 100%) hoặc các từ khóa from (tương đương 0%) và to (tương đương 100%).

@keyframes slide-in {
    0% {
        transform: translateX(-100%);
        opacity: 0;
    }
    50% {
        transform: translateX(10%);
        opacity: 0.5;
    }
    100% {
        transform: translateX(0);
        opacity: 1;
    }
}

Lưu ý về tương thích trình duyệt: cần sử dụng tiền tố nhà cung cấp cho @keyframes (ví dụ: @-webkit-keyframes).

6.3.2. Áp dụng Keyframes với thuộc tính animation

Sau khi định nghĩa keyframes, bạn có thể áp dụng hoạt ảnh cho phần tử bằng các thuộc tính animation:

  • animation-name: Tên của @keyframes được sử dụng.

  • animation-duration: Thời gian hoạt ảnh chạy (ví dụ: 2s, 500ms).

  • animation-timing-function: Tốc độ hoạt ảnh (tương tự transition-timing-function).

  • animation-delay: Thời gian chờ trước khi hoạt ảnh bắt đầu.

  • animation-iteration-count: Số lần hoạt ảnh lặp lại (ví dụ: infinite cho vô hạn, hoặc một số nguyên).

  • animation-direction: Hướng của hoạt ảnh (normal, reverse, alternate, alternate-reverse).

  • animation-fill-mode: Cách hoạt ảnh áp dụng kiểu trước và sau khi chạy (none, forwards, backwards, both).

  • animation-play-state: Trạng thái phát (running, paused).

Thuộc tính viết tắt animation:

.animated-box {
    width: 100px;
    height: 100px;
    background-color: orange;
    animation: slide-in 3s ease-out 1s infinite alternate forwards;
    /* Tương đương:
    animation-name: slide-in;
    animation-duration: 3s;
    animation-timing-function: ease-out;
    animation-delay: 1s;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    animation-fill-mode: forwards;
    */
}

Thẻ: css HTML Web Development CSS3 Selectors

Đăng vào ngày 2 tháng 10 lúc 17:13