ในบทความที่แล้ว ฉันได้ดูความสามารถของ CSS Grid to สร้างเลย์เอาต์ที่ซับซ้อนโดยใช้พลังการจัดตำแหน่งอัตโนมัติ. ฉันก้าวไปอีกขั้นในบทความอื่นที่ เพิ่มเอฟเฟกต์โฮเวอร์ซูมภาพในเลย์เอาต์กริด. คราวนี้ ฉันต้องการเจาะลึกเข้าไปในตารางประเภทอื่น แบบที่ใช้กับรูปร่างได้
เช่น จะเกิดอะไรขึ้นถ้ารูปภาพไม่ได้เป็นรูปสี่เหลี่ยมจัตุรัสอย่างสมบูรณ์ แต่กลับมีรูปร่างเหมือนหกเหลี่ยมหรือรูปสี่เหลี่ยมขนมเปียกปูน การแจ้งเตือนสปอยเลอร์: เราทำได้ อันที่จริง เราจะรวมเทคนิค CSS Grid ที่เราได้ดูและวางใน CSS . บางส่วน clip-path
และ mask
มายากลเพื่อสร้างกริดภาพแฟนซีสำหรับรูปร่างใด ๆ ที่คุณสามารถจินตนาการได้!
มาเริ่มกันด้วยมาร์กอัปกัน
เลย์เอาต์ส่วนใหญ่ที่เราจะดูอาจดูง่ายที่จะทำได้ในแวบแรก แต่ส่วนที่ท้าทายคือการทำให้สำเร็จด้วย มาร์กอัป HTML เดียวกัน. เราสามารถใช้เครื่องห่อได้มาก div
และอะไรก็ตาม แต่เป้าหมายของโพสต์นี้คือการใช้โค้ด HTML ที่เท่ากันและน้อยที่สุด และยังคงได้กริดต่างๆ ที่เราต้องการ ท้ายที่สุดแล้ว CSS คืออะไรนอกจากวิธีแยกสไตล์และมาร์กอัป สไตล์ของเราไม่ควรขึ้นอยู่กับมาร์กอัป และในทางกลับกัน
นี้กล่าวว่าขอเริ่มต้นด้วยสิ่งนี้:
<div class="gallery">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
<!-- as many times as we want -->
</div>
คอนเทนเนอร์ที่มีรูปภาพเป็นสิ่งที่เราต้องการที่นี่ ไม่มีอะไรมาก!
CSS Grid ของหกเหลี่ยม
นี้บางครั้งเรียกว่าตาราง "รังผึ้ง"
มีโพสต์บล็อกอื่น ๆ มากมายที่แสดงวิธีการทำสิ่งนี้ ฮึก ฉัน เขียนหนึ่ง ที่นี่ใน CSS-Tricks! บทความนั้นยังดีอยู่และลงลึกไปถึงการสร้างเลย์เอาต์ที่ตอบสนอง แต่สำหรับกรณีนี้ เราจะใช้แนวทาง CSS ที่ง่ายกว่ามาก
ขั้นแรกให้ใช้ clip-path
บนรูปภาพเพื่อสร้างรูปทรงหกเหลี่ยม และเราวางรูปภาพทั้งหมดไว้ในพื้นที่ตารางเดียวกันเพื่อให้ซ้อนทับกัน
.gallery {
--s: 150px; /* controls the size */
display: grid;
}
.gallery > img {
grid-area: 1/1;
width: var(--s);
aspect-ratio: 1.15;
object-fit: cover;
clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
ยังไม่มีอะไรแฟนซี รูปภาพทั้งหมดเป็นรูปหกเหลี่ยมและอยู่เหนือกัน ดูเหมือนว่าทั้งหมดที่เรามีคือองค์ประกอบรูปภาพรูปหกเหลี่ยมชิ้นเดียว แต่จริงๆ แล้วมีเจ็ดชิ้น
ขั้นตอนต่อไปคือการใช้การแปลกับรูปภาพเพื่อวางลงบนตารางอย่างถูกต้อง
สังเกตว่าเรายังต้องการให้ภาพใดภาพหนึ่งอยู่ตรงกลาง ส่วนที่เหลือจะถูกวางไว้รอบๆ โดยใช้ CSS translate
และรูปทรงเรขาคณิตที่ดี นี่คือสูตรจำลองที่ฉันคิดขึ้นสำหรับแต่ละรูปภาพในตาราง:
translate((height + gap)*sin(0deg), (height + gap)*cos(0))
translate((height + gap)*sin(60deg), (height + gap)*cos(60deg))
translate((height + gap)*sin(120deg), (height + gap)*cos(120deg))
translate((height + gap)*sin(180deg), (height + gap)*cos(180deg))
translate((height + gap)*sin(240deg), (height + gap)*cos(240deg))
translate((height + gap)*sin(300deg), (height + gap)*cos(300deg))
การคำนวณและการเพิ่มประสิทธิภาพเล็กน้อยในภายหลัง (ให้ข้ามส่วนที่น่าเบื่อนั้นไปใช่ไหม) เราได้รับ CSS ต่อไปนี้:
.gallery {
--s: 150px; /* control the size */
--g: 10px; /* control the gap */
display: grid;
}
.gallery > img {
grid-area: 1/1;
width: var(--s);
aspect-ratio: 1.15;
object-fit: cover;
clip-path: polygon(25% 0%, 75% 0%, 100% 50% ,75% 100%, 25% 100%, 0 50%);
transform: translate(var(--_x,0), var(--_y,0));
}
.gallery > img:nth-child(1) { --_y: calc(-100% - var(--g)); }
.gallery > img:nth-child(7) { --_y: calc( 100% + var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(5) { --_x: calc(-75% - .87*var(--g)); }
.gallery > img:nth-child(4),
.gallery > img:nth-child(6) { --_x: calc( 75% + .87*var(--g)); }
.gallery > img:nth-child(3),
.gallery > img:nth-child(4) { --_y: calc(-50% - .5*var(--g)); }
.gallery > img:nth-child(5),
.gallery > img:nth-child(6) { --_y: calc( 50% + .5*var(--g)); }
อาจจะง่ายกว่าเมื่อเราได้รับ ฟังก์ชันตรีโกณมิติจริงใน CSS!
แต่ละภาพแปลโดย --_x
และ --_y
ตัวแปรที่ยึดตามสูตรเหล่านั้น เฉพาะภาพที่สอง (nth-child(2)
) ไม่ได้กำหนดไว้ในตัวเลือกใดๆ เนื่องจากเป็นตัวเลือกที่อยู่ตรงกลาง อาจเป็นภาพใดก็ได้หากคุณตัดสินใจใช้ลำดับอื่น นี่คือคำสั่งที่ฉันใช้:
ด้วยโค้ดเพียงไม่กี่บรรทัด เราก็ได้ตารางรูปภาพเจ๋งๆ ในการนี้ ฉันได้เพิ่มเอฟเฟกต์โฮเวอร์เล็กน้อยให้กับรูปภาพเพื่อทำให้สิ่งต่าง ๆ น่าสนใจยิ่งขึ้น
คาดเดาอะไร? เราสามารถรับตารางหกเหลี่ยมอีกอันได้โดยการอัปเดตค่าสองสามค่า
หากคุณตรวจสอบรหัสและเปรียบเทียบกับรหัสก่อนหน้า คุณจะสังเกตเห็นว่าฉันเพิ่งเปลี่ยนค่าภายใน clip-path
และฉันสลับไปมาระหว่าง --x
และ --y
. นั่นคือทั้งหมด!
CSS Grid ของรูปสี่เหลี่ยมขนมเปียกปูน
รูปสี่เหลี่ยมขนมเปียกปูนเป็นคำแฟนซีสำหรับสี่เหลี่ยมที่หมุนได้ 45 องศา
HTML เดียวกัน จำได้ไหม ก่อนอื่นเราเริ่มต้นด้วยการกำหนดตารางรูปภาพขนาด 2×2 ใน CSS:
.gallery {
--s: 150px; /* controls the size */
display: grid;
gap: 10px;
grid: auto-flow var(--s) / repeat(2, var(--s));
place-items: center;
}
.gallery > img {
width: 100%;
aspect-ratio: 1;
object-fit: cover;
}
สิ่งแรกที่อาจดึงดูดสายตาของคุณคือ grid
คุณสมบัติ. มันค่อนข้างใช้งานไม่บ่อยนัก แต่มีประโยชน์มากเพราะเป็นชวเลขที่ให้คุณกำหนดกริดที่สมบูรณ์ในการประกาศครั้งเดียว ไม่ใช่คุณสมบัติที่เข้าใจง่ายที่สุดและไม่ต้องพูดถึงคุณสมบัติที่อ่านได้ แต่เราอยู่ที่นี่เพื่อ เรียน และ ค้นพบ ของใหม่ ดังนั้น ลองใช้มันแทนที่จะเขียนคุณสมบัติกริดแต่ละรายการทั้งหมด
grid: auto-flow var(--s) / repeat(2,var(--s));
/* is equivalent to this: */
grid-template-columns: repeat(2, var(--s));
grid-auto-rows: var(--s);
สิ่งนี้กำหนดสองคอลัมน์เท่ากับ --s
ตัวแปรและกำหนดความสูงของแถวทั้งหมดเป็น --s
เช่นกัน. เนื่องจากเรามีสี่ภาพ เราจะได้รับตารางขนาด 2×2 โดยอัตโนมัติ
นี่เป็นอีกวิธีหนึ่งที่เราจะเขียนได้:
grid-template-columns: repeat(2, var(--s));
grid-template-rows: repeat(2, var(--s));
…ซึ่งสามารถลดลงได้ด้วย grid
ชวเลข:
grid: repeat(2,var(--s)) / repeat(2,var(--s));
หลังจากกำหนดเส้นตารางแล้ว เราก็หมุนมันและรูปภาพด้วย CSS transform
และเราได้รับสิ่งนี้:
สังเกตว่าฉันหมุนทั้งคู่อย่างไรโดย 45deg
แต่ในทิศทางตรงกันข้าม
.gallery {
/* etc. */
transform: rotate(45deg);
}
.gallery > img {
/* etc. */
transform: rotate(-45deg);
}
การหมุนภาพไปในทิศทางลบช่วยป้องกันไม่ให้หมุนด้วยเส้นตารางเพื่อให้ภาพอยู่ในแนวตรง ตอนนี้เราใช้ a clip-path
เพื่อตัดรูปสี่เหลี่ยมขนมเปียกปูนออกจากพวกเขา
เราใกล้จะเสร็จแล้ว! เราจำเป็นต้องแก้ไขขนาดของภาพให้พอดีกัน มิฉะนั้น พวกมันจะเว้นระยะห่างกันจนดูไม่เหมือนตารางรูปภาพ
รูปภาพอยู่ภายในขอบเขตของวงกลมสีเขียว ซึ่งเป็นวงกลมที่จารึกไว้ของพื้นที่ตารางที่วางรูปภาพ เราต้องการทำให้รูปภาพใหญ่ขึ้นเพื่อให้พอดีกับวงกลมสีแดง ซึ่งเป็นวงกลมที่ล้อมรอบของพื้นที่ตาราง
ไม่ต้องกังวล ฉันจะไม่แนะนำเรขาคณิตที่น่าเบื่ออีกต่อไป สิ่งที่คุณต้องรู้คือความสัมพันธ์ระหว่างรัศมีของวงกลมแต่ละวงคือรากที่สองของ 2 (sqrt(2)
). นี่คือค่าที่เราจำเป็นต้องเพิ่มขนาดของภาพของเราให้เต็มพื้นที่ เราจะใช้ 100%*sqrt(2) = 141%
และทำ!
.gallery {
--s: 150px; /* control the size */
display: grid;
grid: auto-flow var(--s) / repeat(2,var(--s));
gap: 10px;
place-items: center;
transform: rotate(45deg);
}
.gallery > img {
width: 141%; /* 100%*sqrt(2) = 141% */
aspect-ratio: 1;
object-fit: cover;
transform: rotate(-45deg);
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
เช่นเดียวกับตารางหกเหลี่ยม เราสามารถทำให้สิ่งต่างๆ น่าสนใจยิ่งขึ้นด้วยเอฟเฟกต์โฮเวอร์การซูมที่ดี:
ตาราง CSS ของรูปทรงสามเหลี่ยม
คุณคงรู้แล้วว่าเคล็ดลับใหญ่คือการหา clip-path
เพื่อให้ได้รูปทรงที่เราต้องการ สำหรับตารางนี้ แต่ละองค์ประกอบมีของตัวเอง clip-path
ค่าในขณะที่สองกริดสุดท้ายทำงานกับรูปร่างที่สอดคล้องกัน ดังนั้น คราวนี้ มันเหมือนกับว่าเรากำลังทำงานกับรูปทรงสามเหลี่ยมต่างๆ สองสามรูปที่มารวมกันเป็นตารางสี่เหลี่ยมของรูปภาพ
เราวางไว้ในตาราง 3 × 2 ด้วย CSS ต่อไปนี้:
.gallery {
display: grid;
gap: 10px;
grid-template-columns: auto auto auto; /* 3 columns */
place-items: center;
}
.gallery > img {
width: 200px; /* controls the size */
aspect-ratio: 1;
object-fit: cover;
}
/* the clip-path values */
.gallery > img:nth-child(1) { clip-path: polygon(0 0, 50% 0, 100% 100% ,0 100%); }
.gallery > img:nth-child(2) { clip-path: polygon(0 0, 100% 0, 50% 100%); }
.gallery > img:nth-child(3) { clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%); }
.gallery > img:nth-child(4) { clip-path: polygon(0 0, 100% 0, 50% 100%, 0 100%); }
.gallery > img:nth-child(5) { clip-path: polygon(50% 0, 100% 100%, 0% 100%); }
.gallery > img:nth-child(6) { clip-path: polygon(0 0, 100% 0 ,100% 100%, 50% 100%); } }
นี่คือสิ่งที่เราได้รับ:
สัมผัสสุดท้ายคือทำให้ความกว้างของคอลัมน์กลางเท่ากัน 0
เพื่อกำจัดช่องว่างระหว่างภาพ ปัญหาการเว้นวรรคแบบเดียวกับที่เรามีกับตารางสี่เหลี่ยมขนมเปียกปูน แต่ด้วยวิธีการที่แตกต่างกันสำหรับรูปร่างที่เราใช้:
grid-template-columns: auto 0 auto;
ฉันต้องเล่นซอกับ clip-path
ค่าต่างๆ เพื่อให้แน่ใจว่าทั้งหมดจะเข้ากันได้ดีราวกับปริศนา ภาพต้นฉบับทับซ้อนกันเมื่อคอลัมน์กลางมีความกว้างเป็นศูนย์ แต่หลังจากตัดภาพแล้ว ภาพมายาก็สมบูรณ์แบบ:
CSS พิซซ่าพายกริด
คาดเดาอะไร? เราสามารถรับตารางเจ๋ง ๆ อีกอันได้โดยการเพิ่ม border-radius
และ overflow
เป็นรูปตารางหรือรูปสามเหลี่ยมของเรา 🎉
CSS Grid ของชิ้นส่วนปริศนา
คราวนี้เราจะมาเล่นกับ CSS mask
คุณสมบัติที่จะทำให้ภาพดูเหมือนชิ้นส่วนของจิ๊กซอว์
หากคุณไม่ได้ใช้ mask
กับ การไล่ระดับสี CSSฉันขอแนะนำ บทความอื่นนี้ ฉันเขียนในหัวข้อนี้เพราะมันจะช่วยในสิ่งต่อไป ทำไมต้องไล่ระดับ? เพราะนั่นคือสิ่งที่เราใช้เพื่อให้ได้รอยบากทรงกลมในรูปร่างของตัวต่อ
การตั้งตารางน่าจะเป็นเรื่องง่ายในตอนนี้ ดังนั้นเรามาโฟกัสที่ . แทน mask
ส่วนหนึ่ง
ตามที่แสดงในตัวอย่างด้านบน เราจำเป็นต้องมีการไล่ระดับสีสองแบบเพื่อสร้างรูปร่างขั้นสุดท้าย การไล่ระดับสีหนึ่งสร้างวงกลม (ส่วนสีเขียว) และอีกส่วนสร้างเส้นโค้งที่ถูกต้องในขณะที่เติมส่วนบน
--g: 6px; /* controls the gap */
--r: 42px; /* control the circular shapes */
background:
radial-gradient(var(--r) at left 50% bottom var(--r), green 95%, #0000),
radial-gradient(calc(var(--r) + var(--g)) at calc(100% + var(--g)) 50%, #0000 95%, red)
top/100% calc(100% - var(--r)) no-repeat;
ตัวแปรสองตัวควบคุมรูปร่าง ดิ --g
ตัวแปรไม่มีอะไรนอกจากช่องว่างของกริด เราจำเป็นต้องคำนึงถึงช่องว่างในการวางวงกลมของเราอย่างถูกต้อง เพื่อให้ซ้อนทับกันอย่างสมบูรณ์เมื่อประกอบปริศนาทั้งหมด ดิ --r
ตัวแปรควบคุมขนาดของส่วนวงกลมของรูปร่างปริศนา
ตอนนี้เราใช้ CSS เดียวกันและอัปเดตค่าสองสามค่าเพื่อสร้างรูปร่างอื่นๆ อีกสามรูปแบบ:
เรามีรูปร่าง แต่ไม่ใช่ขอบที่ทับซ้อนกันที่เราจำเป็นต้องทำให้พอดีกัน รูปภาพแต่ละรูปถูกจำกัดให้อยู่ในเซลล์กริดที่มันอยู่ ดังนั้นจึงเป็นเหตุเป็นผลว่าทำไมรูปทรงต่างๆ จึงคลาดเคลื่อนในขณะนี้:
เราจำเป็นต้องสร้างโอเวอร์โฟลว์โดยเพิ่มความสูง/ความกว้างของรูปภาพ จากรูปด้านบน เราต้องเพิ่มความสูงของภาพที่หนึ่งและสี่ในขณะที่เราเพิ่มความกว้างของภาพที่สองและสาม คุณอาจเดาได้แล้วว่าเราต้องเพิ่มพวกเขาโดยใช้ --r
ตัวแปร
.gallery > img:is(:nth-child(1),:nth-child(4)) {
width: 100%;
height: calc(100% + var(--r));
}
.gallery > img:is(:nth-child(2),:nth-child(3)) {
height: 100%;
width: calc(100% + var(--r));
}
เรากำลังเข้าใกล้!
เราสร้างการซ้อนทับกัน แต่โดยค่าเริ่มต้น รูปภาพของเราจะซ้อนทับทางด้านขวา (หากเราเพิ่มความกว้าง) หรือด้านล่าง (หากเราเพิ่มความสูง) แต่นั่นไม่ใช่สิ่งที่เราต้องการสำหรับภาพที่สองและสี่ การแก้ไขคือการใช้ place-self: end
ในสองภาพนั้นและโค้ดเต็มของเราจะกลายเป็น:
นี่เป็นอีกตัวอย่างหนึ่งที่ฉันใช้การไล่ระดับสีแบบกรวยแทนการไล่ระดับสีแบบเรเดียล สิ่งนี้ทำให้เรามีชิ้นส่วนปริศนาสามเหลี่ยมในขณะที่ยังคงรักษา HTML และ CSS พื้นฐานไว้เหมือนเดิม
สุดท้าย! ครั้งนี้ฉันใช้ clip-path
และเนื่องจากเป็นคุณสมบัติที่เราสามารถทำให้เคลื่อนไหวได้ เราจึงได้โฮเวอร์ที่ยอดเยี่ยมโดยเพียงแค่อัปเดตคุณสมบัติแบบกำหนดเองที่ควบคุมรูปร่าง
ตัดขึ้น
นั่นคือทั้งหมดสำหรับส่วนแรกนี้! ด้วยการรวมสิ่งที่เราได้เรียนรู้เกี่ยวกับ CSS Grid เข้ากับสิ่งที่เพิ่มเข้ามาแล้ว clip-path
และ mask
มหัศจรรย์ เราสามารถสร้างเลย์เอาต์กริดที่มีรูปทรงต่างๆ ได้ และเราใช้มาร์กอัป HTML เดียวกันทุกครั้ง! และมาร์กอัปเองก็ไม่มีอะไรมากไปกว่าคอนเทนเนอร์ที่มีองค์ประกอบรูปภาพจำนวนหนึ่ง!
ในส่วนที่สอง เราจะสำรวจกริดที่ดูซับซ้อนยิ่งขึ้นด้วยรูปทรงแฟนซีและเอฟเฟกต์โฮเวอร์
ฉันวางแผนที่จะสาธิตการขยายแผงภาพที่เราทำร่วมกันใน บทความอื่นนี้:
…และแปลงเป็นแผงรูปภาพซิกแซก! และนี่เป็นเพียงตัวอย่างเดียวจากหลายๆ เรื่องที่เราจะค้นพบในบทความหน้า