Thủ thuật CSS (P1)

Trần Đức Lĩnh

CSS có thể học trong vòng 2-3 tháng, nhưng muốn giỏi thì đó là một chặng đường.

Tổng hợp lại từ các trang viblo.asia - kipalog của tác giả (Hà Hữu Tín).


Mục lục.

1) style="border-radius:...;".

Nếu để ý kỹ thì trên các trang Facebook có những button được bo tròn 2 bên, vậy làm như thế nào để được như vậy?
Bạn muốn dùng border-radius:50%???.
Không được đâu, trừ khi width = height may ra nó là hình tròn, số còn lại là dạng ellipse mà thôi.

Như trên, nếu chiều dài (height) = 40px thì thiết lập giá trị bằng height/2 = 20px hoặc height = 40px có lẽ tạm thời sẽ đúng.
Nhưng tăng lên 100px mọi lập luận phía trên đều sai.

Theo nguồn stackoverflow có giải thích thì border-radius có 2 giá trị X và Y nằm trên trục tạo nên hình ellipse và xác định hình dạng của góc.
Nếu bặn đặt 1 giá trị duy nhất thì được áp dụng cho tất cả các góc border-radius: x == border-radius: x/x.
Thay vì sử dụng giá trị tương đối %, ta nên dùng giá trị tuyệt đối px để làm điều này.
Khi sử dụng 999px bán kính đường tròn chắc chắn là 999px, quy tắc đặt ra được áp dụng sẽ là các đường cong chồng lên nhau sẽ làm giảm bán kính của vòng tròn xuống 1/2 kích thước của cạnh nhỏ nhất. Bạn có thể xem hình ảnh bên dưới.

Code mẫu.

.br-radius{
    display: block;
    margin: 0 auto;
    position: relative;
    top: 35%;
    width: 300px;
    height: 120px;
    background: linear-gradient(to right, #00b7ff, #a890fe);
    box-shadow: 20px 20px 30px #a8a8a8;    
    border-radius: 999px;
}

2) Image background reponsive.

Muốn dùng background-img ở dạng reponsive thường thì sẽ rất khó khăn. Thường thì sẽ dùng thuộc tính CSS cho như sau.

img {
    max-width: 100%;
    height: auto;
}

Nếu muốn height được scale tự động thì chúng ta cần dùng đến kỹ thuật được nhắc đến trong Bootstrap có tên là embed video, họ áp dụng nó để làm reponsive cho video.

.wrap-image
    .image
.wrap-image {
    border: 1px solid #000;
}
.image {
    max-width: 100%;
    width: 500px;
    height: 350px;
    background: url("http://via.placeholder.com/500x350") no-repeat 0 0;
    background-size: contain;
}
/* .image{width} == @media(max-width) */
@media (max-width: 500px) {
    .image {
        height: 0;
        /* - (.image{height}/.image{width})*100%  = padding-bottom - */
        padding-bottom: 70%; 
    }
}

3) Phần tử cuối cùng không bị ảnh hưởng khi dùng "selector:not()".

Nếu bạn không muốn item cuối cùng không ảnh hưởng đến các item phía trên, bạn có thể làm như sau.

<div class="controll item">A</div>
<div class="controll item">AB</div>
<div class="controll item">ABC</div>
.controll {
    margin-bottom: 2px; 
    width: 200px;
    height: 20px;
}
.item {
    background: #ff0000;
    border-right: 1px solid black;
}
.item:last-child {
    border-right: 0;
    background: #ffffff;
}

Nếu dùng Selector:not() thì sẽ như thế này

.controll {
    margin-bottom: 2px; 
    width: 200px;
    height: 20px;
}
.item:not(:last-child) {
    background: #ff0000;
    border-right: 1px solid black;
}

Đã giảm được 4 dòng code lại còn sạch đẹp.

4) Select Items Using Negative nth-child.

Chọn các phần tử ở các vị trí bao gồm cố định 1 vị trí, các vị trí chẵn, lẽ, 1 khoảng nào đó, loại trừ 1 khoảng nào đó...

/* Chọn 1 phần tử cố định */
:nth-child(2) {};
/* Chọn các phần tử chia hết cho 2 */
:nth-child(2n) {};
/* hoặc */
:nth-child(even) {};
/* Chọn các phần tử không chia hết cho 2 */
:nth-child(2n+1) {};
/* hoặc */
:nth-child(odd) {};
/* Chọn các phần tử trong khoảng từ 1 - 10 */
:nth-child(-n+10) {};
/* Không chọn các phần tử trong khoảng từ 1 -10 */
:not:nth-child(-n+10) {};
/* Chọn các phần tử từ 8 - 16 */
:nth-child(n+8):nth-child(-n+16)

5) Các ô trong table có chiều rộng bằng nhau.

Các cột trong table đều bằng nhau chỉ với 1 dòng code.

table {
    table-layout: fixed;
}

6) Tránh nhầm lẫn khoảng cách giữa 2 component liền kề.

Các trình duyệt sẽ tính khoảng cách giữa 2 component như thế nào khi khối A được đặt margin-bottom: 30pxkhối B được đặt với margin-top: 20px???
Có phải khoảng cách sẽ bằng 50px???

  • Đáp án sẽ là tổng khoảng cách chỉ bằng 30px của khối A.

Tớ cố ý cho khối B margin-bottom: 60px thì tổng khoảng cách sẽ bằng 60px.
Vậy nếu khoảng cách giữa 2 component với nhau, khoảng cách nào lớn hơn sẽ được ưu tiên làm giá trị chung, nếu 2 khoảng cách đều bằng nhau, thì sẽ ưu tiên cho giá trị đã được khai báo trước đó.

Lưu ý: Trong các dự án, nên sử dụng 1 hướng duy nhất (top) hoặc (bottom), giúp bạn dể kiểm soát được khoảng cách giữa các component với nhau.

7) Xuất hiện khoảng trắng dưới image.

Sử dụng vertical-align: middle; cho img, giúp mất khoảng trắng không cần thiết.
Chi tiết vertical-align

8) Ôi!!! pointer-events tuyệt cú mèo.

Bạn có thể kham khảo mã nguồn tại đây.

<div class="container">
    <p>Hello</p>
    <button>Hover</button>
</div>
button {
    pointer-events: auto;
}

.container {
    pointer-events: none;
}
.container:hover p {
    color: red;
}

9) Flexbox với margin-left: auto.

Sử dụng margin-left: auto trong trường hợp user ở bên phải.

image-title-here

<header>
    <div class="logo"></div>
    <div class="menu"></div>
    <div class="user"></div>
</header>
div {
    width: 30px;
    height: 30px;
    background: red;
}
header {
    display: flex;
}
.user {
    margin-left: auto;
}

10) Giá trị initial.

Giá trị thuộc tính width có mỗi giá trị mặc định khác nhau.

  • width = auto
  • min-width = 0
  • max-width = none

Với mọi thuộc tính trong CSS, chỉ cần set giá trị mặc định về dạng initial cho từng thuộc tính mà không cần phải nhớ quá nhiều thứ.
( IE11 không hỗ trợ )

11) Sử dụng placeholder với input.

form {
    display: flex;
    align-items: center;
    flex-direction: column;
    justify-content: center;
}
input:placeholder-shown {
    border: 3px solid red;
}
textarea:focus, input:focus{
    outline: none;
}
  • ::placeholder sẽ tác động vào phần bên trong của style input như font-size, color.
  • :placeholder-shown sẽ tác động tới bề ngoài style của input kể cã border...

12) Cách mà border thừa kế trong thuộc tính từ color.

Với thuộc tính border màu của nó chính là inherit, khi bạn khai báo border: 1px solid thì màu border-color được lấy từ thuộc tính color, nếu không tự định nghĩa color thì màu mặc định sẽ là black.
Vì lý do này, code sẽ được ngắn gọn hơn.

<button>Hover...</button>
button {
    color: rgb(82, 198, 236); //blue
    border: 1px solid;
}
button:hover {
    color: rgb(243, 196, 108); //orange
}

13) display: flex làm méo icon khi text quá dài.

...
Nàng công chúa bong bóng. Yêu chàng mưa lơ đãng. Dường như bên nhau quên giận hờn. Dù có những lúc mưa vô tình. Làm buồn công chúa bong bóng nhiều lần.

Cách khắc phục đơn giản là định danh {flex: 1;} cho phần tử chứa đoạn text đó.

<div class="flex_icon">
        <img src="/icon.png" alt="">
        <div class="text">Nàng công chúa bong bóng. Yêu chàng mưa lơ đãng.
        Dường như bên nhau quên giận hờn. Dù có những lúc mưa vô tình.
        Làm buồn công chúa bong bóng nhiều lần.</div>
</div>
.flex_icon {
    width: 400px;
    display: flex;
}
img {
    width: 50px;
    height: 50px;
}
.text {
    flex: 1;
}

Kết thúc phần 1.