Trang trí hình ảnh lạ mắt: Ma thuật đơn nguyên PlatoThông minh dữ liệu Blockchain. Tìm kiếm dọc. Ái.

Trang trí hình ảnh lạ mắt: Phép thuật đơn nguyên tố

Như tiêu đề đã nói, chúng ta sẽ trang trí hình ảnh! Có một loạt các bài báo khác nói về điều này, nhưng những gì chúng tôi đang đề cập ở đây hơi khác một chút vì nó nhiều thách thức hơn. Các thách thức? Trang trí một hình ảnh chỉ bằng cách sử dụng thẻ và không có gì hơn.

Đúng vậy, không có đánh dấu bổ sung, không có div và không có phần tử giả. Chỉ một thẻ.

Nghe có vẻ khó khăn đúng không? Nhưng đến cuối bài viết này - và những phần khác tạo nên loạt bài nhỏ này - tôi sẽ chứng minh rằng CSS đủ mạnh để mang lại cho chúng ta những kết quả tuyệt vời và ấn tượng bất chấp giới hạn của việc làm việc với một phần tử duy nhất.

Loạt đồ trang trí hình ảnh lạ mắt

  • Phép thuật Đơn nguyên tố - bạn đang ở đây
  • Mặt nạ và Hiệu ứng Di chuột nâng cao (đến ngày 21 tháng XNUMX )
  • Phác thảo và Hoạt ảnh Phức tạp (đến ngày 28 tháng XNUMX )

Hãy bắt đầu với ví dụ đầu tiên của chúng tôi

Trước khi tìm hiểu mã, hãy liệt kê các khả năng tạo kiểu mà không có bất kỳ phần tử phụ hoặc phần tử giả nào. Chúng ta có thể sử dụng border, box-shadow, outline, và dĩ nhiên, background. Có thể trông lạ khi thêm nền vào hình ảnh vì chúng ta không thể nhìn thấy nó vì nó sẽ ở phía sau hình ảnh - nhưng mẹo là tạo khoảng trống xung quanh hình ảnh sử dụng padding và / hoặc border và sau đó vẽ nền của chúng ta bên trong không gian đó.

Tôi nghĩ bạn biết điều gì xảy ra tiếp theo kể từ khi tôi nói về background, bên phải? Đúng, gradients! Tất cả các đồ trang trí chúng ta sẽ thực hiện dựa trên rất nhiều độ dốc. Nếu bạn theo tôi trong một thời gian, tôi nghĩ rằng điều này có lẽ không có gì ngạc nhiên đối với bạn cả. 😁

Hãy quay lại ví dụ đầu tiên của chúng tôi:

img {
  --s: 10px; /* control the size */
  padding: var(--s);
  border: calc(2 * var(--s)) solid #0000;
  outline: 1px solid #000;
  outline-offset: calc(-1 * var(--s));
  background: conic-gradient(from 90deg at 1px 1px, #0000 25%, #000 0);
}

Chúng tôi đang xác định padding và một minh bạch border sử dụng biến --s để tạo ra một không gian xung quanh hình ảnh của chúng ta bằng ba lần biến đó.

Tại sao chúng tôi sử dụng cả hai paddingborder thay vì cái này hay cái khác? Chúng tôi có thể nhận được bằng cách chỉ sử dụng một trong số chúng nhưng tôi cần sự kết hợp này cho gradient của mình bởi vì, theo mặc định, giá trị ban đầu của background-clip is border-boxbackground-origin bằng padding-box.

Dưới đây là minh họa từng bước để hiểu logic:

Ban đầu, chúng tôi không có bất kỳ đường viền nào trên hình ảnh, vì vậy gradient của chúng tôi sẽ tạo ra hai phân đoạn với 1px độ dày. (Tôi đang dùng 3px trong bản trình diễn cụ thể này để dễ nhìn hơn.) Chúng tôi thêm một đường viền màu và gradient vẫn cho chúng ta cùng một kết quả bên trong vùng đệm (do background-origin) nhưng nó lặp lại phía sau đường viền. Nếu chúng ta làm cho màu của đường viền trong suốt, chúng ta có thể sử dụng sự lặp lại và chúng ta sẽ có được khung như ý muốn.

Sản phẩm outline trong bản demo có một phần bù âm. Điều đó tạo ra một hình vuông ở trên cùng của gradient. Đó là nó! Chúng tôi đã thêm một trang trí đẹp mắt vào hình ảnh của mình bằng cách sử dụng một gradient và một outline. Chúng tôi có thể đã sử dụng nhiều gradient hơn! Nhưng tôi luôn cố gắng giữ cho mã của mình càng đơn giản càng tốt và tôi thấy rằng việc thêm một outline tốt hơn theo cách đó.

Đây là một giải pháp chỉ dành cho gradient mà tôi chỉ đang sử dụng padding để xác định không gian. Vẫn là kết quả tương tự nhưng với một cú pháp phức tạp hơn.

Hãy thử một ý tưởng khác:

Đối với cái này, tôi đã lấy ví dụ trước đã loại bỏ outline, và áp dụng một clip-path để cắt gradient ở mỗi bên. Các clip-path giá trị hơi dài dòng và khó hiểu nhưng đây là một minh họa để thấy rõ hơn các điểm của nó:

Trang trí hình ảnh lạ mắt: Phép thuật đơn nguyên tố

Tôi nghĩ rằng bạn có được ý tưởng chính. Chúng tôi sẽ kết hợp hình nền, đường viền, hình cắt và một số mặt nạ để đạt được các loại trang trí khác nhau. Chúng tôi cũng sẽ xem xét một số hoạt ảnh di chuột thú vị như một phần thưởng bổ sung! Những gì chúng tôi đã xem xét cho đến nay chỉ là một cái nhìn tổng quan nhỏ về những gì sắp tới!

Khung chỉ góc

Cái này có bốn gradient. Mỗi gradient bao phủ một góc và khi di chuột, chúng tôi mở rộng chúng để tạo ra một khung đầy đủ xung quanh hình ảnh. Hãy phân tích mã cho một trong các gradient:

--b: 5px; /* border thickness */
background: conic-gradient(from 90deg at top var(--b) left var(--b), #0000 90deg, darkblue 0) 0 0;
background-size: 50px 50px; 
background-repeat: no-repeat;

Chúng ta sẽ vẽ một gradient với kích thước bằng 50px 50px và đặt nó ở góc trên cùng bên trái (0 0). Đối với cấu hình của gradient, đây là minh họa từng bước cho thấy cách tôi đạt được kết quả đó.

Chúng ta có xu hướng nghĩ rằng gradient chỉ tốt cho việc chuyển đổi giữa hai màu. Nhưng trên thực tế, chúng ta có thể làm được nhiều hơn thế với chúng! Chúng đặc biệt hữu ích khi tạo ra các hình dạng khác nhau. Bí quyết là đảm bảo rằng chúng ta có các điểm dừng cứng giữa các màu - như trong ví dụ trên - thay vì chuyển tiếp mượt mà:

#0000 25%, darkblue 0

Về cơ bản, đây là câu nói: “tô màu gradient trong suốt cho đến khi 25% của khu vực, sau đó điền vào khu vực còn lại với darkblue.

Bạn có thể đang vò đầu bứt tai về 0 giá trị. Đó là một chút hack để đơn giản hóa cú pháp. Trong thực tế, chúng ta nên sử dụng điều này để tạo ra sự khác biệt giữa các màu:

#0000 25%, darkblue 25%

Điều đó hợp lý hơn! Màu trong suốt kết thúc ở 25%darkblue bắt đầu chính xác nơi độ trong suốt kết thúc, tạo ra một điểm dừng khó. Nếu chúng ta thay thế cái thứ hai bằng 0, trình duyệt sẽ thực hiện công việc cho chúng ta, vì vậy, đó là một cách hiệu quả hơn một chút để thực hiện nó.

Trong nơi nào đó các đặc điểm kỹ thuật, nó nói rằng:

nếu một màu dừng lại or gợi ý chuyển tiếp có vị trí nhỏ hơn vị trí được chỉ định của bất kỳ điểm dừng màu hoặc gợi ý chuyển tiếp nào trước nó trong danh sách, hãy đặt vị trí của nó bằng vị trí được chỉ định lớn nhất của bất kỳ điểm dừng màu hoặc gợi ý chuyển tiếp nào trước nó.

0 luôn nhỏ hơn bất kỳ giá trị nào khác, vì vậy trình duyệt sẽ luôn chuyển đổi nó thành giá trị lớn nhất đứng trước nó trong khai báo. Trong trường hợp của chúng tôi, con số đó là 25%.

Bây giờ, chúng tôi áp dụng cùng một logic cho tất cả các góc và chúng tôi kết thúc bằng đoạn mã sau:

img {
  --b: 5px; /* border thickness */
  --c: #0000 90deg, darkblue 0; /* define the color here */
  padding: 10px;
  background:
    conic-gradient(from 90deg  at top    var(--b) left  var(--b), var(--c)) 0 0,
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--c)) 100% 0,
    conic-gradient(from 0deg   at bottom var(--b) left  var(--b), var(--c)) 0 100%,
    conic-gradient(from -90deg at bottom var(--b) right var(--b), var(--c)) 100% 100%;
  background-size: 50px 50px; /* adjust border length here */
  background-repeat: no-repeat;
}

Tôi đã giới thiệu các biến CSS để tránh một số dư thừa vì tất cả các gradient sử dụng cùng một cấu hình màu.

Đối với hiệu ứng di chuột, tất cả những gì tôi đang làm là tăng kích thước của các gradient để tạo ra khung hình đầy đủ:

img:hover {
  background-size: 51% 51%;
}

Vâng, nó 51% thay vì 50% - điều đó tạo ra một sự chồng chéo nhỏ và tránh những khoảng trống có thể có.

Hãy thử một ý tưởng khác bằng cách sử dụng cùng một kỹ thuật:

Lần này, chúng tôi chỉ sử dụng hai gradient, nhưng với một hoạt ảnh phức tạp hơn. Đầu tiên, chúng tôi cập nhật vị trí của từng gradient, sau đó tăng kích thước của chúng để tạo khung hình đầy đủ. Tôi cũng giới thiệu nhiều biến hơn để kiểm soát tốt hơn màu sắc, kích thước, độ dày và thậm chí cả khoảng cách giữa hình ảnh và khung hình.

img {
  --b: 8px;  /* border thickness*/
  --s: 60px; /* size of the corner*/
  --g: 14px; /* the gap*/
  --c: #EDC951; 

  padding: calc(var(--b) + var(--g));
  background-image:
    conic-gradient(from  90deg at top    var(--b) left  var(--b), #0000 25%, var(--c) 0),
    conic-gradient(from -90deg at bottom var(--b) right var(--b), #0000 25%, var(--c) 0);
  background-position:
    var(--_p, 0%) var(--_p, 0%),
    calc(100% - var(--_p, 0%)) calc(100% - var(--_p, 0%));
  background-size: var(--s) var(--s);
  background-repeat: no-repeat;
  transition: 
    background-position .3s var(--_i,.3s), 
    background-size .3s calc(.3s - var(--_i, .3s));
}
img:hover {
  background-size: calc(100% - var(--g)) calc(100% - var(--g));
  --_p: calc(var(--g) / 2);
  --_i: 0s;
}

Tại sao làm --_i--_p các biến có dấu gạch dưới trong tên của chúng? Dấu gạch dưới là một phần của quy ước đặt tên mà tôi sử dụng để xem xét các biến "nội bộ" được sử dụng để tối ưu hóa mã. Chúng không có gì đặc biệt nhưng tôi muốn tạo ra sự khác biệt giữa các biến chúng tôi điều chỉnh để kiểm soát khung hình (như --b, --c, v.v.) và những cái tôi sử dụng để làm cho mã ngắn hơn.

Mã có thể trông khó hiểu và không dễ nắm bắt nhưng tôi đã viết loạt ba phần nơi tôi trình bày chi tiết kỹ thuật như vậy. Tôi thực sự khuyên bạn nên đọc ít nhất bài viết đầu tiên để hiểu cách tôi đạt được mã trên.

Dưới đây là hình ảnh minh họa để hiểu rõ hơn về các giá trị khác nhau:

Hiển thị cùng một hình ảnh của hai chiếc xe cổ ba lần để minh họa các biến CSS được sử dụng trong mã.
Trang trí hình ảnh lạ mắt: Phép thuật đơn nguyên tố

Khung tiết lộ

Hãy thử một loại hoạt ảnh khác, nơi chúng tôi hiển thị toàn bộ khung hình khi di chuột:

Tuyệt, phải không? Và nếu bạn quan sát kỹ, bạn sẽ nhận thấy rằng các đường kẻ biến mất theo hướng ngược lại khi di chuột ra ngoài, điều này làm cho hiệu ứng thậm chí còn lạ mắt hơn! Tôi đã sử dụng một hiệu ứng tương tự trong một bài viết trước.

Nhưng lần này, thay vì bao gồm tất cả các phần tử, tôi chỉ bao gồm một phần nhỏ bằng cách xác định height để có được một cái gì đó như thế này:

Đây là đường viền trên cùng của khung của chúng ta. Chúng tôi lặp lại quy trình tương tự ở mỗi bên của hình ảnh và chúng tôi có hiệu ứng di chuột:

img {
  --b: 10px; /* the border thickness*/
  --g: 5px; /* the gap on hover */
  --c: #8A9B0F; 

  padding: calc(var(--g) + var(--b));
  --_g: no-repeat linear-gradient(var(--c) 0 0);
  background: 
    var(--_g) var(--_i, 0%) 0,
    var(--_g) 100% var(--_i, 0%),
    var(--_g) calc(100% - var(--_i, 0%)) 100%,
    var(--_g) 0 calc(100% - var(--_i, 0%));
  background-size: var(--_i, 0%) var(--b),var(--b) var(--_i, 0%);
  transition: .4s, background-position 0s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
}

Như bạn có thể thấy, tôi đang áp dụng cùng một gradient bốn lần và mỗi lần có một vị trí khác nhau để chỉ che một mặt tại một thời điểm.

Một cái khác? Đi nào!

Cái này trông hơi phức tạp và nó thực sự đòi hỏi một số trí tưởng tượng để hiểu làm thế nào hai gradient hình nón đang tạo ra loại ma thuật này. Đây là một bản demo để minh họa một trong các gradient:

Phần tử giả mô phỏng gradient. Ban đầu, nó nằm ngoài tầm nhìn và khi di chuột, trước tiên chúng tôi thay đổi vị trí của nó để có được cạnh trên của khung hình. Sau đó, chúng tôi tăng chiều cao để có được cạnh bên phải. Hình dạng gradient tương tự như hình dạng chúng ta đã sử dụng trong phần trước: hai đoạn để che hai mặt.

Nhưng tại sao tôi lại làm cho chiều rộng của gradient 200%? Bạn sẽ nghĩ 100% sẽ là đủ, phải không?

100% chắc là đủ nhưng tôi sẽ không thể di chuyển gradient như tôi muốn nếu tôi giữ chiều rộng của nó bằng 100%. Đó là một câu hỏi nhỏ khác liên quan đến cách background-position làm. Tôi bao gồm cái này trong một bài viết trước. tôi cũng vậy đã đăng một câu trả lời tại Stack Overflow đối phó với điều này. Tôi biết là đọc rất nhiều, nhưng nó thực sự đáng để bạn dành thời gian.

Bây giờ chúng ta đã giải thích logic cho một gradient, cái thứ hai rất dễ dàng vì nó làm chính xác điều tương tự, nhưng thay vào đó là che các cạnh bên trái và dưới cùng. Tất cả những gì chúng ta phải làm là hoán đổi một vài giá trị và chúng ta đã hoàn thành:

img {
  --c: #8A9B0F; /* the border color */
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap */

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, var(--c) 0;
  background: 
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b))  no-repeat,
    conic-gradient(            at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200%  no-repeat;
  transition: .3s, background-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, background-size .3s .3s;
}

Như bạn có thể thấy, cả hai gradient gần như giống hệt nhau. Tôi chỉ đơn giản là hoán đổi các giá trị của kích thước và vị trí.

Xoay khung hình

Lần này, chúng tôi sẽ không vẽ khung xung quanh hình ảnh của mình, mà là điều chỉnh giao diện của hình ảnh hiện có.

Có lẽ bạn đang hỏi làm thế quái nào mà tôi có thể biến một đường thẳng thành một đường thẳng góc. Không, điều kỳ diệu khác hơn thế. Đó chỉ là ảo ảnh mà chúng ta nhận được sau khi kết hợp các hình ảnh động đơn giản cho bốn gradient.

Hãy xem hoạt ảnh cho gradient trên cùng được tạo ra như thế nào:

Tôi chỉ đang cập nhật vị trí của một gradient lặp lại. Không có gì lạ mắt được nêu ra! Hãy làm tương tự cho phía bên phải:

Bạn có bắt đầu thấy thủ thuật không? Cả hai gradient giao nhau ở góc để tạo ra ảo giác nơi đường thẳng được thay đổi thành góc. Hãy xóa đường viền và ẩn phần tràn để thấy rõ hơn:

Bây giờ, chúng ta thêm hai gradient nữa để che các cạnh còn lại và chúng ta đã hoàn thành:

img {
  --g: 4px; /* the gap */
  --b: 12px; /* border thickness*/
  --c: #669706; /* the color */

  padding: calc(var(--g) + var(--b));
  --_c: #0000 0 25%, var(--c) 0 50%;
  --_g1: repeating-linear-gradient(90deg ,var(--_c)) repeat-x;
  --_g2: repeating-linear-gradient(180deg,var(--_c)) repeat-y;
  background:
    var(--_g1) var(--_p, 25%) 0, 
    var(--_g2) 0 var(--_p, 125%),
    var(--_g1) var(--_p, 125%) 100%, 
    var(--_g2) 100% var(--_p, 25%);
  background-size: 200% var(--b), var(--b) 200%;
  transition: .3s;
}
img:hover {
  --_p: 75%;
}

Nếu chúng ta lấy mã này và điều chỉnh một chút, chúng ta có thể nhận được một hoạt ảnh thú vị khác:

Bạn có thể tìm ra logic trong ví dụ này không? Đó là bài tập về nhà của bạn! Đoạn mã có thể trông đáng sợ nhưng nó sử dụng cùng một logic như các ví dụ trước mà chúng ta đã xem xét. Cố gắng cô lập từng gradient và tưởng tượng nó hoạt hình như thế nào.

Kết thúc

Đó là rất nhiều gradient trong một bài báo!

Nó chắc chắn là như vậy và tôi đã cảnh báo bạn! Nhưng nếu thử thách là trang trí một hình ảnh mà không có các yếu tố phụ và yếu tố giả, chúng ta chỉ còn lại một số khả năng và gradient là lựa chọn mạnh mẽ nhất.

Đừng lo lắng nếu bạn hơi lạc lõng trong một số lời giải thích. Tôi luôn giới thiệu một số bài báo cũ của tôi, nơi tôi đi vào chi tiết hơn với một số khái niệm mà chúng tôi đã tái chế cho thử thách này.

Tôi sẽ rời đi với một bản demo cuối cùng để giữ chân bạn cho đến khi có bài viết tiếp theo trong loạt bài này. Lần này, tôi đang sử dụng radial-gradient() để tạo một hiệu ứng di chuột vui nhộn khác. Tôi sẽ để bạn mổ xẻ mã để tìm hiểu cách thức hoạt động của nó. Đặt câu hỏi cho tôi trong phần bình luận nếu bạn gặp khó khăn!

Loạt đồ trang trí hình ảnh lạ mắt

  • Phép thuật Đơn nguyên tố - bạn đang ở đây
  • Mặt nạ và Hiệu ứng Di chuột nâng cao (đến ngày 21 tháng XNUMX )
  • Phác thảo và Hoạt ảnh Phức tạp (đến ngày 28 tháng XNUMX )

Dấu thời gian:

Thêm từ Thủ thuật CSS