تكبير الصور في تخطيط الشبكة PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

تكبير الصور في تخطيط الشبكة

يعد إنشاء شبكة من الصور أمرًا سهلاً ، وذلك بفضل CSS Grid. لكن جعل الشبكة تفعل أشياء خيالية بعد قد يكون من الصعب سحب الصور التي تم وضعها.

لنفترض أنك تريد إضافة بعض تأثيرات التمرير الرائعة إلى الصور حيث تنمو وتتخطى الصفوف والأعمدة التي تجلس فيها؟ بإمكاننا أن نفعل ذلك!

رائع ، أليس كذلك؟ إذا قمت بفحص الكود ، فلن تجد أي JavaScript أو محددات معقدة أو حتى أرقام سحرية. وهذا مثال واحد فقط من بين العديد من الأمثلة التي سنستكشفها!

بناء الشبكة

كود HTML لإنشاء الشبكة بسيط مثل قائمة الصور داخل الحاوية. لسنا بحاجة إلى أكثر من ذلك.

<div class="gallery">
  <img>
  <img>
  <img>
  <!-- etc. -->
</div>

بالنسبة إلى CSS ، نبدأ أولاً بتعيين الشبكة باستخدام ما يلي:

.gallery {
  --s: 150px; /* controls the size */
  --g: 10px;  /* controls the gap */

  display: grid;
  gap: var(--g);
  width: calc(3*var(--s) + 2*var(--g)); /* 3 times the size plus 2 times the gap */
  aspect-ratio: 1;
  grid-template-columns: repeat(3, auto);
}

باختصار ، لدينا متغيرين ، أحدهما يتحكم في حجم الصور والآخر يحدد حجم الفجوة بين الصور. aspect-ratio يساعد في الحفاظ على تناسب الأمور.

قد تتساءل عن سبب قيامنا بتعريف ثلاثة أعمدة فقط ولكن بدون صفوف. لا ، لم أنس الصفوف - لسنا بحاجة إلى تعيينها بشكل صريح. شبكة CSS قادرة على وضع العناصر تلقائيًا عليها صفوف وأعمدة ضمنية، مما يعني أننا نحصل على العديد من الصفوف حسب الحاجة لأي عدد من الصور نرميها. يمكننا تحديد الصفوف بشكل صريح بدلاً من ذلك ولكننا بحاجة إلى إضافتها grid-auto-flow: column للتأكد من أن المتصفح سينشئ الأعمدة المطلوبة لنا.

هنا مثال لتوضيح كلتا الحالتين. الفرق هو أن المرء يتدفق في row اتجاه الآخر في أ column الاتجاه.

إتمام عملية الشراء هذا المقال الآخر كتبته لمزيد من المعلومات حول الشبكات الضمنية وخوارزمية التنسيب التلقائي.

الآن بعد أن أصبح لدينا شبكتنا ، حان الوقت لتصميم الصور:

.gallery > img {
  width: 0;
  height: 0;
  min-height: 100%;
  min-width: 100%;
  object-fit: cover;
}

يعتمد تأثير التمرير الذي نقوم به على CSS هذا. ربما يبدو غريبًا بالنسبة لك أننا نصنع صورًا ليس لها عرض أو ارتفاع ولكن بحد أدنى للعرض والارتفاع يبلغ 100٪. لكن سترى أنها خدعة رائعة لما نحاول تحقيقه.

ما أفعله هنا هو إخبار المتصفح أن الصور يجب أن تكون موجودة 0 العرض والارتفاع ولكن يجب أيضًا أن يكون لها حد أدنى للارتفاع يساوي 100%… لكن 100% من ماذا؟ عند استخدام النسب المئوية ، تكون القيمة بالنسبة لشيء آخر. في هذه الحالة ، يتم وضع صورتنا داخل أ خلية الشبكة ونحتاج إلى معرفة هذا الحجم لمعرفة ما هو 100% هو نسبي ل.

سوف يتجاهل المتصفح أولاً min-height: 100% لحساب حجم خلايا الشبكة ، لكنها ستستخدم الامتداد height: 0 في حسابه. هذا يعني أن صورنا لن تساهم في حجم الخلايا الشبكية ... لأنها من الناحية الفنية ليس لها حجم مادي. سينتج عن ذلك ثلاثة أعمدة وصفوف متساوية تستند إلى حجم الشبكة (التي حددناها في .galleryعرض و aspect-ratio). ارتفاع كل خلية شبكة ليس سوى المتغير --s حددنا (نفس العرض).

تكبير الصور في تخطيط الشبكة

الآن بعد أن أصبح لدينا أبعاد خلايا شبكتنا ، سيستخدمها المتصفح مع min-height: 100%min-width: 100%) مما سيجبر الصور على ملء مساحة كل خلية شبكية بالكامل. قد يبدو الأمر برمته مربكًا بعض الشيء ولكن الفكرة الرئيسية هي التأكد من أن الشبكة تحدد حجم الصور وليس العكس. لا أريد أن تحدد الصورة حجم الشبكة وسوف تفهم السبب بعد إضافة تأثير التمرير.

إنشاء تأثير التمرير

ما يتعين علينا القيام به هو زيادة حجم الصور عندما يتم تحريكها فوقها. يمكننا القيام بذلك عن طريق تعديل الصورة width و height on :hover:

.gallery {
  --f: 1.5; /* controls the scale factor */
}

.gallery img:hover{
  width:  calc(var(--s) * var(--f));
  height: calc(var(--s) * var(--f));
}

أضفت متغيرًا مخصصًا جديدًا ، --f، إلى المزيج كعامل مقياس للتحكم في الحجم عند التمرير. لاحظ كيف أضرب متغير الحجم ، --sبواسطته لحساب حجم الصورة الجديد.

لكنك قلت أن حجم الصورة يجب أن يكون 0. ماذا يحدث؟ أنا ضائع…

ما قلته لا يزال صحيحًا ولكني أستثني الصورة التي تم تحريكها. أخبر المتصفح أن صورة واحدة فقط سيكون لها حجم لا يساوي الصفر - لذلك ستساهم في أبعاد الشبكة - بينما تظل كل الصور الأخرى متساوية 0.

تكبير الصور في تخطيط الشبكة PlatoBlockchain Data Intelligence. البحث العمودي. عاي.
تكبير الصور في تخطيط الشبكة

يظهر الجانب الأيسر الشبكة في حالتها الطبيعية بدون أي صور متحركة ، وهو ما يظهره الجانب الأيمن. جميع خلايا الشبكة على الجانب الأيسر متساوية في الحجم لأن جميع الصور ليس لها أبعاد مادية.

على الجانب الأيمن ، يتم تحريك الصورة الثانية في الصف الأول ، مما يعطيها أبعادًا تؤثر على حجم خلية الشبكة. سيجعل المتصفح خلية الشبكة المحددة أكبر عند التمرير ، مما يساهم في الحجم الكلي. ونظرًا لأن حجم الشبكة بالكامل مضبوط (لأننا حددنا قيمة ثابتة width على .gallery) ، ستستجيب خلايا الشبكة الأخرى منطقيًا بأن تصبح أصغر من أجل الحفاظ على .galleryالحجم الإجمالي في اللباقة.

هذا هو تأثير التكبير لدينا في العمل! من خلال زيادة حجم صورة واحدة فقط ، فإننا نؤثر على تكوين الشبكة بالكامل ، وقلنا من قبل أن الشبكة تحدد حجم الصور بحيث تمتد كل صورة داخل خلية الشبكة الخاصة بها لملء كل المساحة.

لهذا نضيف لمسة transition واستخدامها object-fit لتجنب تشويه الصورة والوهم مثالي!

أعلم أن المنطق الكامن وراء الحيلة ليس من السهل فهمه. لا تقلق إذا لم تفهمها تمامًا. الأهم هو فهم بنية الكود المستخدم وكيفية تعديله للحصول على مزيد من الاختلافات. هذا ما سنفعله بعد ذلك!

إضافة المزيد من الصور

لقد أنشأنا شبكة 3 × 3 لشرح الخدعة الرئيسية ، لكنك ربما خمنت أنه لا داعي للتوقف عند هذا الحد. يمكننا جعل عدد الأعمدة ومتغيرات الصفوف وإضافة العديد من الصور كما نريد.

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--s) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--s) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

لدينا متغيرين جديدين لعدد الصفوف والأعمدة. ثم نقوم ببساطة بتعريف عرض شبكتنا وارتفاعها باستخدامهما. الشيء نفسه بالنسبة ل grid-template-columns والذي يستخدم --m عامل. ومثلما حدث من قبل ، لا نحتاج إلى تحديد الصفوف بشكل صريح نظرًا لأن ميزة الوضع التلقائي لشبكة CSS ستؤدي المهمة بالنسبة لنا بغض النظر عن عدد عناصر الصورة التي نستخدمها.

لماذا لا توجد قيم مختلفة للعرض والارتفاع؟ بإمكاننا أن نفعل ذلك:

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --h: 120px; /* control the height */
  --w: 150px; /* control the width */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--w) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--h) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

.gallery img:hover{
  width:  calc(var(--w)*var(--f));
  height: calc(var(--h)*var(--f));
}

نحن نستبدل --s بمتغيرين ، أحدهما للعرض ، --w، وواحد آخر للارتفاع ، --h. ثم نقوم بتعديل كل شيء وفقًا لذلك.

لذلك ، بدأنا بشبكة ذات حجم ثابت وعدد من العناصر ، ولكن بعد ذلك قمنا بإنشاء مجموعة جديدة من المتغيرات للحصول على أي تكوين نريده. كل ما يتعين علينا القيام به هو إضافة العديد من الصور كما نريد وضبط متغيرات CSS وفقًا لذلك. التركيبات لا حدود لها!

ماذا عن نسخة ملء الشاشة؟ نعم ، هذا ممكن أيضًا. كل ما نحتاجه هو معرفة القيم التي نحتاج إلى تخصيصها لمتغيراتنا. إذا أردنا N صفوف من الصور ونريد أن تكون شبكتنا في وضع ملء الشاشة ، نحتاج أولاً إلى إيجاد ارتفاع 100vh:

var(--n) * var(--h) + (var(--n) - 1) * var(--g) = 100vh

نفس المنطق للعرض ، ولكن باستخدام vw بدلا من vh:

var(--m) * var(--w) + (var(--m) - 1) * var(--g) = 100vw

نقوم بالحسابات لنحصل على:

--w: (100vw - (var(--m) - 1) * var(--g)) / var(--m)
--h: (100vh - (var(--n) - 1) * var(--g)) / var(--n)

القيام به!

إنه نفس HTML بالضبط ولكن مع بعض المتغيرات المحدثة التي تغير حجم الشبكة وسلوكها.

لاحظ أنني حذفت الصيغة التي حددناها مسبقًا في .galleryالصورة width و height واستبدالها بـ 100vw و 100vh، على التوالى. ستعطينا الصيغة نفس النتيجة ولكن نظرًا لأننا نعرف القيمة التي نريدها ، يمكننا التخلص من كل هذا التعقيد الإضافي.

يمكننا أيضًا تبسيط --h و --w عن طريق إزالة الفجوة من المعادلة لصالح هذا:

--h: calc(100vh / var(--n)); /* Viewport height divided by number of rows */
--w: calc(100vw / var(--m)); /* Viewport width divided by number of columns */

سيؤدي ذلك إلى زيادة نمو الصورة التي تم تحريكها قليلاً عن المثال السابق ، ولكنها ليست مشكلة كبيرة حيث يمكننا التحكم في المقياس باستخدام --f متغير نستخدمه كمضاعف.

ونظرًا لاستخدام المتغيرات في مكان واحد ، فلا يزال بإمكاننا تبسيط الكود بإزالتها تمامًا:

من المهم ملاحظة أن هذا التحسين ينطبق فقط على مثال ملء الشاشة وليس على الأمثلة التي غطيناها. هذا المثال هو حالة خاصة حيث يمكننا جعل الكود أخف وزناً عن طريق إزالة بعض الأعمال الحسابية المعقدة التي نحتاجها في الأمثلة الأخرى.

لدينا في الواقع كل ما نحتاجه لإنشاء النمط الشائع لتوسيع الألواح:

دعونا نحفر أعمق

هل لاحظت أن عامل القياس لدينا يمكن أن يكون أقل من 1؟ يمكننا تحديد حجم الصورة التي تم تحريك المؤشر عليها لتكون أصغر من --h or --w لكن الصورة تكبر عند المرور بالماوس.

الحجم الأولي لخلية الشبكة يساوي --w و --h، فلماذا تجعل القيم الأصغر خلية الشبكة أكبر؟ لا ينبغي أن تحصل الخلية الأصغر، أو على الأقل الحفاظ على حجمها الأولي؟ وما هو الحجم النهائي لخلية الشبكة؟

نحتاج إلى التعمق أكثر في كيفية حساب خوارزمية CSS Grid لحجم خلايا الشبكة. وهذا ينطوي على فهم افتراضي لشبكة CSS محاذاة تمتد.

هذا مثال لفهم المنطق.

على الجانب الأيسر من العرض التوضيحي ، قمت بتعريف عمودين بـ auto العرض. نحصل على النتيجة البديهية: عمودان متساويان (وخليتان شبكيتان متساويتان). لكن الشبكة التي أعددتها على الجانب الأيمن من العرض التوضيحي ، حيث أقوم بتحديث المحاذاة باستخدام place-content: start، يبدو أنه لا يوجد لديه شيء.

تساعد DevTools في توضيح ما يحدث بالفعل في كلتا الحالتين:

تكبير الصور في تخطيط الشبكة PlatoBlockchain Data Intelligence. البحث العمودي. عاي.
تكبير الصور في تخطيط الشبكة

في الشبكة الثانية ، لدينا عمودين ، لكن عرضهما يساوي صفرًا ، لذلك نحصل على خليتين شبكيتين مطويتين في الزاوية العلوية اليسرى من حاوية الشبكة. هذا هو ليس خطأ ولكن النتيجة المنطقية لمحاذاة الشبكة. عندما نقوم بتغيير حجم العمود (أو الصف) باستخدام auto، فهذا يعني أن محتواه يحدد حجمه - لكن لدينا مساحة فارغة div مع عدم وجود محتوى لإفساح المجال له.

لكن منذ ذلك الحين stretch هي المحاذاة الافتراضية ولدينا مساحة كافية داخل شبكتنا ، وسيقوم المتصفح بتمديد كل من خلايا الشبكة بالتساوي لتغطية كل تلك المنطقة. هذه هي الطريقة التي تنتهي بها الشبكة الموجودة على اليسار بعمودين متساويين.

من المواصفات:

لاحظ أن بعض قيم justify-content و align-content يمكن أن يتسبب في تباعد المسارات (space-around, space-between, space-evenly) أو يتم تغيير حجمها (stretch).

لاحظ "ليتم تغيير حجمها" وهو المفتاح هنا. في المثال الأخير ، اعتدت place-content وهو اختصار ل justify-content و align-content

وهذا مدفون في مكان ما خوارزمية تحجيم الشبكة المواصفات:

تعمل هذه الخطوة على توسيع المسارات التي تحتوي على ملف السيارات أقصى وظيفة تحجيم المسار بقسمة أي باقٍ موجب ، واضح مساحة حرة بينهم بالتساوي. إذا كانت المساحة الحرة غير محدد، ولكن حاوية الشبكة محدد العرض الأدنى / الارتفاع، استخدم هذا الحجم لحساب المساحة الخالية لهذه الخطوة بدلاً من ذلك.

يشرح مصطلح "بالتساوي" لماذا ننتهي بخلايا شبكية متساوية ، ولكنه ينطبق على "المساحة الحرة" وهو أمر مهم جدًا.

لنأخذ المثال السابق ونضيف محتوى إلى أحد ملفات divs:

أضفنا مربعًا 50px صورة. فيما يلي توضيح لكيفية استجابة كل شبكة في مثالنا لتلك الصورة:

تكبير الصور في تخطيط الشبكة PlatoBlockchain Data Intelligence. البحث العمودي. عاي.
تكبير الصور في تخطيط الشبكة

في الحالة الأولى ، يمكننا أن نرى أن الخلية الأولى (باللون الأحمر) أكبر من الثانية (باللون الأزرق). في الحالة الثانية ، يتغير حجم الخلية الأولى لتناسب الحجم المادي للصورة بينما تظل الخلية الثانية بدون أبعاد. يتم تقسيم المساحة الخالية بالتساوي ، ولكن تحتوي الخلية الأولى على محتوى أكبر بداخلها مما يجعلها أكبر.

هذه هي الرياضيات لمعرفة المساحة الخالية لدينا:

(grid width) - (gap) - (image width) = (free space)
200px - 5px - 50px = 145px 

مقسومًا على اثنين - عدد الأعمدة - نحصل على عرض 72.5px لكل عمود. لكننا نضيف حجم الصورة ، 50px، إلى العمود الأول الذي يترك لنا عمودًا واحدًا عند 122.5px والثاني يساوي 72.5px.

نفس المنطق ينطبق على شبكة الصور لدينا. كل الصور لها حجم يساوي 0 (لا يوجد محتوى) بينما تساهم الصورة التي تم تحريكها في الحجم - حتى لو كانت فقط 1px - جعل خليتها الشبكية أكبر من الخلايا الأخرى. لهذا السبب ، يمكن أن يكون عامل القياس أكبر من أي قيمة 0 حتى بين الكسور العشرية 0 و 1.

للحصول على العرض النهائي لخلايا الشبكة ، نقوم بنفس العملية الحسابية للحصول على ما يلي:

(container width) - (sum of all gaps) - (hovered image width) = (free space)

يتم تحديد عرض الحاوية من خلال:

var(--m)*var(--w) + (var(--m) - 1)*var(--g)

... وجميع الفجوات متساوية مع:

(var(--m) - 1)*var(--g)

... وللصورة التي تم تحريكها لدينا:

var(--w)*var(--f)

يمكننا حساب كل ذلك باستخدام متغيراتنا:

var(--m)*var(--w) - var(--w)*var(--f) = var(--w)*(var(--m) - var(--f))

يتم تحديد عدد الأعمدة بواسطة --m ، لذلك نقسم هذه المساحة الفارغة بالتساوي للحصول على:

var(--w)*(var(--m) - var(--f))/var(--m)

... مما يعطينا حجم الصور غير المتحركة. بالنسبة للصور التي تم تحريكها ، لدينا هذا:

var(--w)*(var(--m) - var(--f))/var(--m) + var(--w)*var(--f)
var(--w)*((var(--m) - var(--f))/var(--m) + var(--f))

إذا أردنا التحكم في الحجم النهائي للصورة التي تم تحريكها ، فإننا نعتبر الصيغة أعلاه للحصول على الحجم الدقيق الذي نريده. على سبيل المثال ، إذا أردنا أن تكون الصورة أكبر بمرتين:

(var(--m) - var(--f))/var(--m) + var(--f) = 2

إذن ، قيمة مضاعف مقياسنا ، --f، يجب أن تكون مساوية لـ:

var(--m)/(var(--m) - 1)

لثلاثة أعمدة سيكون لدينا 3/2 = 1.5 وهذا هو عامل الحجم الذي استخدمته في العرض التوضيحي الأول لهذه المقالة لأنني أردت جعل الصورة أكبر بمرتين عند المرور فوقها!

ينطبق نفس المنطق على حساب الارتفاع ، وفي حالة رغبتنا في التحكم في كليهما بشكل مستقل ، فسنحتاج إلى النظر في عاملين للقياس للتأكد من أن لدينا عرضًا وارتفاعًا محددين عند التحويم.

.gallery {
  /* same as before */
   --fw: 1.5; /* controls the scale factor for the width */
   --fh: 1.2; /* controls the scale factor for the height */

  /* same as before */
}

.gallery img:hover{
  width:  calc(var(--w)*var(--fw));
  height: calc(var(--h)*var(--fh));
}

الآن ، أنت تعرف كل الأسرار لإنشاء أي نوع من شبكة الصور مع تأثير تحوم رائع مع التحكم أيضًا في الحجم الذي تريده باستخدام الرياضيات التي غطيناها للتو.

اختتام

في بلدي مشاركة المقالة، أنشأنا شبكة ذات مظهر معقد مع بضعة أسطر من CSS التي تستخدم الشبكة الضمنية وميزات التنسيب التلقائي في CSS Grid. في هذه المقالة ، اعتمدنا على بعض خدع تحجيم CSS Grid لإنشاء شبكة رائعة من الصور التي تقوم بالتكبير عند التمرير وتتسبب في ضبط الشبكة وفقًا لذلك. كل هذا برمز مبسط يسهل تعديله باستخدام متغيرات CSS!

في المقالة التالية ، سنلعب بالأشكال! سنقوم بدمج شبكة CSS مع القناع ومسار المقطع للحصول على شبكة رائعة من الصور.

الطابع الزمني:

اكثر من الخدع المغلق