Ảnh động đường viền CSS

Xem 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 cho một phần tử: border, outlinebox-shadow. Như đã trình bày chi tiết trong 3 phương pháp 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 một CSS border thích hợp là dùng cho mục đích ảnh động.

Ảnh động viền sử dụng outline-offset của Kevin J. Powell

Một bài viết thu hút sự chú ý của tôi gần đây là Ảnh động đường viền CSS tuyệt đẹp, trong đó tác giả Coco đã khám phá nhiều lựa chọn khác. Bằng cách chèn nội dung đã tạo bằng ::before::after, chúng sẽ tạo một đường viền giả và sau đó sẽ trở thành ả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. Chúng 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 quả mong muốn.

Ảnh động đường viền sử dụng nội dung do Coco tạo

Cả lớp trắng và đường màu đều là nội dung được tạo. Bằng cách làm mờ và làm mờ lớp màu trắng, bạn sẽ thấy rõ cách các lớp này xếp chồng 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 đã tạo để bắt chước đường viền là bạn sẽ gặp phải mô hình hộp bị hỏng: giờ đây nội dung 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 mà bạn muốn làm padding.

Để có đường viền thực sự và do đó vẫn giữ được các chức năng của mô hình hộp, bạn có thể sử dụng nhiều nền sau đó kéo dài ra vùng đường viền.

Thông tin cơ bản

Hãy bắt đầu bằng cách tạo một đườ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 kích thước nền bằng background-origin

Như bạn có thể thấy có điều gì đó hài hước đ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ư hoàn toàn sai. Đây thực sự là hành vi có chủ đích: theo mặc định, hình nền không vẽ vào đường viền vì nguồn gốc của chúng là padding-box của phần tử. Rốt cuộc thì để tạo đường viền, các 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à đặt lại vị trí nền, nhưng tốt nhất là sử dụng thuộc tính background-origin để định kích thước nền theo border-box.

Hỗ trợ trình duyệt

  • 1
  • 12
  • 4
  • 3

Nguồn

Không nên
/* 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%);
Nên
background-origin: border-box;

Một tính năng bổ sung này làm cho mọi thứ trông đẹp hơn nhiều:

Thu hẹp lớp nền trắng bằng background-clip

Với các nền hiện đang chiếm toàn bộ không gian, lớp bán trong suốt cần được thu nhỏ lại một lần nữa. Thay vì sử dụng background-size lần nữa, có một cách dễ dàng hơn để thực hiện việc này: sử dụng background-clip và đặt thành padding-box. Bằng cách đó, nền không còn được vẽ bên dưới vùng đường viền nữa.

Hỗ trợ trình duyệt

  • 1
  • 12
  • 4
  • 5

Nguồ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ể chỉnh sửa 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 sẽ trở nên dễ dàng hơn trong các trình duyệt hỗ trợ:

Hỗ trợ trình duyệt

  • 85
  • 85
  • 16,4

Nguồn

@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes rotate {
  to {
    --angle: 360deg;
  }
}

Tất cả kết hợp lại, mã sẽ trở thành như sau:

Nội dung phụ: 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.

Hỗ trợ trình duyệt

  • 16
  • 12
  • 15
  • 6

Nguồn

Tính năng này giúp đơn giản hoá mã hơn vì bạn không cần phải 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 đây.

/* 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 phù hợp với phương pháp này:

  • border-image không tuân theo border-radius; nó sẽ luôn là hình chữ nhật.
  • Khi thiết lập border-image-slice để tô màu nền, border-image không được vẽ bên dưới background đã đặt mà ở trên cùng. Việc này có thể gây rắc rối nếu bạn muốn nền bán trong suốt.

Sắp đóng

Có vô số cách để tạo ảnh động cho đường viền trong CSS. Tuỳ thuộc vào trường hợp sử dụng, bạn có thể khai thác một trong hai cách này.