- vừa được xem lúc

Tìm hiểu về clip-path trong CSS

0 0 417

Người đăng: Nguyễn Quang Vinh

Theo Viblo Asia

1. Introduction

Thuộc tính clip-path tạo ra một vùng cắt nơi nội dung bên trong nó được hiển thị và nội dung bên ngoài nó bị ẩn đi.

Đây là một ví dụ cơ bản về clip-path: circle.

.card { background-color: #77cce9; clip-path: circle(80px at 50% 50%);
}

Với việc sử dụng clip-path, vùng hiển thị chỉ là vòng tròn màu xanh lam (#77cce9).

Bất cứ phần nào bên ngoài vòng tròn là vô hình.

Đây là một hình ảnh động cho thấy một đoạn cắt của vòng tròn trong ví dụ trước.

2. The Coordinate System

Trước khi đi sâu vào chi tiết của clip-path, cần đề cập đến cách thức hoạt động của hệ trục tọa độ.

Điểm gốc là điêm góc trên cùng bên trái với trục x hướng sang phải và trục y hướng xuống dưới.

Với ý nghĩ đó, hãy lấy một ví dụ đơn giản để xem cách một phần tử sử dụng clip-path.

Trong ví dụ bên dưới, vùng bị cắt là một hình tròn có kích thước 100px và tâm của nó được đặt ở vị trí 0,0 (top left).

Lưu ý rằng người dùng chỉ có thể nhìn thấy khu vực được đánh dấu (màu xanh lam đậm).

Phần còn lại của hình tròn được cắt bớt (cliped).

Câu hỏi đặt ra là, làm thế nào chúng ta có thể hiển thị toàn bộ vòng tròn?

Đó là việc chúng ta cần thay đổi các điểm trục x và trục y.

Tâm của vòng tròn được đặt 100px từ bên trái và 100px từ trên cùng.

Bây giờ bạn đã hiểu cách hoạt động của hệ tọa độ, tôi sẽ giải thích các giá trị có thể có cho thuộc tính clip-path.

3. The Clip-Path Values

3.1 Inset

Giá trị inset xác định một hình chữ nhật inset.

Chúng ta có thể kiểm soát bốn cạnh, giống như chúng ta xử lý margin hoặc padding.

Trong ví dụ sau, .card có độ dài 20px từ tất cả các cạnh (trên, phải, dưới và trái).

.card { clip-path: inset(20px);
}

Nếu bạn cần điều chỉnh phần chèn từ một trong các cạnh, bạn có thể. Đây là một ví dụ khác:

.card { clip-path: inset(20px 20px 50px 20px); // hoặc: // clip-path: inset(20px 20px 50px); // theo tứ tự là trên - phải - dưới - trái giống như margin hoặc padding
}

The eleent has a 50px inset from the bottom.

.card mới có một inset 50px từ bên dưới.

Một câu hỏi nữa là, liệu chúng ta có thể làm các góc được bo tròn như các block bình thuờng không?

Tất nhiên là có thể nhờ thuộc tính round.

Thêmround <border-radius> có thể bo tròn các góc.

.card { clip-path: inset(20px 20px 50px round 15px);
}

Không chỉ vậy, chúng ta có thể điều chỉnh bán kính cho từng bên một cách riêng biệt.

Bên dưới là một ví dụ với bán kính bằng 0 cho các góc trên cùng bên phải và dưới cùng bên trái.

.card { clip-path: inset(20px 20px 50px round 15px 0);
}

3.2 Circle

Để sử dụng giá trị circle(), chúng ta cần bán kính và vị trí của nó. Đây là một ví dụ:

.card { clip-path: circle(80px at 50% 50%);
}

Bán kính của hình tròn là 80px và nó được định vị 50% trên trục x và 50%1 trên trục y.

3.3 Ellipse

Với ellipse(), chúng ta có thể thiết lập chiều rộng và chiều cao để tạo một hình cắt hình bầu dục.

.card { clip-path: ellipse(100px 80px at center);
}

3.4 Polygon

Giá trị polygon() là giá trị thú vị nhất.

Chúng ta có khả năng kiểm soát nhiều bộ giá trị trục x và trục y khác nhau.

.card { clip-path: polygon(x y, x y, x y, x y);
}

Đây là một ví dụ sử dụng polygon() để cắt một hình chữ nhật.

Lưu ý cách chúng ta ánh xạ từng tập hợp điểm với tọa độ của nó trên các trục.

.card { clip-path: polygon(5% 5%, 95% 5%, 95% 95%, 5% 95%);
}

Chúng ta cũng có thể vẽ các hình phức tạp với nhiều điểm bằng cách sử dụng giá trị polygon.

3.5 Path

Giá trị path() cho phép chúng ta sử dụng một đường dẫn SVG để cắt một khu vực cụ thể.

Hiện tại, việc hỗ trợ các trình duyệt khác nhau còn nhiều hạn chế.

Chúng ta cần sử dụng inline SVG, sau đó sử dụng url() làm giá trị cho clip-path.

<svg class="svg"> <clipPath id="triangle" clipPathUnits="objectBoundingBox"> <path d="M0.05,0.05 h1 v1"></path> </clipPath>
</svg>

Trong CSS, chúng ta cần thêm đường dẫn bằng giá trị url().

.card { clip-path: url("#triangle");
}

Hiện tại, chúng ta đã xem qua lý thuyết về clip-path và các giá trị tổng quát, đã đến lúc áp dụng nó vào thực tế rồi.

(go)

4. Use Cases

4.1 Angled Effect

Trong các trang web hiện đại, bạn có thể đã thấy nhiều mẫu tương tự như hình bên dưới, trên web sẽ có một số phần có nền hơi góc cạnh và có độ dài các cạnh không đều nhau.

Đó là một trường hợp hoàn hảo để sử dụng clip-path

Chúng ta sẽ sử dụng polygon().

.section { clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%);
}

Trong một số trường hợp, việc điều chỉnh 8 số cho giá trị đa giác có thể gây khó chịu.

Vì lý do đó, chúng ta có một mẹo nhỏ đó là phụ thuộc vào trình duyệt để tạo ra hình dạng mà chúng ta muốn.

Đầu tiên, chúng ta cần thêm những điều sau:

.section { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}

Sau đó, chúng ta cần kiểm tra phần đó của DevTools.

Sau khi hoàn tất, hãy lưu ý rằng có một biểu tượng đa giác nhỏ ở phía bên trái của giá trị polygon().

Sau khi nhấp vào biểu tượng đó, chúng ta có thể chỉnh sửa đa giác trong trình duyệt.

Thật tuyệt vời phải không? Gif bên dưới sẽ là ví dụ cho bạn.

4.2 Making The Angle Relative To The Viewport Width

Chúng ta cũng có thể sử dụng CSS calc() kết hợp với CSS viewport unit để tạo góc so với chiều rộng của viewport.

.section { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 5vw), 0 100%);
}
  • Tài liêu tham khảo:

https://kilianvalkhof.com/2017/design/sloped-edges-with-consistent-angle-in-css/

4.3 Multiple Angled Effects

Tôi có một câu hỏi trong đầu về việc liệu chúng ta có cần nhiều phần tử có nhiều góc cạnh không?

Điều đầu tiên tôi nghĩ đến là chỉ cần thêm một lớp box-shadow hoặc border.

Thật không may, chúng cũng sẽ nằm trong phạm vi ảnh hưởng của clip-path, vì vậy ngay cả khi chúng ta thêm box-shadow hoặc border, nó cũng sẽ không xuất hiện như mong đợi.

Trong trường hợp như vậy, giải pháp là sử dụng nhiều phần tử, với mỗi phần tử có một điểm cắt khác nhau. Đây là cách chúng ta có thể làm điều đó.

<div class="hero"> <img src="bg.jpg" alt="" />
</div>
.hero { position: relative; min-height: 350px;
} .hero img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; clip-path: polygon(0 0, 100% 0, 100% 80%, 0 90%);
} .hero:after { content: ""; position: absolute; left: 0; // Đây chính là thuộc tính làm lớp nền bên dưới ở bên d bottom: -20%; z-index: -1; width: 100%; height: 100%; background-color: #4545a0; clip-path: polygon(0 0, 100% 0, 100% 80%, 0 90%);
}

Chúng ta có một phần tử giả có cùng kích thước và đường dẫn clip như phần tử kia.

Sự khác biệt là nó được đặt bên dưới nó với bottom: -20%z-index: -1.

Tôi đã sử dụng giá trị 20% vì nó là kết quả của 100 - 80.

4.4 Reveal On Scroll

Bằng cách sử dụng API IntersectionObserver , chúng ta có thể hiển thị các phần tử nhất định trên trang khi người dùng đang cuộn.

Giá trị clip-path mà tôi thấy hữu ích cho hiệu ứng này là inset.

Lưu ý rằng hình chữ nhật màu xanh có thể hoàn toàn vô hình bằng cách áp dụng inset(50%).

Giá trị làm cho nó vô hình là 50% vì chúng ta đang áp dụng nội dung từ bốn phía.

Nói cách khác, hình chữ nhật được áp dụng từ cạnh đến tâm của hình chữ nhật.

Trong hình bên dưới, inset đang được sử dụng để hiển thị hình ảnh trong khi người dùng đang cuộn.

Với nó, chúng ta có thể làm cho hình ảnh hiển thị bằng cách cuộn.

const images = document.querySelectorAll("img"); function check(entries) { entries.map((entry) => { if (entry.isIntersecting) { entry.target.classList.add("is-visible"); observer.unobserve(entry.target); } });
} const observer = new IntersectionObserver(check);
images.forEach((image) => observer.observe(image));
img { clip-path: inset(50%); transition: 1.2s ease-in;
} img.is-visible { clip-path: inset(0);
}

Nó thực sự đơn giản phải không?

Chúng ta đã tạo một hiệu ứng cuộn đơn giản với một vài dòng CSS và Javascript.

Không chỉ vậy, chúng ta còn có thể kiểm soát hướng của quá trình chuyển đổi do scroll.

Để làm điều đó, chúng ta chỉ cần sử dụng một giá trị từ bốn cạnh.

Ví dụ: nếu chúng ta muốn chuyển đổi từ trên xuống dưới, giá trị dưới cùng phải được chuyển từ 100% sang 0.

Đây là hình ảnh giải thích điều đó.

And here is an interactive demo.

Và đây là một bản demo:

4.5 Hover And Animation Effects

Khả năng tạo hiệu ứng hoverclick với clip-path là vô tận.

Hãy xem xét ví dụ sau.

Những gì chúng ta cần làm là thêm hiệu ứng hover từ một vị trí đã được chỉ định.

Trong trường hợp này, hãy sử dụng giá trị circle().

Để làm cho nó dễ dàng hơn và dễ maintaince hơn, hãy sử dụng các biến CSS.

Bằng cách đó, chúng ta sẽ không trùng lặp toàn bộ clip-path.

Chúng ta sẽ chỉ thay đổi các biến CSS cần thiết.

:root { --pos: left center; --size: 0;
} .stats__item:before { position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: #7777e9; clip-path: circle(var(--size) at var(--pos)); transition: 0.4s linear;
} .stats__item:hover:before { --size: 300px;
}

Gif bên dưới để biết cách hoạt động.

Không chỉ vậy, chúng ta có thể thay đổi vị trí của ảnh động rất dễ dàng.

Tôi đã tạo một bản demo với khả năng thay đổi vị trí từ menu thả xuống.

Nếu bạn muốn tìm hiểu sâu hơn về các hiệu ứng hoạt hình, ông Adam Argyle đã tạo ra một thư viện hoạt hình CSS rất hữu ích dựa 100% vào CSS clip-path.

Tài liệu tham khảo:

https://www.transition.style/

4.6 Ripple Effect

The ripple effect has been popular since the release of Material design. With clip-path, we can easily replicate this effect.

Hiệu ứng gợn sóng đã trở nên phổ biến kể từ khi phát hành Material design.

Với clip-path, chúng ta có thể dễ dàng sao chép hiệu ứng này.

<button class="button"><span>Sign up now</span></button>
.button { position: relative;
} .button span { position: relative; z-index: 1;
} .button:before { content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: #fff; opacity: 0.1; clip-path: circle(0 at center); transition: 0.3s ease-out;
} .button:hover:before { clip-path: circle(100px at center);
}

Complement

Để dễ dàng hơn trong việc sử dụng giá trị clip-path, bennettfeely sẽ giúp bạn làm điều đó

  • Link tham khảo:

https://bennettfeely.com/clippy/

Conclusion

Bên trên là tìm hiểu về thuộc tính clip-path trong CSS, hi vọng giúp ích được cho mọi người trong việc vẽ hay custom lại những giao diện khó

Thank for watching!!!

Reference

Bình luận

Bài viết tương tự

- vừa được xem lúc

Căn giữa các phần tử HTML theo chiều dọc (phần 1)

Bài viết được dịch từ bài Vertical centering of elements in HTML xuất bản ngày 18/01/2015 trên trang Web++. .

0 0 58

- vừa được xem lúc

Căn giữa phần tử trong CSS

1. Theo chiều ngang. Đó có phải là phần tử inline hay inline-* (như text hay links). .

0 0 49

- vừa được xem lúc

99% không biết đến mẹo này khi sử dụng Flexbox CSS

Hello lại là mình đây. Bài viết hôm nay mình sẽ giới thiệu tới mọi người một trick khá hay khi dùng CSS flexbox nhé. 1. Chia layout với flexbox.

0 0 47

- vừa được xem lúc

Vanilla JS Project: Tính tuổi

1. Yêu cầu.

0 0 49

- vừa được xem lúc

1 số UI component và layout hữu ích với Frontend

Giới thiệu. Hôm nay mình xin chia sẻ 1 số Layout và UI component quen mà có lẽ là quen thuộc với nhiều người khi làm dự án, hay bắt gặp trên mạng.

0 0 47

- vừa được xem lúc

Style text css

Giới thiệu. Chào 2021, mình sẽ giới thiệu vài kiểu style cho text màu mè chút cho rực rỡ .

0 0 28