+11

Sửa CSS không phải của bạn?

1. Mở bài

Khi sử dụng bất cứ một thư viện UI nào đó như Material UI, Ant Design, Polaris, PrimeUI, ... để đỡ phải code lại mọi thứ từ đầu thì chúng ta sẽ thường nảy sinh nhu cầu sửa lại style có sẵn của các thư viện này do yêu cầu từ phía design hoặc đơn giản vì bạn thấy style mặc định xấu. Để làm được điều này, chúng ta có thể sử dụng một vài cách như sau:

2. Ghi đè style

1. Cách làm chính thống

Trở thành một chú ong chăm chỉ, ngồi đọc kĩ document để xem thư viện mà bạn đang sử dụng có hỗ trợ sẵn cách sửa đổi style của component mà bạn mong muốn hay không. Nếu có thì chúng ta cứ thể mà sử dụng như trường hợp dưới đây:

// Thay đổi padding của children element của component Overlay
<template>
    <OverlayPanel :pt="{ content: { style: 'padding: 16px' } }">
        // ...
    </OverlayPanel>
</template>

hoặc

// Đổi màu primary của button mặc định trong thư viện
import { createTheme } from '@mui/material/styles';

const theme = createTheme({
  palette: {
    primary: {
      light: '#757ce8',
      main: '#3f50b5',
      dark: '#002884',
      contrastText: '#fff',
    },
  },
});

Với cách làm nói trên ta sẽ hạn chế tối đa được các vấn đề có thể phát sinh khi ta ghi đè style của thư viện vì đang sử dụng phương án được thư viện cung cấp sẵn rồi. Nhưng để làm được việc nói trên thì chúng ta phải đi tìm trong document xem có không và đôi khi không có thì công cốc.

2. Sử dụng inline style

Trong một số trường hợp nếu bạn sử dụng các thư viện của Vue hoặc đang maintain một dự án đang sử dụng Bootstrap từ xưa thì đây là một trong các lựa chọn mà bạn có thể sử dụng thay vì phải thêm file css mới hoặc viết thêm ra file css. Với các project đang sử dụng Bootstrap và muốn đổi màu button default của Bootstrap thì ta có thể làm như sau:

<button type="button" class="btn btn-default" style="background-color: #a855f7">Default</button>

Bằng cách thêm inline style như trên ta đã đổi được màu button qua màu tím mà không lo có bất cứ ảnh hưởng nào đến các thành phần khác trên trang web của chúng ta cả. Còn đối với Vue thì ta có thể sử dụng tính năng fallthrough attribute để thêm style cho component mà thư viện cung cấp:

<Button label="Submit" style="background-color: #a855f7" />

Lưu ý nếu bạn thấy có nhiều inline-style đang sử dụng thì mình khuyên bạn nên biến nó thành một class và mang đống inline style đó vào trong class ở một file css nào đó để tránh code của bạn nhìn trông chán không muốn nói

3. Ghi đè style thông qua sử dụng lại class của thư viện

Giả sử khi ta sử dụng một component đến từ một thư viện nào đó và thu được kết quả như sau:

Tuy nhiên bằng một nhu cầu hoặc một phép màu nào đó mà có một vị trí trên trang chúng ta lại muốn cái button ấy có màu tím mộng mơ. Nhưng mà đời không như mơ vì thư viện chúng ta đang dùng không có hỗ trợ sẵn màu tím mà chúng ta mong muốn và thêm nữa chúng ta cũng lười dở document ra đọc chỉ vì chúng ta muống một button màu tím. Cách làm gọi nhanh ở đây là ta sẽ tiến hành inspect button của chúng ta lên bằng Devtool và thấy:

<a href="/publish/post" class="btn btn-primary ml-2 float-right text-uppercase hidden-md-down">
    <i aria-hidden="true" class="fa fa-pencil"></i> Viết bài
</a>

Ngay lập tức đầu chúng ta nảy số và quyết định ghi đè background-color mặc định trong class btn-primary thành màu tím như sau:

.btn-primary {
    background-color: #a855f7
}

Và thu được kết qủa như mong muốn mà không phải đọc document gì hết:

Tuy nhiên với cách làm nói trên thì bạn sẽ phải lưu ý một số vấn đề như sau:

  • Vị trí đặt file css của bạn so với vị trí đặt file css của thư viện: Nếu bạn đặt file css của thư viện bên dưới file css mà bạn viết thì khả năng cao nó sẽ không ghi đè được style của thư viện:
import 'custom-style.css';
import 'element-ui.css';
  • Không có wrapper để cô lập phần style mà bạn đã custom với style của toàn bộ trang web. Giả sử bạn cho cái button nói trên ở màn login như sau:

Kết quả thu được nhìn quá là oke, bạn push code và deploy ngay lập tức để kéo task mình thành Done rồi còn lượn ra ngoài uống trà đá với anh em bạn bè. Ấy vậy mà vừa ngồi xuống đến nơi thì bạn nhận được noti là PM, PO, Tester và ae trong team mention đang mention bạn liên tục trên Slack, mở nó ra và đập vào mắt bạn là dòng chữ:

Đúng vậy vì cái class btn-primary mà bạn vừa thay đổi ấy được dùng chung cho toàn bộ các primary button trên trang nên việc thay đổi nói trên của bạn đã đổi bộ nhận diện thương hiệu của bạn sang màu tím. Để tránh tình trạng này xảy ra, thì cách đơn giản nhất là ta hay bọc đoạn code của bạn trong một class khác như sau:

.login-form {
    .btn-primary {
         background-color: #a855f7
    }
}

Rồi sau đỏ thêm cái class login-form nói trên của bạn cho cái thẻ nào đó bọc bên ngoài button mà bạn muốn đổi màu thôi và lần này ta có thể kéo task Done mà không lo việc sửa đổi nho nhỏ này ảnh hưởng đến một chỗ nào đó trong hệ thống mà chúng ta đếch biết đến.

4. !important

Đôi khi cuộc sống không như là chúng ta mong muốn, việc ta sử dụng cách làm nói trên đếch được vì nhiều lý do ta cũng đếch biết được thì đây là lúc mà !important vào cuộc. !important một từ tưởng chừng chỉ là một tiếng anh bình thường thôi nhưng ẩn sau bên trong nó lại là một sức mạnh to lớn mà không phải ai cũng biết cách sử dụng. Nó đã và đang góp một phần không nhỏ giúp FE Dev chúng ta hoàn thành được công việc của mình trước khi deadline đến và có thể yên giấc ngủ ngon mỗi đêm vì biết rằng đoạn chỗ style mà mình mới thêm !important buổi chiều đã nhìn giống hệt Figma, tester đã chuyển ticket đó thành Done và Sprint đã thành công mỹ mãn.

Còn với các BE Dev thứ thiệt bị dí đi sửa style thì !important đôi khi giống như bản năng để sửa chữa chỗ style mà mình thêm vào những nó không nhận ấy giống như việc ta đập điều khiển TV khi bấm mà nó không nhận.

Xét trường hợp sau:

<div class="m-10">
  <p class="text-blue">Hello world</p>
</div>

<style>
.m-10 p {
  color: green;
}
.text-blue {
  color: blue;
}
</style>

Như bạn có thể đoán được mặc dù class text-blue nằm ở dưới, tuy nhiên dòng chữ Hello world ở đây của chúng ta lại có màu đỏ thay vì xanh còn lý do tại sao thì mình sẽ không đề cập đến ở đây. Tuy nhiên nếu bạn chỉ đơn giản muốn nó phải thành màu xanh thì rất đơn giản, ta chỉ cần thêm !important và kết thúc một ngày làm việc:

.text-blue {
  color: blue !important;
}

Bằng cách làm nói trên ta đang nói với css của chúng ta là cái color: blue này rất là quan trọng nên hãy ưu tiên nó hơn những màu khác và ta nhận được thứ mình muốn:

.Nhưng nếu mọi thứ không chỉ đơn giản như ta nói ở trên thì sao? Nếu class text-blue của chúng ta phức tạp hơn:

.text-blue {
    font-size: 24px;
    line-height: 1.45;
    text-align: center;
    font-weight: 600;
    text-decoration: underline;
    color: blue !important;
}

Và trong file global.css của chúng ta có một class như này:

text-error {
  text-decoration: line-through !important;
  color: red !important;
  font-weight: black !important;
}

Tuy nhiên thứ tự import của css lại là:

import 'global.css';
import 'blue-text.css'

Giả sử chúng ta có một đoạn script nào đấy, làm một điều gì đấy để khi cần ta thêm class thành text-error nhưng vị mọi thứ đều important nên color trong text-blue sẽ được ưu tiên hơn nên ta sẽ thu được cái style nửa nọ nửa kia như này:

5. .class.class

Có thể với trường hợp đơn giản chỉ đổi màu thì ta có thể dùng script thêm inline style: style="color: red !important" nhưng nó sẽ ổn nếu ta chỉ thêm một đến hai inline-style mà thôi còn nếu nhiều hơn thì mệt lắm đừng làm vậy. Một solution mà mình có thể nghĩ ra đó là thay vì để color: blue !important thì ta có thể khai báo class text-blue dạng stack như sau:

.text-blue.text-blue {
    font-size: 24px;
    line-height: 1.45;
    text-align: center;
    font-weight: 600;
    text-decoration: underline;
    color: blue;
}

Và ta vẫn đạt được kết quả như mong muốn:

Khi thêm class text-error:

Ở đây khi ta khai báo dạng .text-blue.text-blue thì các property trong class text-blue của chúng ta sẽ có độ ưu t iên cao hơn so với:

.m-10 p {
    color: green;
}

Tương tự nếu ta muốn có độ ưu tiên cao hơn nữa thì ta chỉ đơn giản viết 3 lần class text-yellow như sau .text-yellow.text-yellow.text-yellow và thu được kết quả mù mắt không thấy gì hết:

3. Kết bài

Mình nặn mãi mới được có tí nội dung như này thôi, đọc lại thấy hơi lủng củng lan man nhưng mà văn kém nên cũng chả biết sửa sao cho hợp lý đành cứ publish lên mong được cá bạn ủng hộ.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.