Web 2: chụp X-quang trang web đầu tay

Bài này giúp bạn hiểu rõ việc ngồi gõ phím lọc cọc vừa rồi của bạn đã làm ra trang web đầu tay ở bài 1 như thế nào:

  • Cách xây dựng bố cục HTML cho trang dự định làm
  • Sử dụng CSS để chỉnh bố cục và trang trí
  • Vì sao các lập trình viên khá bối rối trước CSS?

Mở file bai1.html của bạn ra xem nội dung bằng Notepad Plus Plus, và đồng thời cũng dùng trình duyệt Web mở ra để xem hiển thị trang web. Chúng ta bắt tay vào phân tích.

1. Phần HEADER

Có element HEADER bọc ngoài, nó không có thuộc tính nào, bên trong là element IMG. Element IMG này có 1 thuộc tính bắt buộc src và 3 thuộc tính thường dùng: width, height, alt.

Mọi hình ảnh trên máy tính nói chung, hình ảnh trên trang web nói riêng, cho dù cho người xem thấy hình dáng trông thế nào đi nữa thì khi lưu thành file máy tính hình ảnh cũng luôn là hình chữ nhật (bạn hiểu như một tấm lưới có các ô).

Với những hình ảnh (mà mắt bạn xem thấy) như hình tam giác, tròn, cong uốn lượn, bát giác,… gì đó là do màu sắc ngoài viền, chỗ cần ẩn sử dụng màu “trong suốt” nên không nhìn thấy, bản chất hình ảnh vẫn là hình chữ nhật.

Phần header

Element IMG nếu không có thuộc tính src có giá trị là URL dẫn đến file hình ảnh thì xem như nó vô dụng, không đạt mục đích hiện hình ảnh trên trình duyệt web. Khi bạn tạo element IMG mà không có src thì xem như “mất căn bản” trầm trọng.

Trình duyệt cần có widthheight để hiển thị hình ảnh được nhanh, mượt. Nếu không có width, height hình ảnh vẫn hiển thị được nhưng trình duyệt web tốn thời gian tính toán, nạp trang bị giật lag trông quá thiếu chuyên nghiệp đến ngáo ngơ. Đặc biệt, trong lĩnh vực SEO, Google đánh giá thấp IMG không có width, height.

Giá trị của width, height là số nguyên dương. Số nguyên dương này thể hiện kích thước tính bằng đơn vị điểm ảnh pixel của hình ảnh. Nếu bạn chưa từng biết pixel (thường viết tắt là px) là gì, đọc bài này.

Thuộc tính alt thì sao? Alt hiển thị dòng chữ khi hình ảnh vì lý do gì đó không hiện lên màn hình để người duyệt web hiểu được cái hình đề cập là gì. Ngoài ra, với những người dùng khiếm thị, trình duyệt sẽ đọc to dòng text giá trị của alt giúp cho họ hiểu được rằng hình minh hoạ ở đó nghĩa là đang đề cập đến điều gì, dù họ không thể nhìn thấy.

Các trình duyệt và máy tìm kiếm luôn đánh giá cao mọi hình ảnh có thuộc tính alt kèm giá trị là chuỗi văn bản mô tả ngắn về hình ảnh, hiểu đơn giản: “tốt cho SEO”. Giá trị của alt là một cụm từ mô tả ngắn gọn về ảnh. Ví dụ: alt=“Hoàng hôn trên biển Nha Trang” được đặt ở một IMG hình ảnh chụp hoàng hôn trên biển Nha Trang.

Cuối HEADER có element HR có thuộc tính class mang giá trị gap. HR mặc định là một thước kẻ ngang khi hiển thị trên màn hình, nó có ý nghĩa phân chia nội dung, ví dụ bạn có nhiều bài thơ trên một trang web, tiêu đề, tác giả không quá nổi bật khi nhìn khó biết bài thơ nào kết thúc ở đâu, hãy dùng HR để giúp người đọc dễ nhận biết.

Thuộc tính class có giá trị gap có ý nghĩa gì ở đây? Nào, giờ dùng Notepad Plus Plus mở file D:\MyWeb\css\style.css ra xem, bấm Ctrl + F.gap để tìm cho nhanh. Thực ra, HR có class là gap này không hoàn toàn thuộc HEADER, đơn giản nó chỉ là một phân cách trông các thành phần trên web có khoảng không hở, tạo sự thông thoáng khi xem.

Gap của HR

Haha, cái gì thế này? Bên HTML gap chỉ là gap, còn bên CSS lại mọc đâu ra thêm dấu chấm đứng dính liền trước chữ gap, thành .gap? Mọc ra như này là không có gì lạ, đó là quy tắc viết do CSS quy định khi diễn tả một selector

Selector là một khái niệm khá phức tạp để nắm vững, và tui cũng không biết trong tiếng Việt nên gọi là gì nên tự nghĩ ra một cụm từ giúp bạn dễ hiểu “selector được hiểu là một hoặc một nhóm element được chỉ định”. Ngay lúc này bạn chỉ cần nhớ có 3 kiểu viết selector:

Kiểu 1: dùng tên thẻ (tag name) làm selector

Tên thẻ làm selector

Style (kiểu dáng) trong rule (là cái khối có dấu cong sừng trâu mở và đóng trên hình). Tên thẻ được viết “trần truồng” (ví dụ: a, p, div, h2, span, quote, section) mà không có thêm thứ gì khác vây quanh nó, ngoại trừ sau nó là một khoảng cách (bấm phím dài space bar) và dấu sừng trâu mở (open curly bracket) để bắt đầu khối rule của CSS.

Kiểu 2: dùng giá trị của thuộc tính ID để làm selector

Giả sử bạn có một DIV và DIV này có thuộc tính id (thuộc tính này kiểu số căn cước công dân của bạn vậy, thì DIV cũng có thể có :D ), mã HTML của nó: <div id="left-box">Hộp nằm bên trái</div>. Giờ đây, bạn viết một rule trong CSS để đầy khối này trôi về bên trái, và có viền cho khối:

Sử dụng id làm selector

Vậy, khi dùng id (từ nay gọi tắt “dùng id” để chỉ giá trị id, không phải chữ id) để làm selector trong CSS, hãy thêm dấu thăng ngay phía trước nó vì nếu quên, selector sẽ bị hỏng vì bị hiểu đó là thẻ.

Kiểu 3: dùng giá trị của class làm selector

Một element có attributeclass, giá trị này ta tự đặt, ta sẽ lấy cái giá trị này (sau đây gọi tắt là “dùng class” để chỉ giá trị class) làm selector khi viết các rule trong CSS. Ví dụ như sau:

Lấy class làm selector

Khi dùng class làm selector, bên rule CSS ta sẽ phải thêm dấu chấm ngay phía trước tên class, nếu quên, sẽ sai.

Còn có kiểu phối hợp, nhưng đó là việc nâng cao, chưa bàn vội.

Thú vị nè: bạn có thể dùng nhiều selector có chung một rule, lúc này các selector cách nhau bởi dấu phẩy như bạn đã thấy minh hoạ ở Kiểu 1, khối rule cuối cùng, ở hình bên trên.

Ghi nhớ:

  • Từ nay tui dùng lẫn lộn các từ như áp style, áp rule hoặc áp CSS cho element ABC bạn cần hiểu rằng ý là một element nào đó có một rule mà selector là chỉ định đến nó. Ví dụ: khi tui nói, đoạn văn này có chữ màu xanh lá cây. Bạn lập tức biết rằng có cái gọi là <p class="color">Đoạn văn của tui</p> và bạn có CSS được viết: .color { color: green; } ở đâu đó. Các cách gắn CSS khác sẽ sớm học sau đây.

  • Không bao giờ có 2 thuộc tính giống nhau cho cùng một element, nếu thuộc tính giống nhau xem như bị lỗi, trình duyệt sẽ xử lý sai. Ngắn gọn: mỗi element chỉ dùng 1 thuộc tính duy nhất 1 lần. Tức không bao giờ có 2 class, 2 width, 2 alt, 2 id,… mỗi thuộc tính chỉ xuất hiện 1 lần trong 1 element cụ thể mà thôi.

  • Một số trường hợp một thuộc tính có nhiều giá trị thì các giá trị này cách nhau bởi dấu cách space (gõ phím dài trên bàn phím). Ví dụ: class=“red-text yewllow-background border-bold” cho thấy thuộc tính class có chứa 3 giá trị.

  • Thuộc tính trong HTML được đề cập khi tra cứu tiếng Anh hãy dùng HTML attribute. Không dùng từ property (ies - số nhiều) vì cũng là “thuộc tính” trong tiếng Việt nhưng mang ý nghĩa khác. Khi dùng CSS, thuộc tính lại là property, tra cứu hãy CSS property, vì CSS attribute là vô nghĩa.

  • Từ nay trở đi, tui nói dùng id, dùng class, dùng alt, dùng src,… vân vân, những cái mà là attribute trong HTML ấy, bạn luôn hiểu rằng lúc đó dùng giá trị của nó chứ hổng phải chính nó. Ví dụ: dùng class right cho element ASIDE, nghĩa là có cái element <aside class="">Blah blah</aside> được viết thành <aside class="right">Blah blah</aside>

Dài dòng quá sức rồi, tóm lại là có cái element HR mà selector được tạo theo cách 3 ở trên, tức là sử dụng class làm selector. Do vậy mà gap đã thành .gap

Kết thúc phần này bạn thử element HR chỉ còn đứng chơi vơi <hr> mà không có class gì xem sao? Nó có tạo một đường kẻ ngang như cây thước hay không? Bật mí: HR chính là viết tắt của Horizontal Ruler (thước kẻ ngang) đó.

2. Phần NAV (tức menu)

Một menu chính trên trang thường được tạo vởi element NAV (viết tắt của từ navigation section).

Phần NAV

Bên trong NAV trực tiếp là một elemenent UL (danh sách không thứ tự, Unordered List), element UL không thể đứng “chơi vơi đít vịt” được mà bên trong nó sẽ phải có những item được tạo thành bởi các element LI (viết tắt của List).

Bên trong thẻ LI là thẻ A, thẻ A hầu như đều có thuộc tính href nhận giá trị là một URL. Nếu bạn chưa có tạo các rule CSS, khi thử mở xem trang web trên trình duyệt, chắc chắn menu nằm theo chiều dọc, các mục sẽ lần lượt xuống dòng. Tại sao lại vậy? Tại vì mặc định thẻ LI có kiểu hiển thị là block, mà bạn đọc đâu đó tui đã nói qua rằng block là… chiếm hết chiều ngang dù cho nó có width chỉ bằng 1% width của element cha mẹ đi nữa.

Hãy tận dụng AI để xem giải thích về cái cách một số element hiển thị mặc định kiểu block này, gọi là block-level element, tui chụp màn hình giải thích, bạn xem:

Block-level là gì

Block-level áp dụng

Theo tui, AI giải thích như trên là ổn, tui đã kiểm chứng lại tài liệu.

Muốn các mục của menu xếp chiều ngang, tất nhiên sẽ phải làm cách nào đó khác mặc định hiển thị. Trong quá khứ, khi CSS còn ở phiên bản cũ, ban có thể sẽ áp dụng thuộc tính float cho LI và/ hoặc kêt hợp với display: inline-block; để làm các mục xếp hàng ngang.

Ngày nay, cách làm: đặt display: flex; cho UL, ngay lập tức “bỗng nhiên” các LI con của nó nằm theo chiều ngang ngay.

Hầu hết các thuộc tính của các element đều là class. Khi nhìn vào các giá trị của class bạn bắt đầu hiểu rằng dường như người làm web có thể tự đặt được theo ý thích mà không phải thuộc lòng từ một danh sách được quy định nào đó. Thật vậy, bạn tự đặt được các tên (giá trị) cho thuộc tính class. Tuy nhiên cần nhớ nhanh vài điều sau về giá trị cho class:

  • Luôn bắt đầu bằng chữ cái mà không phải con số vì con số là sẽ bị trình duyệt hiểu sai. Ví dụ: mot-la-ma thì được, nhưng 1-la-ma là sai.

  • Không được dùng khoảng cách hoặc ký tự đặc biệt vì khoảng cách xem như class có nhiều giá trị khác nhau, còn ký tự đặc biệt khiến trình duyệt không thể hiểu được. Để dễ đọc, bạn có thể dùng ký tự dấu trù - hoặc dấu gạch dưới _ thay khoảng cách. Ví dụ: class=“canh-le-phai” rất OK, nhưng class=“canh-lề-phải” là hỏng bét.

  • Nên viết chữ thường cho giá trị của class. Ví dụ: class=“stronger-text” là OK, nhưng class=“Lower-Case” là không nên, dù không sai.

  • Tham khảo thêm về các phương pháp trong CSS để biết cách đặt class sao cho… ra dáng một chút.

Ghi nhớ: những chữ viết dài tiếng Anh được đặt trong ngoặc là để tui giải thích thêm cho bạn đọc hiểu và có thể tra cứu dễ dàng về các element hơn khi cần mô tả theo ngôn ngữ con người dùng trên máy tìm kiếm. Trong HTML thì element không có hình thức viết ngắn hoặc viết dài đâu nhé. Bạn học thẻ/ element thế nào viết thế ấy. Tức là A, UL, DIV, SECTION, ASIDE, SPAN,… mà không có các hình thức viết dài của các từ này.

Thực hành:

  • Mở file style.css tìm các class: top-menu-wrapper, top-menu, top-menu-item xem các rule có gì? Thử thay đổi giá trị của một phát biểu trong rule và lưu lại file rồi quay trở về trang web bấm phím F5 xem chúng thay đổi ra sao? Bạn sẽ bật lại: có biết gì đâu mà thay đổi? OK, đọc bài này về sau có một số cái được cung cấp, từ những “nguyên liệu” đó bạn quay lên đoạn này để “quậy tưng bừng” file style.css của bạn.

  • Tự tra cứu về inline-level content CSS trên Google để xem AI tổng hợp thông tin. Hãy so sánh với block-level đề cập bên trên, cố nhớ một số element chính trong 2 nhóm để có thể sử dụng ngay khi bắt tay vào làm bất kỳ trang web nào sau này mà không cần phải “mỗi cái lại mỗi tra cứu”.

  • Làm những điều tui khuyến khích làm trong các đoạn thực hành này sẽ giống với một đứa trẻ vọc đồ chơi, bạn tiến bộ bằng cách chơi mà bạn không thể tưởng tượng được đâu.

3. Phần MAIN, nơi trình bày nội dung chính và 2 cột lề

Mở trang Bài 1 ra xem thấy rằng KACBT đang đề cập đến dòng code 27 đến 130. Nhiều dòng trong số này chỉ là trích đoạn cuốn sách “Đường chân trời đã mất”, đơn giản là nội dung văn bản của các element P, chẳng phải code HTML nào.

Vậy nên, KACBT cắt tỉa hết nội dung, chỉ còn cái khung giúp dễ “soi chiếu”, giải thích các element, attribute bên HTML và property bên CSS.

Bọc bên ngoài là element MAIN có class là middle, khiến bạn nghĩ đến nó làm cái gì đó “giữa”, ta qua bên file style.css xem thử rule của nó là gì:

Main là flex

Bạn đã biết kiểu hiển thị của DIV mặc định là block nếu không trong CSS không có rule nào định nghĩa lại, nghĩa là block là một khối chữ nhật, có thể chứa nội dung bên trong, tuỳ bên trong là block, inline-block hoặc inline mà trình duyệt Web sẽ xếp đặt vị trí theo chuẩn của W3C đặc tả.

Trong trường hợp này, MAIN được đặt lại display: flex; nghĩa là bật chế độ Flexbox, nói dễ hiểu hơn đó là bên trong nó những block sẽ sắp xếp lần lượt mặc định theo chiều ngang, hình dung như sau:

Chia bố cục flexbox

Nếu theo mặc định là các khối sẽ xếp theo chiều dọc thì không thể bố trí được các element SECTION, ARTICLE, ASIDE như khung sườn thiết kế hoạch định ban đầu, chính vì thế cái display: flex; vừa làm là để “hoá giải” việc này, giúp 2 DIV nằm kề nhau theo hàng ngang dễ dàng.

Vậy, tui đã thực hiện việc bẻ phần MAIN ra làm đô: DIV có class middle-left và DIV có class là middle-right. Thử lược bỏ “ruột” ta còn lại 2 DIV đó trông như sau:

Div đầu tiên trong MAIN

Div thứ 2 trong MAIN

Một tác dụng hay ho của Flexbox đó là dễ thực hiện thiết kế tuỳ biến. Khi màn hình nhỏ hơn, có thể cho element đang nằm bên phải được “bẻ xuống” nằm bên dưới element bên trái.

Trong DIV middle-left được xẻ làm đôi để chứa SECTION bên trên, ARTICLE bên dưới, 2 cái này ngăn nhau bởi HR (mục đích cho thoáng, cho đẹp). Tui cũng nhồi vào bên trong nội dung để trông nó có gì đó hiển thị chứ nếu chỉ là những hình chữ nhật khô khan e rằng việc học là trang web quá tẻ nhạt, sớm bỏ cuộc.

Tương tự, DIV middle-right giờ đây có thêm H1 bên trên ASIDE để làm tiêu đề, đó là một dạng thêm thắt theo ý đồ người thiết kế.

Đi lòng vòng chút chơi, giờ lại quay lên đoạn mã của SECTION đầu tiên của cột trái middle-left, đoạn mã:

Hình trên, SECTION middle-left-book-covers chứa những hình bìa cuốn sách, nhưng không trực tiếp là cha của IMG. Đầu tiên có H2 làm tiêu đề, nội dung của H2 này là chữ Section mà lẽ ra nên là chữ gì đó có ý nghĩa, nhỉ? Chữ Section giúp bạn dễ đối chiếu với cái hình ảnh wireframe ban đầu ở Bước 2 Bài 1.

DIV book-gallery là nơi thực sự chứa các hình ảnh bìa sách, vẫn chưa trực tiếp, mà bên trong nó có tới 8 DIV con, mỗi DIV con mới trực tiếp chứa IMG. Khi mở qua bên style.css, tìm .book-gallery.book-cover xem thử:

Style cho các bìa sách

DIV book-gallery được gọi là khối chứa/ hộp chứa (container). Đặt width chiếm 100% chiều rộng của khối cha mẹ nó (tức khối SECTION middle-left-book-covers

Các DIV (8 cái) con của book-gallery có class là book-cover đều có chiều rộng, cao như nhau, rộng bằng 183px và cao 275px (hình chữ nhật đứng / portrait), các DIV này thụt lề 5px (để tạo khoảng hở giữa chúng).

Các DIV con của DIV book-gallery được định lại kiểu hiển thị là inline-block, nhận được ưu điểm của 1 element có cách hiển thị inline đó là có khả năng nằm cạnh nhau mà không phải xuống hàng, nhưng cũng tận dụng được đặc điểm của element có cách hiển thị block đó là có thể thiết lập chiều rộng, chiều cao.

Viết style kiểu trên tui tạm gọi là kiểu xưa xử xừa xưa, khi bạn tra cứu trên mạng, có thể gặp chữ legacy. Sau 2012, những ai làm UI/UX hoặc lập trình front-end nhìn vào rule như trên sẽ ngơ ngác. Họ có thể viết lại, hiện đại hơn:

Dùng flexbox

Bạn cũng thử Save As file style.css ra làm một bản sao để thực hành việc thay đổi. Đây là những thực hành nhẹ nhàng nhưng quan trọng giúp cho bạn có thêm chút kinh nghiệm về dàn bố cục cho các element.

Ở điểm trên có thể gây thắc mắc cho bạn, ngay cả tui cũng chưa đủ trình để “biết thế nào là tốt nhất”, một phần do thói quen. Bạn cần tỉnh táo, đừng bắt chước hệt như tui, hãy xem liệu có cần thiết phải bọc lồng các element vào nhau hay không. Vấn đề bọc lồng mấy cấp element đó là suy nghĩ, phác thảo ý tưởng về thiết kế, khi các cấp element quá ít, nó có thể mất đi sự linh hoạt khi sử dụng CSS, áp style. Nhưng nếu lồng element nhiều cấp một cách không cần thiết lại làm cho cấu trúc HTML trở nên rối rắm, phức tạp một cách không cần thiết, làm cho trang web nặng nề, nạp chậm và để đọc mã, sửa chữa.

Các element IMG nằm bên trong DIV chính là những hình bìa cuốn sách, đây chính là những bản in được phát hành của cuốn sách đang đề cập, nhưng được phát hành ở các nước khác nhau, ở các thời điểm khác nhau. Chứng tỏ, đây cũng là một cuốn sách khá ăn khách, bán chạy.

Tương tự như việc “truy tìm” class middle của MAIN trong file style.css để xem các rule nó làm gì, bạn hãy lần lượt theo các element trên, viết ra từng class và xem trong file style.css để thử có hiểu các rule đó làm gì? Tui sẽ chỉ giải thích một số cài như là ví dụ, còn lại thì sẽ phải tự tìm kiếm, tra cứu trên mạng và thực hành bằng cách thử thay thông số để nắm rò “cái này là cái gì”, và “nó tác động ra sao” đối với vệc trình bày, định dạng các element trên trang.

Phần “soi tia X” để khám phá xem DIV middle-right và thành phần con của nó như ASIDE để dành cho bạn tự thực hiện như bài tập. Có những chỗ nào không thông, chức năng comment bên dưới bài viết là nơi để bạn gửi thắc mắc.

Lồng ghép “ăn nói đạo lý” chút chơi 😼

Phần này để thấy rằng KACBT viết bài hướng dẫn tự học còn rất kém. Lẽ ra bạn được xem một trang web mẫu hoàn chỉnh và sẽ nhìn vào đó như tấm bản đồ để làm theo, cách ấy hợp lý hơn. Đàng này, KACBT viết lăng nhăng khiến bạn cùng KACBT chui vào rừng để rồi chỉ… thấy cây mà hổng thấy rừng đâu hết, lạc lối như chim chích ham vui.

Mỗi người có một kiểu tiếp cận vấn đề khác nhau, các của KACBT khiến nhiều người sớm bỏ cuộc, nhưng nếu bạn có trí tò mò của trẻ em, cứ vọc chơi thoải mái, bạn sẽ tiến xa. Còn nếu bạn nghĩ bạn là một người lớn, có trí tuệ thuộc loại khá thích mang lý luận của người lớn ra đòi hỏi sự rõ ràng, hiểu rõ ý nghĩa mới bắt tay,… e rằng bạn đã bỏ cuộc, té sấp mặt với những bài viết hết sức lùng nhùng kiểu này.

Phần này khá đơn giản, chẳng có gì để nói, chỉ là hiển thị một dòng để tổng kết lại trang web này là để giới thiệu một cuốn sách, chỉ vậy mà thôi. Ở đây dùng SUMMARY để cho có vẻ là “web ngữ nghĩa” một chút.

Footer làm chân trang

Bạn cũng tra các class của các element này để hiểu chúng làm gì, không hiểu gì cũng không sao nhưng cố đặt câu hỏi trong đầu đề sớm tìm lời giải đáp.

Phần phân tích trang web đã tạm xong. Nhưng nếu chỉ như vậy, bạn hoàn toàn chưa thể làm được gì ngoài việc ngồi đó và nhìn mớ code với niềm hoang mang sâu sắc. Do đó, KACBT mở rộng đoạn sau dài lê thê, bạn đọc vài lần để hiểu thêm về HTML, CSS hoạt động độc lập và phối hợp ra sao.


5. Tra cứu tên, công dụng, giá trị của các property trong CSS

Để nhớ hơn 200 property và các giá trị đi kèm của chúng là điều kinh dị với một người bình thường nên tui không định khuyên bạn làm điều đó. Bạn cần biết tra cứu trong danh sách sắp xếp theo ABC và thực hành nhiều đế biết áp dụng khi làm một trang web.

Gú gồ AI đã giúp tổng kết lại thành 5 nhóm property trong CSS như sau:

Các thuộc tính CSS 1

Các thuộc tính CSS 2

Các thuộc tính CSS 3

Các thuộc tính CSS 4

Các thuộc tính CSS 5

6. Một ít lý thuyết “bỏ túi” về CSS

Có 3 cách nhúng CSS vào một tài liệu HTML. Cách 2 (dùng external CSS) theo bài này) là cách được khuyên dùng.

Cách 1: (internal CSS hoặc embedded CSS) sử dụng trong nội dung tài liệu HTML, các luật (rules) CSS được đặt ở phần HEAD, bên trong thẻ STYLE như minh hoạ:

Cấu tạo CSS rule

Hình trên có chữ sai, propertie không tồn tại, nó phải là properties cho số nhiều hoặc property cho số ít. Thành thật xin lỗi các bạn vì KACBT lười chỉnh sửa trên hình vì máy tính không có phần mềm chỉnh đồ hoạ mạnh kiểu như Photoshop, dùng công cụ thô sơ quá cực nhọc.

Những cái khối ở trên gọi là luật (rule) CSS. Mỗi luật gồm ít nhất 1 phát biểu bên trong cặp dấu ngoặc sừng trâu. Mỗi phát biểu có cấu tạo gồm: thuộc tính, dấu hai chấm, giá trị thuộc tính, dấu chấm phẩy kết thúc phát biểu.

Chú ý: ở CSS, thuộc tính được đề cập trong ngữ cảnh CSS là property mà không phải attribute như bên HTML. Vì sao có sự khác biệt này, các bài sau học về DOM, về JavaScript tui sẽ giải thích thêm.

Cách này gọi là internal CSS. Đây là cách sử dụng cho trang web nhỏ, ít CSS, chỉ khoảng 100 dòng trở lại và/ hoặc trong quá trình học, thực hành cơ bản về HTML, CSS như hiện đang ở bài viết này.

Cách 2: (external CSS) sử dụng một file có nội dung là các rule CSS nhúng vào trong HTML. Cách này gọi là external CSS. Đây là cách khuyên dùng trong thực tế khi làm trang web.

Quay lại Bài 1 bạn sẽ thấy ở phần HEAD có:

Dòng có CSS

Dòng 8 ở hình trên chính là dòng gắn nội dung file CSS vào HTML. Kha khá số lượng học viên ban đầu chăm chỉ viết CSS nhưng quên gắn vào hoặc tên file sai nên CSS không có tác dụng. Bạn cần tránh mắc lỗi cơ bản ngớ ngẩn này.

Rule CSS hoặc CSS rule là đều chính nó mà thôi, tại vì ở đây viết tiếng Việt cho nên nó đổi lộn xộn như vậy, nhưng bạn vẫn hiểu. Trong ngữ cảnh bạn đọc bài tiếng Anh, họ sẽ dùng CSS rule.

Chú ý: nội dung file CSS bắt đầu bằng một rule nào đó, hoàn toàn không có thẻ STYLE nào, néu không trình duyệt sẽ không hiểu. Lỗi có thẻ STYLE thường do copy code từ cách 1 qua mà quên xoá đi.

Hãy thử mở file D:\MyWeb\css\style.css ra soạn gì đó, nếu chưa bíêt gì thử nhập y chang vầy:

Sử dụng CSS ở file ngoài

Chữ external này có thể hiểu theo 2 nghĩa trong lúc làm trang web cho nên bạn cần chú ý external đang nói nghĩa là gì.

  • Nghĩa 1: nguồn từ bên ngoài, nhưng cùng domain, cùng cấp thư mục với “dự án website đang thực hiện” (hoặc đơn giản là một trang HTML bạn đang làm). Nói cách khác, extenal HTML, external CSS, external JavaScript lúc này là ám chỉ 1 file của bạn, không phải trực tiếp trong file HTML hoặc CSS hoặc JavaScript mà đang soạn thảo nhưng được nhúng (embed, include, import) vào file bạn đang soạn thảo.

  • Nghĩa 2: vì World Wide Web chạy trên hạ tầng Internet cho phép tham khảo đến tài nguyên bên ngoài website của bạn và có thể nhúng vào HTML của bạn để sử dụng, nên lúc này external được hiếu rằng bạn có các thẻ LINK, thuộc tinh src của thẻ SCRIPT, lệnh @import trong file CSS của bạn trỏ đến nguồn tài nguyên (resources) bên ngoài website của bạn, nằm trên máy chủ server nào đó trên Internet. Trường hợp này thường thấy trong thực tế dưới dạng các framework, các library được phân phối như là public CDN.

Cách 3: gọi là inline-style, nhập trực tiếp các rule vào các element ngay trên file HTML, dùng thuộc tính style kèm các giá trị để nạp các rule CSS:

Dùng inline CSS

Cách này không khuyên dùng vì nó thuộc loại bá đạo, chỉ dùng để chữa cháy hoặc khi không tìm ra các rule được định nghĩa ở đâu để chỉnh sửa.

Những khoảng cách sau dấu 2 chấm phân tách property và giá trị hoặc sau dấu chấm phẩy là không cần thiết nhưng nếu tồn tại vẫn không gặp lỗi mà chỉ giúp đọc mã dễ dàng hơn (như bạn đã thấy ở hình trên. Nếu chỉ có 1 property duy nhất, ta có thể lược bỏ dấu chấm phẩy. Ví dụ: <p style="text-align:right">Đoạn văn của tui</p>

Chú ý quan trọng: bạn không được lẫn lộn chuyện in-line CSS (hay in-line style) đang đề cập, ý nói cách viết CSS như là giá trị của attribute style với việc mặc định một số element có kiểu hiển thị là in-line (một số khác hiển thị kiểu block). Hai in-line này hoàn toàn là 2 chuyện khác nhau không có gì để lẫn lộn hết trơn. Nếu bạn lẫn lộn, nghe như có một ông tên là Nguyễn Văn The, bạn nói với người ta rằng ông đó là mạo từ The trong tiếng Anh :D thì hết… nước chấm.

Cấu trúc của một rule CSS:

Cú pháp rule CSS

Mẹo: để tránh sai sót khi tạo một rule, cách nhanh nhất là gõ se rồi cặp dấu sừng trâu mở - đóng ngay liền sau. Tiếp tục, mang con trỏ vào giữa cặp dấu sừng trâu, bấm Enter xuống dòng và làm ngay một phát biểu declare đầu tiên dạng: p: v; xem hình dưới:

Một rule CSS

Sau đó sửa se thành selector của bạn, p là propery, còn v là giá trị tương ứng. Luôn kết thúc một phát biểu bằng dấu chấm phẩy.

Đơn vị đo (chiều dài, rộng, cự ly) các element được chia làm 2 nhóm:

  • Đơn vị tuyệt đối: cm, mm, in, px, pt, pc. Ngoại trừ px thường dùng trong thiết kế web để xem trên màn hình, còn lại chỉ dùng trong việc làm trang web xuất ra định dạng có liên quan đến in ấn ra vật liệu như giấy, vải.

  • Đơn vị tương đối: em, ex, ch, rem, vw, vh, vmin, vmax, %. Các đơn vị này tính tỉ lệ trong mối tương quan giữa các element.

Những đơn vị được in đậm bên trên là đơn vị thường dùng trong thực tế thiết kế web.

7. Thực hành canh chỉnh element bên trong element

Giả sử có 2 DIV lồng nhau: 1 DIV làm khung chứa hình ảnh, và 1 DIV chứa hình ảnh. Code như sau:

Khung ảnh chứa ảnh

Mặc định khi chưa có dòng CSS nào, khung viền không thấy đâu, chỉ thấy một cái ảnh đứng đó mà thôi. Sau đây KACBT sẽ dùng giá trị của class để gọi các element DIV, tức sẽ gọi containerphoto để chỉ 2 DIV đang xét.

Giờ đây, ý tưởng của chúng ta: khung ảnh màu Chestnut (#954535), rộng 300px, cao 400px. Viết ngay vài dòng và xem kết quả bên phải:

CSS khung ảnh

Ảnh nằm trong khung kiểu này có vẻ không ổn cho lắm? Ta sẽ đem nó vào giữa khung cho đẹp. Có vài cách thực hiện khác nhau, KACBT sẽ thử xem sao.

Cách 1: cách này tận dụng việc hiển thị kiểu grid của DIV bọc ngoài (tức container) và tự động tính toán lề của hình ảnh (tức photo), mã như sau:

CSS canh giữa - giữa

Bạn thử sửa code và xem kết quả xem sao nhé!

Cách 2: tận dụng việc có thể canh giữa theo chiều dọc với những thứ liên quan table.

CSS canh giữa - giữa vertical

Cách này có vẻ hơi “dị”, hơi kiểu chày cối làm lấy được. Tuy nhiên, đó chính là “nét nghệ thuật” trong thực hiện các canh chỉnh CSS.

Cách 3: hiện đại, hiệu quả nhất hiện nay. Đoạn CSS sau cho bạn nhìn thấy điều đó:

Canh giữa flex box

Cách này không cần viết rule liên quan gì đến photo, chỉ cần container với 3 dòng “thần thánh” khoanh đỏ ở hình trên là đủ để “ruột” (element con) của nó nằm ở giữa.

Còn thêm vài cách khác, để dành cho bạn khám phá, đó là điều thú vị khi chơi với CSS.


Bạn có thể chọn 1 trong 3 cách trên hoặc tự nghĩ ra cách khác sau khi tra cứu, thực hành CSS vì không dừng 3 cách như trên mà thôi, miễn sao kết quả cuối hình năm giữa khung như sau:

Hình nằm giữa khung

Cũng nhớ rằng cái vùng màu xám là không liên quan gì CSS đang thực hiện, đó là vì nền trang web bạn đang đọc bài này là nền màu trắng nên KACBT muốn các hình minh hoạ nổi lên dễ phân biệt cái nào là nền trang web, cái nào đang là ảnh minh hoạ.

Cho dù cách nào đi nữa, kết quả bạn đạt được phải ổn định, nhất quán trên các trình duyệt thông dụng khác nhau như Google Chrome, Microsoft Edge, Mozilla Firefox, Apple Safari. Nếu chỉ chạy được trên 1-2 loại trình duyệt, xem như chất lượng CSS của bạn chưa đạt yêu cầu vậy.

Lời nhắc: bạn viết CSS kiểu quái dị gì đi nữa, cần hướng đến điều mà trong ngành lập trình phần mềm gọi là Sanity check.

Chuyện canh chỉnh element bên trong element là một trong những kỹ thuật thuộc loại “hại não” mà cần phải thực hành nhiều, tra cứu trên mạng, thậm chí tham gia vài thử thách, cuộc thi để nâng cao tay nghề. KACBT từng trải qua một thời kỳ vật vã với Internet Explorer trong việc canh chỉnh CSS nên cũng có vài thứ giúp bạn “đi tắt” nhanh, sau đây là cách canh chỉnh tạm gọi là theo ý muốn element bên trong element:

  • Đặt position: relative; cho khối cha mẹ (thường gọi là container) để cho phép các khối con có thể có toạ độ.

  • Các khối (element) con luôn chọn element có block-level, đặt position: absolute; và có ít nhất 2 trong 4 property: top, right, left, bottom.


8. Xưởng thực hành: nơi bạn “nấu món lẩu” HTML, CSS

a) Tạo hình tròn: ý tưởng là chiều rộng và chiều cao bằng nhau và đặt border-radius bằng 50%, và nhứ overflow cần hidden để cắt phần thừa ra:

Hình tròn CSS

b) Đặt những hình vuông bên trong một khối chữ nhật 7 sắc cầu vồng:

Khối vuông trong khối chữ nhật

Lần lượt bạn “múa phím” ra những chuỗi mã HTML, CSS. Giờ đây KACBT trình bày rất lộn xộn nhưng với mớ lý thuyết ở trên, hẳn bạn cũng đã biết làm thế nào cho chuẩn chỉnh:

Khối trong khối

Thêm các rule:

Khối trong khối absolute

Điểm mấu chốt cần ghi nhớ nằm lòng trong kỹ thuật đặt các element dạng khối theo con có toạ độ chính xác bên trong khối cha mẹ đó là khối cha mẹ (xem .seven-squares bên trên) phải có position: relative; và các khối con có position: absolute;. Nếu khối cha quên đặt thành relative thì các khối con chạy lung tung cả lên hoặc bạn không cách nào thiết lập được vị trí của nó.

c) Nghệ thuật font chữ: trình bày chữ thường liên quan đến màu, font chữ, kiểu dáng (đậm, nghiêng, đậm và nghiêng, gạch chân):

Nghệ thuật font chữ

Nghệ thuật chữ đậm, nghiêng

d) Màu nền và ảnh nền: một element có thể lấp đầy bằng màu nền hoặc hình nền.

Hình nền và màu nền

Liên quan đến màu nền, hình nền có khá nhiều thông tin, cần thực hành nhiều, bạn cần tham khảo ở MDN. Một điểm cần lưu ý nhất về ảnh nền: dùng ảnh PNG có nền trong suốt để làm nền cho những hình uốn lượn, trang trí, có thể kết hợp với màu nền để tạo nền bắt mắt.

Một điều thú vị đó là có thể dùng background-image: linear-gradient(to right, red,orange,yellow,green,blue,indigo,violet); để tạo nền 7 sắc cầu vồng.

e) Hộp chữ nhật và mối tương quan giữa chúng: việc canh chỉnh các khối element tuy không khó nhưng vì trông kết quả giống nhau nhưng cách làm khác nhau, khiến những người mới học trở nên hoang mang vì không hiểu sao làm được tốt ban đầu, khi bố trí lại code trở nên một mớ hỗn mang. Hãy xem ví dụ sau:

Các khối chữ nhật

Margin, padding của element

Để các hộp không bị phình ra khi có nội dung bên trong, ta cần thiết lập thuộc tính box-sizing: border-box;

Margin, padding làm nhiều sẽ biết lúc nào chọn cái nào. Ban đầu chỉ cần ghi nhớ: padding là phần đệm vào nằm bên trong element đang được xét, còn margin là phần lùi lề, nằm bên ngoài biên của element được xét.


9. Vì sao các lập trình viên ghét hoặc sợ CSS?

Có lẽ vì khía cạnh “art” của nó. Bạn là một coder đang viết mã frontend cho trang web, bạn lập luận rất logic, tra cứu CSS rất chuẩn chỉnh,… nhưng khi chạy với trình duyệt, những gì hiện lên khác xa mong đợi và chẳng thể hiểu tại sao. Bạn vò đầu bứt tai và vô vọng để rồi tìm đến các trang như StackOverflow, Reddit hoặc bất cứ ở đâu trên mạng, nơi người ta thảo luận về CSS để cầu cứu, xin sự trợ giúp…

Loay hoay với CSS

Một sáng đẹp trời, bạn nhận ra CSS hoá ra không phải là ngôn ngữ lập trình. Vì thế cho nên cái gọi là “tư duy lập trình” bạn luyện tập miệt mài giờ mang áp dụng vô CSS hầu như… không ăn thua. Thử gõ vào thanh tìm kiếm Google cụm từ programmers dislike CSS xem có vui?