לאחר חלק 1 ו חלק 2, חזרתי עם מאמר שלישי כדי לחקור צורות מפוארות יותר. כמו המאמרים הקודמים, אנחנו הולכים לשלב CSS Grid עם גזירה ומסיכה כדי ליצור פריסות מהודרות עבור גלריות תמונות.
סדרת CSS Grid ו-Custom Shapes
האם עלי לקרוא את המאמרים הקודמים לפני?
זה לא חובה אבל מומלץ מאוד לכסות כמה שיותר טריקים. אתה יכול גם לקרוא אותם בכל סדר, אבל לעקוב אחריהם בכרונולוגי זה רעיון טוב לראות איך הגענו לכאן.
די לדבר, בואו נקפוץ ישר לדוגמא הראשונה שלנו.
גלריית התמונות Die Cut
לפני שנחפור ב-CSS, בואו נבדוק את הסימון:
שום דבר מלבד כמה תגיות בעטיפת div, נכון? זכור, האתגר העיקרי בסדרה זו הוא לעבוד עם הכמות הקטנה ביותר של HTML. כל הדוגמאות שראינו לאורך הסדרה הזו משתמשות באותו סימון HTML בדיוק. ללא רכיבים נוספים, עטיפות, ומה לא. כל מה שאנחנו צריכים זה תמונות הכלולות באלמנט עטיפה.
בוא נבדוק את ה-CSS עכשיו:
.gallery {
--g: 6px; /* the gap */
display: grid;
width: 450px; /* the size */
aspect-ratio: 1; /* equal height */
grid: auto-flow 1fr / repeat(3, 1fr);
gap: var(--g);
}
.gallery img:nth-child(2) {
grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
grid-area: 2 / 1 / span 2 / span 2;
}
בעיקרון, זוהי רשת מרובעת עם שלוש עמודות שוות. משם, כל מה שקורה הוא שהתמונות השניות והשלישיות ממוקמות במפורש על הרשת, ומאפשרות לתמונות הראשונות והאחרונות להתפרש אוטומטית סביבן.
התנהגות אוטומטית זו היא תכונה רבת עוצמה של CSS Grid הנקראת "מיקום אוטומטי". אותו דבר עם מספר השורות - אף אחת מהן אינה מוגדרת במפורש. הדפדפן יוצר אותם באופן "מרומז" על סמך מיקום הפריטים. יש לי מאמר מפורט מאוד שחוקר את שני המושגים.
אתה אולי תוהה מה קורה עם אלה grid
ו grid-area
ערך הנכס. הם נראים מוזרים וקשה להכשיל אותם! זה בגלל שבחרתי ב-CSS grid
מאפיין קיצור, שהוא סופר שימושי אך מקבל מספר בלתי ראוי של ערכים מהמאפיינים המרכיבים אותו. אתה יכול לראות את כולם באלמנך.
אבל מה שאתה באמת צריך לדעת זה:
grid: auto-flow 1fr / repeat(3, 1fr);
… שווה ערך לזה:
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 1fr;
כנ"ל לגבי grid-area
תכונה. אם נפתח את DevTools ונבדוק את ההצהרה שלנו: grid-area: 1/2/span 2/span 2;
תקבל את הדברים הבאים:
grid-area: 1 / 2 / span 2 / span 2;
...זה אותו דבר כמו לכתוב את כל זה:
grid-row-start: 1; /* 1st row */
grid-column-start: 2; /* 2nd column */
grid-row-end: span 2; /* take 2 rows */
grid-column-end: span 2; /* take 2 columns */
אותה עסקה עבור האחר grid-area
הַצהָרָה. כשאנחנו מחברים את הכל ביחד, זה מה שאנחנו מקבלים:
כן, התמונה השנייה והשלישית חופפות באמצע. זו לא טעות! בכוונה חיברתי אותם זה על גבי זה כדי שאוכל ליישם א clip-path
כדי לחתוך חלק מכל אחד ולקבל את התוצאה הסופית:
איך אנחנו עושים את זה? נוכל לחתוך את הפינה השמאלית התחתונה של התמונה השנייה (img:nth-child(2)
) עם ה-CSS clip-path
נכס:
clip-path: polygon(0 0, 100% 0, 100% 100%, calc(50% + var(--g) / 4) 100%, 0 calc(50% - var(--g) / 4))
והפינה השמאלית העליונה של השלישי:
clip-path: polygon(0 0, calc(50% - var(--g) / 4) 0, 100% calc(50% + var(--g) / 4), 100% 100%, 0 100%);
אני יודע אני יודע. זה הרבה מספרים ומה לא. יש לי מאמר שמפרט את הטכניקה.
זהו, יש לנו את רשת התמונות הראשונה שלנו! הוספתי גווני אפור filter
על בורר כדי לקבל את אפקט הריחוף הקטן והמסודר הזה.
חשיפת התמונה המפוצלת
בואו ננסה משהו אחר. אנחנו יכולים לקחת את מה שלמדנו על חיתוך פינה של תמונה ולשלב אותו עם אפקט נחמד כדי לחשוף את התמונה המלאה על ריחוף.
תצורת הרשת עבור זו היא פחות אינטנסיבית מהקודמת, מכיוון שכל מה שאנחנו צריכים זה שתי תמונות חופפות:
.gallery {
display: grid;
}
.gallery > img {
grid-area: 1 / 1;
width: 350px; /* the size */
aspect-ratio: 1; /* equal height */
}
שתי תמונות בגודל זהה מוערמות זו על גבי זו (תודה ל grid-area: 1 / 1
).
אפקט הריחוף מסתמך על הנפשה clip-path
. ננתח את הקוד של התמונה הראשונה כדי לראות איך זה עובד, ואז נחבר את אותו הדבר לתמונה השנייה עם ערכים מעודכנים. שימו לב, למרות שיש לנו שלושה מצבים שונים:
- כאשר אין תמונות מרחפות, מחצית מכל תמונה מתגלה.
- כאשר אנו מרחפים מעל התמונה הראשונה, היא נחשפת בצורה מלאה יותר אך שומרת על קליפ פינתי קטן.
- כאשר אנו מרחפים מעל התמונה השנייה, לתמונה הראשונה יש רק משולש קטן גלוי.
בכל מקרה, יש לנו צורה משולשת. זה אומר שאנחנו צריכים מצולע שלוש נקודות עבור clip-path
ערך.
מה? המצב השני הוא לא משולש, אלא יותר ריבוע עם פינה חתוכה.
אתה צודק, אבל אם נתבונן היטב נוכל לראות משולש "נסתר". בואו נוסיף א box-shadow
לתמונות.
אה! שמתם לב לזה?
איזה מין קסם זה? זה עובדה מעט ידועה ש clip-path
מקבל ערכים מחוץ ל 0%-100%
טווח, המאפשר לנו ליצור צורות "עולות על גדותיו". (כן, זה עתה המצאתי את זה. אתה מוזמן.) בדרך זו, אנחנו צריכים לעבוד רק עם שלוש נקודות במקום החמש שנדרש כדי ליצור את אותה צורה מהחלקים הגלויים. CSS מותאם לניצחון!
זה הקוד לאחר שאנו מחברים את ערכי המצולע ל- clip-path
נכס:
.gallery > img:first-child {
clip-path: polygon(0 0, calc(100% + var(--_p)) 0 , 0 calc(100% + var(--_p)))
}
.gallery > img:last-child {
clip-path: polygon(100% 100%, 100% calc(0% - var(--_p)), calc(0% - var(--_p)) 100%)
}
שים לב --_p
מִשְׁתַנֶה. אני משתמש בזה כדי לייעל מעט את הקוד כשאנו מוסיפים את מעבר הרחף. במקום לעדכן את המכלול clip-path
אנו מעדכנים את המשתנה הזה רק כדי לקבל את התנועה. הנה סרטון כדי לראות כיצד הנקודות צריכות לעבור בין כל מדינה:
אנחנו יכולים לקבל סטירה א transition
על בורר, ולאחר מכן עדכן את
--_p
משתנה על המדינות כדי לקבל את ההשפעה הסופית:
.gallery {
--g: 8px; /* the gap */
}
.gallery > img {
/* etc. */
--_p: calc(-1 * var(--g));
transition: .4s .1s;
}
.gallery:hover > img:last-child,
.gallery:hover > img:first-child:hover{
--_p: calc(50% - var(--g));
}
.gallery:hover > img:first-child,
.gallery:hover > img:first-child:hover + img {
--_p: calc(-50% - var(--g));
}
אם לא ניקח בחשבון את הפער (מוגדר כ --g
בקוד) בין התמונות, ולאחר מכן שלושת הערכים של --_p
יש לו 0%
, 50%
, ו -50%
. כל אחד מגדיר את אחד מהמצבים שהסברנו קודם לכן.
גילוי תמונת העוגה
בואו נעלה את רמת הקושי מהקודם הזה וננסה לעשות את אותו הטריק אבל עם ארבע תמונות במקום שתיים.
מגניב נכון? כל תמונה היא רבע עיגול, וברחף יש לנו אנימציה שהופכת תמונה לעיגול שלם המכסה את שאר התמונות. האפקט עשוי להיראות בלתי אפשרי כי אין דרך לסובב נקודות ולהפוך אותן כדי למלא את המעגל. אבל במציאות, אנחנו לא מסובבים נקודות בכלל. זו אשליה!
עבור דוגמה זו, אתמקד רק ב clip-path
אנימציה שכן תצורת הרשת זהה לדוגמא הקודמת: ארבע תמונות בגודל שווה מוערמות זו על גבי זו.
וסרטון ששווה הסבר משעמם וארוך:
השמיים clip-path
נוצר על ידי שבע נקודות, כאשר שלוש מהן נמצאות במצב קבוע והאחרות זזות כפי שמוצג בסרטון. האפקט נראה פחות מגניב כשהוא פועל לאט אבל אנחנו יכולים לראות איך clip-path
משתנה בין צורות.
האפקט קצת יותר טוב אם נוסיף border-radius
ואנחנו עושים את זה מהר יותר:
ועל ידי הפיכתו למהיר עוד יותר כמו בדוגמה המקורית, אנו מקבלים את האשליה המושלמת של רבע מעגל שהופך למעגל שלם. הנה ערך המצולע שלנו clip-path
בתמונה הראשונה ברצף:
.gallery > img:nth-child(1) {
clip-path: polygon(50% 50%, calc(50% * var(--_i, 0)) calc(120% * var(--_i, 0)), 0 calc(100% * var(--_i, 0)),0 0, 100% 0, 100% calc(100% * var(--_i, 0)), calc(100% - 50% * var(--_i, 0)) calc(120% * var(--_i, 0)));
}
.gallery > img:hover {
--_i: 1;
}
כרגיל, אני משתמש במשתנה כדי לייעל את הקוד. המשתנה יעבור בין 0
ו 1
כדי לעדכן את המצולע.
אותו דבר לגבי התמונה של האחרים אבל עם תמונה אחרת clip-path
תְצוּרָה. אני יודע שהערכים אולי נראים קשים לפענוח אבל אתה תמיד יכול להשתמש בכלים מקוונים כמו Clippy לדמיין את הערכים.
פסיפס התמונות
אתה מכיר פסיפסים, נכון? זהו סגנון אמנותי שיוצר עיצובים דקורטיביים מחלקים בודדים קטנים יותר, כמו אבנים צבעוניות. אבל זה יכול להיות גם תמונה מורכבת המורכבת מתמונות קטנות אחרות.
וגם, ניחשתם נכון: אנחנו לגמרי יכולים לעשות דברים כאלה ב-CSS!
ראשית, בואו נדמיין איך הדברים נראים אם clip-path
הוצאו מהתערובת וכל מה שהיה לנו היו חמש תמונות חופפות:
אני בוגד מעט בסרטון הזה כי אני בודק את הקוד כדי לזהות את האזור של כל תמונה, אבל זה מה שאתה צריך לעשות בראש שלך. עבור כל תמונה, נסה להשלים את החלק החסר כדי לראות את המלבן המלא, ועם זה נוכל לזהות את המיקום והגודל של כל אחת מהן.
אנחנו צריכים למצוא כמה עמודות ושורות אנחנו צריכים עבור הרשת:
- יש לנו שתי תמונות גדולות הממוקמות אחת ליד השנייה שכל אחת ממלאת חצי מרוחב הרשת ואת גובה הרשת המלא. זה אומר כנראה יהיה צורך שני עמודים (אחד עבור שתי התמונות) ו שורה אחת (למלוא גובה הרשת).
- יש לנו את התמונה באמצע שחופפת את שתי התמונות האחרות. זה אומר שאנחנו באמת צריכים ארבעה עמודים במקום שניים, למרות שאנחנו עדיין צריכים רק את שורה אחת.
- שתי התמונות האחרונות ממלאות כל אחת חצי מהרשת, בדיוק כמו שתי התמונות הראשונות. אבל הם רק חצי מגובה הרשת. אנחנו יכולים להשתמש בעמודות הקיימות שכבר יש לנו, אבל נצטרך שתי שורות במקום אחד שיגרום לכך שתמונות אלו הן מחצית מגובה הרשת.
אני לא רוצה שתחשוב שהדרך שבה חתכתי את זה היא רק דרך לעשות את זה. רק כך הבנתי את זה. אני בטוח שיש תצורות אחרות שאפשר לקבל את אותה פריסה!
בואו ניקח את המידע הזה ונגדיר את הרשת שלנו, ואז נניח עליו את התמונות:
.gallery {
display: grid;
grid: repeat(2, 1fr) / repeat(4, 1fr);
aspect-ratio: 2;
}
.gallery img:nth-child(1) {
grid-area: 1 / 1 / span 2 / span 2;
}
.gallery img:nth-child(2) {
grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
grid-area: span 2 / span 2 / -1 / -1;
}
.gallery img:nth-child(4) {
grid-area: 2 / 1 / span 1 / span 2;
}
.gallery img:nth-child(5) {
grid-area: span 1 / span 2 / -1 / -1;
}
אני חושב שאתה מבין מה קורה כאן עכשיו כשראינו כמה דוגמאות המשתמשות באותה גישה. אנו מגדירים רשת וממקמים עליה תמונות באופן מפורש, באמצעות grid-area
כך שהתמונות חופפות.
בסדר, אבל ה
aspect-ratio
שונה הפעם.
זה! אם תחזור לנימוק שהבאנו, יש לנו את שתי התמונות הראשונות המרובעות אחת ליד השנייה בגודל זהה. המשמעות היא שרוחב הרשת צריך להיות שווה פי שניים מגובהה. לָכֵן, aspect-ratio: 2
.
עכשיו הגיע הזמן ל clip-path
ערכים. יש לנו ארבעה משולשים ומעוין.
שוב, אני משתמש ב-Clippy עבור כל הדברים המתמטיים האלה. אבל, בכנות, אני יכול לכתוב הרבה צורות פשוטות ביד, לאחר שביליתי כמה שנים בעבודה צמודה איתן clip-path
, ואני יודע שגם אתה יכול עם תרגול!
הפסיפס המורכב של תמונות
נגביר את הקושי וננסה פסיפס אחר, הפעם עם פחות סימטריה וצורות מורכבות יותר.
אל תדאג, אתה תראה שזה אותו רעיון כמו זה שהכנו! שוב, בואו נדמיין שכל תמונה היא מלבן, ואז נמשיך להגדיר את הרשת על סמך מה שאנו רואים.
נתחיל בשתי תמונות:
שניהם ריבועים. התמונה הראשונה שווה לחצי מהגודל של התמונה השנייה. התמונה הראשונה תופסת פחות ממחצית מרוחב הרשת, בעוד שהתמונה השנייה תופסת יותר ממחצית ונותנת לנו סך של שני עמודים עם גודל שונה (הראשון שווה לחצי מהשני). התמונה הראשונה היא חצי מהגובה, אז בוא נניח אוטומטית שאנחנו צריכים שתי שורות גם כן.
בואו נוסיף עוד תמונה לפריסה
זה עושה את הדברים קצת יותר מורכבים! עלינו לשרטט כמה קווים כדי לזהות כיצד לעדכן את תצורת הרשת.
נעבור מרשת 2×2 ל ארבעה עמודים ו שלוש שורות. די אסימטרי, נכון? לפני שננסה להבין את הגודל המלא הזה, בואו נראה אם אותה פריסה מחזיקה מעמד כשאנחנו מוסיפים את התמונות האחרות.
נראה שאנחנו עדיין צריכים עוד שורות ועמודות כדי שהכל ייכנס למקומו. בהתבסס על הקווים בתמונה הזו, יהיה לנו סך של חמישה עמודים ו ארבע שורות.
ההיגיון פשוט למרות שהפריסה מורכבת, נכון? אנו מוסיפים את התמונות אחת אחת כדי למצוא את התצורה הנכונה שמתאימה לכל דבר. כעת עלינו לזהות את הגודל של כל עמודה ושורה.
אם נגיד שהשורה/עמודה הקטנה ביותר שווה לשבריר אחד מהרשת (1fr
) אנו נקבל:
grid-template-columns: 1fr 1fr 2fr 3fr 5fr;
…עבור העמודות, ו:
grid-template-rows: 3fr 1fr 2fr 2fr;
...עבור השורות. אנחנו יכולים לאחד את זה באמצעות grid
שוב נכס קיצור:
grid: 3fr 1fr 2fr 2fr / 1fr 1fr 2fr 3fr 5fr;
אתה מכיר את הנוהל! הנח את התמונות על הרשת והחל א clip-path
עליהם:
.gallery img:nth-child(1) {
grid-area: 1 / 1 /span 2 / span 3;
clip-path: polygon(0 0, 100% 0, 0 100%);
}
.gallery img:nth-child(2) {
grid-area: 1/2/span 3/span 3;
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.gallery img:nth-child(3) {
grid-area: 1 / span 2 / -1 / -1;
clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.gallery img:nth-child(4) {
grid-area: span 3 / 1 / -1 / span 3;
clip-path: polygon(25% 0, 100% 60%, 50% 100%, 0 100%, 0 20%);
}
.gallery img:nth-child(5) {
grid-area: span 3/span 3/-1/-1;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
אנחנו יכולים לעצור כאן והקוד שלנו בסדר, אבל נעשה קצת יותר כדי לייעל את clip-path
ערכים. מכיוון שאין לנו פערים בין התמונות שלנו, אנחנו יכולים להשתמש בעובדה שהתמונות שלנו חופפות כדי להקטין דברים. להלן סרטון להמחשת הרעיון:
כפי שאתה יכול לראות, התמונה באמצע (זו עם המצלמה) לא צריכה א clip-path
. כי התמונות האחרות חופפות אותו, ונותנות לנו את הצורה ללא כל עבודה נוספת! ושימו לב שאנחנו יכולים להשתמש באותה שלוש נקודות על גדותיה clip-path
קונספט שהשתמשנו קודם לכן בתמונה בפינה השמאלית התחתונה כדי שהקוד יהיה קטן יותר גם שם.
בסופו של דבר, יש לנו רשת מורכבת למראה של תמונות עם ארבע בלבד clip-path
הצהרות - כולם מצולעים של שלוש נקודות!
גלישה את
וואו, נכון? אני לא יודע מה איתכם, אבל אני אף פעם לא משתעמם מלראות מה CSS יכול לעשות בימים אלה. לא עבר זמן רב שכל זה היה דורש האקרי מפורש ובהחלט קצת JavaScript.
לאורך הסדרה הזו, חקרנו הרבה מאוד סוגים שונים של רשתות תמונה, מהחומר הבסיסי ועד לפסיפס המורכב שיצרנו היום. ויש לנו הרבה ניסיון מעשי בעבודה עם חיתוך CSS - משהו שבהחלט תוכל להשתמש בפרויקטים אחרים!
אבל לפני שנסיים את זה, יש לי כמה שיעורי בית בשבילך...
הנה שני פסיפסים שאני רוצה שתכין בעזרת מה שסקרנו כאן. האחד בצד "הקל" יותר, והשני קצת מסובך. זה יהיה ממש מדהים לראות את העבודה שלך בתגובות, אז קשר אותם! אני סקרן לראות אם הגישה שלך שונה מהאופן שבו הייתי עושה זאת!