قم بإنشاء تأثيرات صورة مستجيبة باستخدام تدرجات CSS ونسبة العرض إلى الارتفاع

نشرت: 2022-03-10
ملخص سريع ↬ تتمثل المشكلة التقليدية في CSS في الحفاظ على نسبة العرض إلى الارتفاع للصور عبر المكونات ذات الصلة ، مثل البطاقات. توفر خاصية aspect-ratio المدعومة حديثًا جنبًا إلى جنب مع object-fit علاجًا لصداع الماضي هذا! دعنا نتعلم استخدام هذه الخصائص ، بالإضافة إلى إنشاء تأثير صورة متدرج سريع الاستجابة لمزيد من الذوق.

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

قد يكون الحل السابق الآخر إلى جانب الاقتصاص هو التبديل من ملف img مضمّن إلى عنصر div فارغ كان موجودًا فقط لتقديم الصورة عبر صورة background-image . لقد نفذت هذا الحل عدة مرات بنفسي في الماضي. تتمثل إحدى الميزات التي يتمتع بها هذا في استخدام خدعة قديمة لنسبة العرض إلى الارتفاع والتي تستخدم عنصر ارتفاع صفري وتعيين قيمة padding-bottom . يؤدي تعيين قيمة المساحة المتروكة كنسبة مئوية إلى قيمة محسوبة نهائية تتعلق بعرض العنصر. ربما تكون قد استخدمت هذه الفكرة أيضًا للحفاظ على نسبة 16: 9 لتضمينات الفيديو ، وفي هذه الحالة يتم العثور على قيمة المساحة المتروكة بالصيغة: 9/16 = 0.5625 * 100% = 56.26% . لكننا سنستكشف خاصيتين حديثتين لـ CSS لا تتطلبان المزيد من الرياضيات ، وتعطينا المزيد من المرونة ، وتسمحان أيضًا بالحفاظ على الدلالات المقدمة باستخدام img حقيقي بدلاً من div فارغ.

أولاً ، دعنا نحدد دلالات HTML ، بما في ذلك استخدام قائمة غير مرتبة كحاوية البطاقات:

 <ul class="card-wrapper"> <li class="card"> <img src="" alt=""> <h3>A Super Wonderful Headline</h3> <p>Lorem ipsum sit dolor amit</p> </li> <!-- additional cards --> </ul>

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

 .card { background-color: #fff; border-radius: 0.5rem; box-shadow: 0.05rem 0.1rem 0.3rem -0.03rem rgba(0, 0, 0, 0.45); padding-bottom: 1rem; } .card > :last-child { margin-bottom: 0; } .card h3 { margin-top: 1rem; font-size: 1.25rem; } img { border-radius: 0.5rem 0.5rem 0 0; width: 100%; } img ~ * { margin-left: 1rem; margin-right: 1rem; }

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

ويقودنا تقدمنا ​​حتى الآن إلى ظهور البطاقة التالية:

بطاقة واحدة بالأنماط الأساسية الموصوفة سابقًا والتي تم تطبيقها وتتضمن صورة من Unsplash للحلوى على طبق صغير بجوار مشروب ساخن في كوب
بطاقة واحدة مع الأنماط الأساسية الموصوفة سابقًا المطبقة وتتضمن صورة من Unsplash للحلوى على طبق صغير بجوار مشروب ساخن في كوب. (معاينة كبيرة)

أخيرًا ، .card-wrapper لتخطيط سريع الاستجابة باستخدام شبكة CSS. سيؤدي هذا أيضًا إلى إزالة أنماط القائمة الافتراضية.

 .card-wrapper { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(30ch, 1fr)); grid-gap: 1.5rem; }

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

مع تطبيق هذا ومع جميع البطاقات التي تحتوي على صورة بمسار مصدر صالح ، توفر لنا أنماط .card-wrapper البطاقة.

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

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

المزيد بعد القفز! أكمل القراءة أدناه ↓

تفعيل Uniform Image Sizes مع object-fit

كما ذكرنا سابقًا ، ربما تكون قد أجريت تحديثًا مسبقًا في هذا السيناريو لتغيير الصور لإضافتها عبر background-image بدلاً من ذلك واستخدام background-size: cover للتعامل مع تغيير حجم الصورة بشكل جيد. أو ربما تكون قد حاولت فرض الاقتصاص مسبقًا (لا يزال هدفًا مهمًا لأن أي تقليل لحجم الصورة سيؤدي إلى تحسين الأداء!).

الآن ، لدينا خاصية object-fit والتي تتيح لعلامة img أن تعمل كحاوية للصورة. وهو يأتي مع قيمة cover أيضًا ينتج عنها تأثير مشابه لحل صورة الخلفية ، ولكن مع ميزة الاحتفاظ بدلالات الصورة المضمنة. دعونا نطبقها ونرى كيف تعمل.

نحتاج إلى إقرانها بأبعاد height للحصول على إرشادات إضافية حول الطريقة التي نريد أن تتصرف بها حاوية الصورة (تذكر أننا أضفنا width: 100% ). وسنستخدم الدالة max() لتحديد إما 10rem أو 30vh اعتمادًا على أيهما أكبر في سياق معين ، مما يمنع ارتفاع الصورة من التقلص كثيرًا في إطارات العرض الأصغر أو عندما يقوم المستخدم بتعيين تكبير / تصغير كبير.

 img { /* ...existing styles */ object-fit: cover; height: max(10rem, 30vh); }

نصيحة إضافية لإمكانية الوصول : يجب عليك دائمًا اختبار تخطيطاتك بنسبة تكبير 200٪ و 400٪ على سطح المكتب. على الرغم من عدم وجود استعلام عن وسائط zoom حاليًا ، إلا أن وظائف مثل max() يمكن أن تساعد في حل مشكلات التخطيط. سياق آخر هذه التقنية مفيد هو التباعد بين العناصر.

مع هذا التحديث ، قمنا بالتأكيد بتحسين الأشياء ، والنتيجة المرئية كما لو كنا سنستخدم تقنية صورة الخلفية الأقدم:

يبدو الآن أن الصور المكونة من ثلاث بطاقات لها ارتفاع موحد ويتم توسيط محتويات الصورة داخل الصورة كما لو كانت حاوية
يبدو الآن أن الصور المكونة من ثلاث بطاقات لها ارتفاع موحد ويتم توسيط محتويات الصورة داخل الصورة كما لو كانت حاوية. (معاينة كبيرة)

تحجيم صورة متسق سريع الاستجابة مع aspect-ratio

عند استخدام object-fit حد ذاته ، فإن أحد الجوانب السلبية هو أننا ما زلنا بحاجة إلى تعيين بعض تلميحات الأبعاد.

خاصية قادمة (متوفرة حاليًا في متصفحات Chromium) تسمى aspect-ratio ستعزز قدرتنا على تغيير حجم الصور باستمرار.

باستخدام هذه الخاصية ، يمكننا تحديد نسبة لتغيير حجم الصورة بدلاً من تعيين أبعاد صريحة. سنستمر في استخدامه جنبًا إلى جنب مع object-fit للتأكد من أن هذه الأبعاد لا تؤثر إلا على الصورة كحاوية ، وإلا فقد تظهر الصورة مشوهة.

إليك قاعدة الصور المحدثة بالكامل:

 img { border-radius: 0.5rem 0.5rem 0 0; width: 100%; object-fit: cover; aspect-ratio: 4/3; }

سنبدأ بنسبة صورة 4 3 لسياق بطاقتنا ، ولكن يمكنك اختيار أي نسبة. على سبيل المثال ، 11 لمربع أو 16 9 لتضمينات الفيديو القياسية.

فيما يلي البطاقات المحدثة ، على الرغم من أنه من المحتمل أن يكون من الصعب ملاحظة الاختلاف المرئي في هذه الحالة بالذات نظرًا لأن نسبة العرض إلى الارتفاع تتطابق بشكل وثيق مع المظهر الذي حققناه من خلال تعيين height object-fit وحده.

الصور المكونة من ثلاث بطاقات لها أبعاد عرض وارتفاع متطابقة ، والتي تختلف قليلاً عن حل ملاءمة الكائن السابق
الصور المكونة من ثلاث بطاقات لها أبعاد عرض وارتفاع متطابقة ، والتي تختلف قليلاً عن حل ملاءمة الكائن السابق. (معاينة كبيرة)

يؤدي تعيين "نسبة عرض إلى ارتفاع" إلى الحفاظ على النسبة مع نمو العناصر أو تقلصها ، بينما عند تعيين "ملاءمة الكائن" و "الارتفاع" فقط ، ستكون نسبة الصورة في حالة تغير مستمر مع تغير أبعاد الحاوية.

"

إضافة تأثيرات مستجيبة مع تدرجات ووظائف CSS

حسنًا ، الآن بعد أن عرفنا كيفية إعداد الصور ذات الحجم المتسق ، فلنستمتع ببعض المرح عن طريق إضافة تأثير متدرج!

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

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

 .card { --card-gradient: #5E9AD9, #E271AD; background-image: linear-gradient( var(--card-gradient), white max(9.5rem, 27vh) ); /* ...existing styles */ }

لكن انتظر - هل هذه وظيفة CSS max() ؟ في التدرج؟ نعم ، هذا ممكن ، والسحر هو الذي يجعل هذا التدرج فعالاً بشكل متجاوب!

ومع ذلك ، إذا قمت بإضافة لقطة شاشة ، فلن نرى في الواقع للتدرج أي تأثير على الصورة حتى الآن. لذلك ، نحتاج إلى إحضار خاصية mix-blend-mode ، وفي هذا السيناريو سنستخدم قيمة overlay :

 img { /* ...existing styles */ mix-blend-mode: overlay; }

تتشابه خاصية mix-blend-mode مع تطبيق أنماط مزج الطبقات المتوفرة في برامج معالجة الصور مثل Photoshop. وسيكون لقيمة overlay تأثير السماح بدمج الدرجات اللونية المتوسطة في الصورة مع التدرج اللوني خلفها ، مما يؤدي إلى النتيجة التالية:

تحتوي كل صورة بطاقة على تأثير مزج متدرج يبدأ باللون الأزرق الفاتح في الأعلى ، ويمتزج باللون الوردي المحمر ، ثم ينتهي بالتدرج إلى اللون الأبيض قبل باقي محتوى نص البطاقة
كل صورة بطاقة لها تأثير مزج متدرج يبدأ باللون الأزرق الفاتح في الأعلى ، والذي يمتزج مع اللون الوردي المحمر ، ثم ينتهي بالتدرج إلى اللون الأبيض قبل باقي محتوى نص البطاقة. (معاينة كبيرة)

الآن ، في هذه المرحلة ، نعتمد على قيمة aspect-ratio وحدها لتغيير حجم الصورة. وإذا قمنا بتغيير حجم الحاوية وتسببنا في إعادة تدفق مخطط البطاقة ، فإن تغيير ارتفاع الصورة يؤدي إلى تناقضات حيث يتلاشى التدرج إلى اللون الأبيض.

لذلك سنضيف خاصية max-height أيضًا والتي تستخدم أيضًا الدالة max() وتحتوي على قيم أكبر قليلاً من تلك الموجودة في التدرج اللوني. السلوك الناتج هو أن التدرج (دائمًا تقريبًا) يصطف بشكل صحيح مع الجزء السفلي من الصورة.

 img { /* ...existing styles */ max-height: max(10rem, 30vh); }

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

"

ومع ذلك ، ستستمر aspect-ratio في ضمان تغيير حجم الصور باستمرار كما كانت الفائدة على object-fit فقط. حاول التعليق aspect-ratio في العرض التوضيحي النهائي لـ CodePen لمعرفة الفرق الذي تحدثه عبر أحجام الحاويات.

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

البديل: mix-blend-mode وإضافة مرشح

كان استخدام overlay كقيمة mix-blend-mode هو الخيار الأفضل لتأثير التلاشي إلى الأبيض الذي كنا نبحث عنه ، ولكن دعنا نجرب خيارًا بديلًا لتأثير أكثر دراماتيكية.

سنقوم بتحديث الحل الخاص بنا لإضافة خاصية مخصصة CSS لقيمة mix-blend-mode وأيضًا تحديث قيم اللون للتدرج:

 .card { --card-gradient: tomato, orange; --card-blend-mode: multiply; } img { /* ...existing styles */ mix-blend-mode: var(--card-blend-mode); }

قيمة multiply لها تأثير داكن على الدرجات اللونية المتوسطة ، لكنها تحافظ على الأبيض والأسود كما هي ، مما ينتج عنه المظهر التالي:

كل صورة بطاقة لها صبغة برتقالية قوية من التدرج الجديد الذي يبدأ من الأحمر البرتقالي إلى البرتقالي النقي. المناطق البيضاء لا تزال بيضاء والمناطق السوداء لا تزال سوداء
كل صورة بطاقة لها صبغة برتقالية قوية من التدرج الجديد الذي يبدأ من الأحمر البرتقالي إلى البرتقالي النقي. المناطق البيضاء لا تزال بيضاء والمناطق السوداء لا تزال سوداء. (معاينة كبيرة)

بينما فقدنا التلاشي ولدينا الآن حافة صلبة أسفل الصورة ، لا يزال الجزء الأبيض من التدرج اللوني مهمًا لضمان انتهاء التدرج قبل محتوى البطاقة.

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

 img { /* ...existing styles */ filter: grayscale(100); }

ينتج عن استخدام قيمة grayscale(100) إزالة كاملة للألوان الطبيعية للصورة وتحويلها إلى أبيض وأسود. إليك التحديث للمقارنة مع لقطة الشاشة السابقة لتأثيرها عند استخدام التدرج البرتقالي مع multiply :

الآن لا تزال كل صورة بطاقة تحتوي على التدرج البرتقالي ولكن تتم إزالة كل الألوان الأخرى واستبدالها بظلال من الرمادي
الآن لا تزال كل صورة بطاقة تحتوي على التدرج البرتقالي ولكن تتم إزالة كل الألوان الأخرى واستبدالها بظلال من الرمادي. (معاينة كبيرة)

استخدم aspect-ratio كتحسين تدريجي

كما ذكرنا سابقًا ، لا يتم دعم aspect-ratio حاليًا إلا في أحدث إصدار من متصفحات Chromium (Chrome و Edge). ومع ذلك ، تدعم جميع المتصفحات object-fit وهذا بالإضافة إلى قيود height لدينا يؤدي إلى نتيجة أقل مثالية ولكنها لا تزال مقبولة ، كما هو موضح هنا في Safari:

يتم تحديد ارتفاع صورة البطاقة ، ولكن كل بطاقة لها ارتفاع محقق مختلف قليلاً
يتم تحديد ارتفاع صورة البطاقة ، ولكن كل بطاقة لها ارتفاع محقق مختلف قليلاً. (معاينة كبيرة)

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

تمديد تأثيرات التدرج

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

أولاً ، سنقوم بتحديث كل بطاقة h3 لتحتوي على ارتباط ، مثل:

 <h3><a href="">A Super Wonderful Headline</a></h3>

بعد ذلك ، يمكننا استخدام أحد أحدث المحددات المتاحة لدينا - :focus-within - لتغيير التدرج اللوني للبطاقة عندما يكون الرابط في بؤرة التركيز. للحصول على تغطية إضافية للتفاعلات المحتملة ، سنقرن هذا بـ :hover . وسنقوم بإعادة استخدام فكرة max() الخاصة بنا لتعيين لون واحد لتولي تغطية جزء الصورة من البطاقة. الجانب السلبي لهذا التأثير الخاص هو أن توقفات التدرج وتغييرات الألوان ليست قابلة للتحريك بشكل موثوق - لكنها ستتحقق قريبًا بفضل CSS Houdini.

لتحديث اللون وإضافة التوقف اللوني الجديد ، نحتاج فقط إلى إعادة تعيين قيمة --card-gradient ضمن هذه القاعدة الجديدة:

 .card:focus-within, .card:hover { --card-gradient: #24a9d5 max(8.5rem, 20vh); }

قيمنا max() أقل من الأصل المستخدم للون white للحفاظ على الحافة المصقولة بالريش. إذا استخدمنا نفس القيم ، فإنها ستلتقي white وتخلق فصلًا واضحًا للمسودة.

في إنشاء هذا العرض التوضيحي ، جربت في الأصل تأثيرًا يستخدم transform scale لتأثير التكبير. لكنني اكتشفت أنه نظرًا لتطبيق mix-blend-mode ، لن يقوم المتصفح بإعادة رسم الصورة باستمرار مما تسبب في حدوث وميض غير سار. ستكون هناك دائمًا مفاضلات في مطالبة المتصفح بتنفيذ تأثيرات CSS ورسوم متحركة فقط ، وعلى الرغم من أنه من الرائع جدًا ما يمكننا القيام به ، فمن الأفضل دائمًا التحقق من تأثير أداء تأثيراتك.

استمتع بالتجربة!

لقد منحتنا CSS الحديثة بعض الأدوات الرائعة لتحديث مجموعات أدوات تصميم الويب الخاصة بنا ، مع كون aspect-ratio هي أحدث إضافة. لذا انطلق ، واختبر object-fit ، aspect-ratio ، وأضف وظائف مثل max() إلى التدرجات اللونية للحصول على بعض تأثيرات الاستجابة الممتعة! فقط تأكد من إعادة التحقق من الأشياء عبر المستعرضات (في الوقت الحالي!) وعبر منافذ العرض وأحجام الحاويات المختلفة.

إليك CodePen بما في ذلك الميزات والتأثيرات التي استعرضناها اليوم:

راجع القلم [تأثيرات الصور المتجاوبة مع تدرجات CSS ونسبة العرض إلى الارتفاع] (https://codepen.io/smashingmag/pen/WNoERXo) بقلم ستيفاني إيكليس.

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

اتبحث عن المزيد؟ تأكد من مراجعة دليل CSS الخاص بنا هنا على Smashing →