Xem xét một số cách tạo ảnh động cho đường viền trong CSS
Đặt đường viền
Có một số phương thức để đặt đường viền trên một phần tử: border
, outline
và box-shadow
. Như đã trình bày chi tiết trong bài viết 3 phương thức CSS để thêm đường viền phần tử của Stephanie Eckles, mỗi phương pháp đều có ưu và nhược điểm riêng, đặc biệt là khi tạo ảnh động cho đường viền. Lý do chính khiến bạn không sử dụng border
CSS thích hợp là cho mục đích tạo ảnh động.
Gần đây, tôi đã chú ý đến một bài viết có tên Ảnh động đường viền CSS tuyệt vời, trong đó tác giả Coco đã khám phá thêm nhiều lựa chọn. Bằng cách chèn nội dung được tạo bằng ::before
và ::after
, chúng tạo ra một đường viền giả sau đó được tạo ảnh động.
Điều nổi bật nhất đối với tôi là các hình ảnh động hỗ trợ được sử dụng trong bài viết. Các chú thích này thực sự giúp giải thích chính xác những gì đang được thực hiện để đạt được hiệu ứng mong muốn.
Cả lớp màu trắng và các đường có màu đều là nội dung được tạo. Bằng cách làm mờ và làm rõ lớp màu trắng, bạn có thể thấy rõ cách các lớp xếp chồng lên nhau và cách hoạt động của ảnh động.
Giữ lại mô hình hộp
Một nhược điểm của việc sử dụng Nội dung được tạo để mô phỏng đường viền là bạn sẽ có một mô hình hộp bị hỏng: nội dung hiện có thể che khuất đường viền giả vì "đường viền" đó được vẽ bên dưới. Để giảm thiểu, bạn phải áp dụng border-width
mong muốn làm padding
.
Để có đường viền thực sự – và do đó giữ lại hoạt động của mô hình hộp – bạn có thể sử dụng nhiều nền, sau đó kéo giãn ra khu vực đường viền.
Khái niệm cơ bản
Hãy bắt đầu bằng cách tạo đường viền chấm và thêm nhiều nền.
/* Size of the border */
--border-size: 0.5rem;
/* Create a dotted border */
border: var(--border-size) dotted lime;
/* Create two background layers:
1. A white semi-transparent
2. A layer with the colored boxes
*/
background-image:
linear-gradient(to right, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.5)),
conic-gradient(
from 45deg,
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
)
;
Định cỡ nền bằng background-origin
Như bạn có thể thấy, có điều gì đó thú vị đang xảy ra với nền ở đây: chúng được vẽ vào đường viền, nhưng conic-gradient
có vẻ như không đúng. Đây thực sự là hành vi dự kiến: theo mặc định, hình nền không vẽ vào đường viền vì nguồn gốc của hình nền là padding-box
của phần tử. Xét cho cùng, để tạo đường viền, hình nền đã đặt sẽ được lặp lại trong chính đường viền đó, tạo ra hiệu ứng hình ảnh kỳ lạ.
Để giải quyết vấn đề này, bạn cần kéo giãn nền để nền cũng chiếm kích thước của đường viền. Bạn có thể thực hiện việc này theo cách thủ công bằng cách kéo giãn và định vị lại nền, nhưng tốt nhất là sử dụng thuộc tính background-origin
để định cỡ nền so với border-box
.
/* Manually add or offset the size of the border where needed */
background-position: calc(var(--border-size) * -1) calc(var(--border-size) * -1);
background-size: calc(var(--border-size) * 2 + 100%) calc(var(--border-size) * 2 + 100%);
background-origin: border-box;
Chỉ cần thêm một phần này vào là mọi thứ trông sẽ đẹp hơn nhiều:
Thu nhỏ lớp nền trắng bằng background-clip
Giờ đây, nền đã chiếm hết không gian, nên lớp bán trong suốt cần được thu nhỏ lại. Thay vì lại phải xử lý background-size
, bạn có thể làm theo cách dễ dàng hơn: sử dụng background-clip
và đặt thành padding-box
. Bằng cách đó, nền sẽ không còn được vẽ bên dưới khu vực đường viền.
background-clip:
padding-box, /* Clip white semi-transparent to the padding-box */
border-box /* Clip colored boxes to the border-box (default) */
;
Cuối cùng, hãy tạo đường viền transparent
để có hiệu ứng đầy đủ.
border: 0.3rem dotted transparent;
Hoạt ảnh
Để khôi phục ảnh động của đường viền, bạn có thể thao tác với góc bắt đầu của conic-gradient
.
--angle: 0deg;
conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
);
Nhờ @property, việc này trở nên dễ dàng trong các trình duyệt hỗ trợ thuộc tính này:
@property --angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
@keyframes rotate {
to {
--angle: 360deg;
}
}
Khi kết hợp tất cả, mã sẽ trở thành:
Nội dung thưởng: border-image
Một phương pháp đã đề cập trước đây để vẽ đường viền chuyển màu là sử dụng CSS border-image
.
Điều này giúp mã đơn giản hơn vì bạn không cần xử lý các nền chồng chéo. Bạn có thể áp dụng ảnh động theo cách tương tự như trước.
/* Create a border */
border: 0.5rem solid transparent;
/* Paint an image in the border */
border-image:
conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
) 1
;
Tuy nhiên, bạn sẽ nhận thấy một số tính năng không còn hoạt động với phương pháp này:
border-image
không tuân theoborder-radius
; nó sẽ luôn giữ nguyên hình chữ nhật.- Khi đặt
border-image-slice
thành fill (điền),border-image
không được vẽ bên dưới tập hợpbackground
mà ở trên cùng. Điều này có thể gây phiền toái nếu bạn muốn nền có độ trong suốt bán phần.
Kết luận
Có rất nhiều cách để tạo hiệu ứng động cho đường viền trong CSS. Tuỳ thuộc vào trường hợp sử dụng, bạn có thể sử dụng một trong hai phương thức này.