بعد جزء 1 و جزء 2، لقد عدت بمقال ثالث لاستكشاف المزيد من الأشكال الفاخرة. مثل المقالات السابقة ، سنقوم بدمج CSS Grid مع القص والإخفاء لإنشاء تخطيطات رائعة لمعارض الصور.
شبكة CSS وسلسلة الأشكال المخصصة
هل يجب أن أقرأ المقالات السابقة من قبل؟
إنه ليس إلزاميًا ولكن يوصى به بشدة لتغطية أكبر عدد ممكن من الحيل. يمكنك أيضًا قراءتها بأي ترتيب ، ولكن اتباعها بترتيب زمني يعد فكرة جيدة لمعرفة كيف وصلنا إلى هنا.
يكفي الحديث ، دعنا نقفز مباشرة إلى مثالنا الأول.
معرض صور Die Cut
قبل البحث في CSS ، دعنا نتحقق من الترميز:
لا شيء سوى القليل العلامات في غلاف div ، أليس كذلك؟ تذكر أن التحدي الرئيسي لهذه السلسلة هو العمل مع أقل قدر ممكن من HTML. تستخدم جميع الأمثلة التي رأيناها خلال هذه السلسلة نفس ترميز HTML بالضبط. لا يوجد divs إضافي ، ومغلفات ، وما إلى ذلك. كل ما نحتاجه هو صور موجودة في عنصر غلاف.
دعنا نتحقق من 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-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 هذه الأيام. لم يمض وقت طويل على أن كل هذا كان سيأخذ قرصنة مطولة وبالتأكيد بعض جافا سكريبت.
خلال هذه السلسلة ، استكشفنا العديد والعديد من الأنواع المختلفة لشبكات الصور ، من العناصر الأساسية إلى الفسيفساء المعقدة التي صنعناها اليوم. ولدينا الكثير من الخبرة العملية في العمل مع قص CSS - وهو شيء ستتمكن بالتأكيد من استخدامه في مشاريع أخرى!
ولكن قبل أن ننهي هذا ، لدي بعض الواجبات المنزلية لك ...
إليك نوعان من الفسيفساء أريدك أن تصنعهما باستخدام ما قمنا بتغطيته هنا. أحدهما على الجانب "الأسهل" والآخر صعب بعض الشيء. سيكون من الرائع حقًا رؤية عملك في التعليقات ، لذا اربطها! أشعر بالفضول لمعرفة ما إذا كان نهجك مختلفًا عن الطريقة التي سأتبعها!