CSS Gradyanları ve en boy oranı ile Duyarlı Görüntü Efektleri Oluşturun

Yayınlanan: 2022-03-10
Hızlı özet ↬ CSS'deki klasik bir sorun, kartlar gibi ilgili bileşenler arasında görüntülerin en boy oranını korumaktır. Yeni desteklenen aspect-ratio özelliği, object-fit ile birlikte geçmişteki bu baş ağrısına bir çare sunuyor! Ekstra yetenek için duyarlı bir degrade görüntü efekti oluşturmaya ek olarak bu özellikleri kullanmayı öğrenelim.

Gelecekteki görüntü efektlerimize hazırlanmak için, üstte büyük bir görüntü ve ardından bir başlık ve açıklama bulunan bir kart bileşeni oluşturacağız. Bu kurulumla ilgili ortak sorun, görüntünün ne olduğu ve daha da önemlisi yerleşimimiz için boyutlarının ne olduğu üzerinde her zaman mükemmel kontrole sahip olamayabilmemizdir. Bu, önceden kırparak çözülebilse de, duyarlı boyuttaki kaplar nedeniyle sorunlarla karşılaşabiliriz. Bunun bir sonucu, bir sıra kart sunduğunuz zaman gerçekten göze çarpan kart içeriğinin eşit olmayan konumlarıdır.

Kırpmanın yanı sıra önceki bir başka çözüm, satır içi bir div yalnızca görüntüyü background-image aracılığıyla sunmak için var olan boş bir img geçmek olabilir. Bu çözümü geçmişte birçok kez kendim uyguladım. Bunun sahip olduğu bir avantaj, en boy oranı için sıfır yükseklik öğesi kullanan ve padding-bottom değeri ayarlayan daha eski bir numara kullanmaktır. Bir dolgu değerinin yüzde olarak ayarlanması, öğenin genişliğine göre son hesaplanmış bir değerle sonuçlanır. Bu fikri, video yerleştirmeleri için 16:9 oranını korumak için de kullanmış olabilirsiniz; bu durumda dolgu değeri şu formülle bulunur: 9/16 = 0.5625 * 100% = 56.26% . Ancak fazladan matematik içermeyen, bize daha fazla esneklik sağlayan ve ayrıca boş bir div yerine gerçek bir img kullanarak sağlanan anlambilimin korunmasına izin veren iki modern CSS özelliğini keşfedeceğiz .

İlk olarak, kartların kapsayıcısı olarak sırasız bir listenin kullanımı dahil olmak üzere HTML semantiğini tanımlayalım:

 <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>

Ardından, .card bileşeni için minimal bir temel stil seti oluşturacağız. Kartın kendisi için bazı temel görsel stiller, beklenen h3 başlığına hızlı bir güncelleme ve ardından kart görüntüsünü stillendirmeye başlamak için temel stiller ayarlayacağız.

 .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; }

Son kural, görüntünün kendisinin kartın kenarlarıyla aynı img olmasını istediğimizden, görüntüyü izleyen herhangi bir öğeye yatay bir kenar boşluğu eklemek için genel kardeş birleştiriciyi kullanır.

Ve şimdiye kadarki ilerlememiz bizi aşağıdaki kart görünümüne götürüyor:

Daha önce açıklanan temel stillerin uygulandığı ve bir kupadaki sıcak içeceğin yanındaki küçük bir tabakta bir tatlının Unsplash'ından bir görüntü içeren bir kart
Daha önce açıklanan temel stillerin uygulandığı ve bir kupadaki sıcak içeceğin yanında küçük bir tabakta bir tatlının Unsplash'tan bir görüntüsünü içeren bir kart. (Büyük önizleme)

Son olarak, CSS ızgarasını kullanarak hızlı yanıt veren bir düzen için .card-wrapper stilleri oluşturacağız. Bu, varsayılan liste stillerini de kaldıracaktır.

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

Not : Bu ızgara tekniği size yabancıysa, 12 sütunlu ızgara için modern çözümlerle ilgili öğreticimdeki açıklamayı gözden geçirin.

Bu uygulandığında ve geçerli bir kaynak yolu olan bir görüntü içeren tüm kartlarda, .card-wrapper stillerimiz bize aşağıdaki düzeni verir:

Uygulanan kart sarma düzeni stilleri nedeniyle arka arkaya üç kart gösterilir. Her kartın, farklı doğal en boy oranlarına sahip benzersiz bir resmi vardır; son kart, diğer kart resimlerinin iki katından daha yüksek olan dikey olarak yönlendirilmiş bir resme sahiptir.
Uygulanan kart sarma düzeni stilleri nedeniyle arka arkaya üç kart gösterilir. Her kartın, farklı doğal en-boy oranlarına sahip benzersiz bir resmi vardır ve son kart, diğer kart görüntülerinin iki katından daha yüksek olan dikey olarak yönlendirilmiş bir görüntüye sahiptir. (Büyük önizleme)

Önizleme görüntüsünde gösterildiği gibi, bu temel stiller, değişen doğal boyutları göz önüne alındığında görüntüleri düzgün bir şekilde içermek için yeterli değildir. Bu görüntüleri tekdüze ve tutarlı bir şekilde sınırlamak için bir yönteme ihtiyacımız var.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

object-fit ile Tekdüzen Görüntü Boyutlarını Etkinleştir

Daha önce belirtildiği gibi, bu senaryoda eklenecek resimleri bunun yerine background-image ile değiştirmek için daha önce bir güncelleme yapmış ve resmi güzel bir şekilde yeniden boyutlandırmak için background-size: cover kullanmış olabilirsiniz. Veya önceden kırpmayı zorlamayı denemiş olabilirsiniz (herhangi bir görüntü boyutu küçültme performansı artıracağından, yine de değerli bir hedeftir!).

Şimdi, bir img etiketinin görüntü için kapsayıcı olarak hareket etmesini sağlayan object-fit özelliğine sahibiz. Ayrıca, arka plan görüntüsü çözümüne benzer bir etkiyle sonuçlanan bir cover değeriyle birlikte gelir, ancak bir satır içi görüntünün semantiğini koruma avantajıyla birlikte. Uygulayalım ve nasıl çalıştığını görelim.

Görüntü kapsayıcısının nasıl davranmasını istediğimize dair ek rehberlik için bir height boyutuyla eşleştirmemiz gerekiyor (hatırlayın, zaten width: 100% eklemiştik). Ve belirli bir bağlamda hangisinin daha büyük olduğuna bağlı olarak 10rem veya 30vh seçmek için max() işlevini kullanacağız, bu da daha küçük görünüm alanlarında veya kullanıcı büyük bir yakınlaştırma ayarladığında görüntü yüksekliğinin çok fazla küçülmesini önler.

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

Bonus Erişilebilirlik İpucu : Düzenlerinizi her zaman masaüstünde %200 ve %400 yakınlaştırma ile test etmelisiniz. Şu anda bir zoom ortamı sorgusu bulunmamakla birlikte, max() gibi işlevler, yerleşim sorunlarının çözülmesine yardımcı olabilir. Bu tekniğin yararlı olduğu başka bir bağlam, öğeler arasındaki boşluktur.

Bu güncellemeyle, kesinlikle bazı şeyleri iyileştirdik ve görsel sonuç, sanki daha eski arka plan görüntüsü tekniğini kullanıyormuşuz gibi:

Üç kartlı görüntüler artık tek tip bir yüksekliğe sahip görünüyor ve görüntü içeriği sanki bir kapsayıcıymış gibi görüntünün içinde ortalanıyor.
Üç kartlı görüntüler artık tek tip bir yüksekliğe sahip görünüyor ve görüntü içeriği sanki bir kapsayıcıymış gibi görüntünün içinde ortalanıyor. (Büyük önizleme)

En aspect-ratio ile Duyarlı Tutarlı Görüntü Boyutlandırma

object-fit tek başına kullanırken, bir dezavantajı, hala bazı boyut ipuçları ayarlamamız gerekmesidir.

En aspect-ratio adı verilen ve yakında kullanıma sunulacak bir özellik (şu anda Chromium tarayıcılarında mevcut), görüntüleri tutarlı bir şekilde boyutlandırma yeteneğimizi geliştirecek.

Bu özelliği kullanarak, açık boyutlar ayarlamak yerine görüntüyü yeniden boyutlandırmak için bir oran tanımlayabiliriz . Bu boyutların görüntüyü yalnızca kapsayıcı olarak etkilediğinden emin olmak için object-fit ile birlikte kullanmaya devam edeceğiz, aksi takdirde görüntü bozuk görünebilir.

İşte tam güncellenmiş resim kuralımız:

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

Kart bağlamımız için 43 resim oranıyla başlayacağız, ancak herhangi bir oranı seçebilirsiniz. Örneğin, bir kare için 11 veya standart video yerleştirmeleri için 169 .

Güncellenen kartlar burada, ancak en boy oranı yalnızca object-fit için height ayarlayarak elde ettiğimiz görünümle yakından eşleştiğinden, bu belirli durumda görsel farkı fark etmek muhtemelen zor olacaktır.

Üç kartlı görüntüler, önceki nesne sığdırma çözümünden biraz farklı olan aynı genişlik ve yükseklik boyutlarına sahiptir.
Üç kartlı görüntüler, önceki nesne sığdırma çözümünden biraz farklı olan aynı genişlik ve yükseklik boyutlarına sahiptir. (Büyük önizleme)

Bir "en-boy oranı" ayarlamak, elemanlar büyüdükçe veya küçüldükçe oranın korunmasıyla sonuçlanırken, yalnızca "nesne-uyum" ve "yükseklik" ayarlanırken, kap boyutları değiştikçe görüntü oranı sürekli olarak değişim içinde olacaktır.

CSS Gradyanları ve İşlevleriyle Duyarlı Efektler Ekleme

Tamam, artık tutarlı boyutlu görüntüleri nasıl kuracağımızı bildiğimize göre, şimdi bir degrade efekti ekleyerek onlarla biraz eğlenelim!

Bu efektle amacımız, görselin kart içeriğine karışıyormuş gibi görünmesini sağlamaktır. Gradyanı eklemek için görüntüyü kendi kabına sarmak isteyebilirsiniz, ancak görüntü boyutlandırma üzerinde yaptığımız çalışma sayesinde, ana .card üzerinde nasıl güvenli bir şekilde yapılacağını çözebiliriz.

İlk adım bir degrade tanımlamaktır . Degrade efektini maviden pembeye kolayca değiştirmeyi sağlamak için degrade renkleri eklemek için bir CSS özel özelliği kullanacağız. Kart içeriği arka planına geçişi korumak ve "tüylü" kenarı oluşturmak için degradedeki son renk her zaman beyaz olacaktır.

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

Ama bekleyin - bu bir CSS max() işlevi mi? Gradyan olarak mı? Evet, mümkün ve bu gradyanı duyarlı bir şekilde etkili kılan sihir!

Ancak, bir ekran görüntüsü ekleseydim, henüz görüntü üzerinde herhangi bir etkisi olan degradeyi görmezdik. Bunun için mix-blend-mode özelliğini getirmemiz gerekiyor ve bu senaryoda overlay değerini kullanacağız:

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

mix-blend-mode özelliği, Photoshop gibi fotoğraf işleme yazılımlarında bulunan katman karıştırma stillerinin uygulanmasına benzer. Ve overlay değeri, görüntüdeki orta tonların arkasındaki gradyanla karışmasını sağlayarak aşağıdaki sonuca yol açma etkisine sahip olacaktır:

Her kart görüntüsünün üstte açık mavi ile başlayan, kırmızımsı pembeye karışan ve ardından kart metni içeriğinin geri kalanından önce beyaza geçiş yumuşatmayla biten bir degrade karıştırma efekti vardır.
Her kart görüntüsünün üstte açık mavi ile başlayan, kırmızımsı pembeye karışan ve ardından kart metni içeriğinin geri kalanından önce beyaza geçiş yumuşatmayla biten bir degrade karıştırma efekti vardır. (Büyük önizleme)

Şimdi, bu noktada, resmi yeniden boyutlandırmak için yalnızca en aspect-ratio değerine güveniyoruz. Ve kabı yeniden boyutlandırırsak ve kart düzeninin yeniden akmasına neden olursak, değişen görüntü yüksekliği, degradenin beyaza dönüştüğü yerlerde tutarsızlıklara neden olur.

Bu nedenle, max() işlevini de kullanan ve degradedeki değerlerden biraz daha büyük değerler içeren bir max-height özelliği ekleyeceğiz. Ortaya çıkan davranış, degradenin (neredeyse her zaman) görüntünün alt kısmıyla doğru bir şekilde hizalanmasıdır.

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

Bir "maksimum yükseklik" eklemenin "en-boy oranı" davranışını değiştirdiğine dikkat etmek önemlidir. Her zaman tam oranı kullanmak yerine, yalnızca "max-height"ın yeni ekstra kısıtlaması göz önüne alındığında yeterli ayrılan alan olduğunda kullanılacaktır.

Bununla birlikte, aspect-ratio , yalnızca object-fit göre avantajı olduğu gibi, görüntülerin tutarlı bir şekilde yeniden boyutlandırılmasını sağlamaya devam edecektir. Kapsayıcı boyutları arasında yarattığı farkı görmek için son CodePen demosunda en aspect-ratio yorumlamayı deneyin.

Asıl hedefimiz, tutarlı bir şekilde yanıt veren resim boyutlarını etkinleştirmek olduğundan, yine de hedefi tuttuk. Kendi kullanım durumunuz için, istediğiniz efekti elde etmek için oran ve yükseklik değerleriyle oynamanız gerekebilir.

Alternatif: mix-blend-mode ve Filtre Ekleme

mix-blend-mode değeri olarak overlay kullanmak, aradığımız soldurmadan beyaza efekti için en iyi seçimdi, ancak daha dramatik bir efekt için alternatif bir seçenek deneyelim.

mix-blend-mode değeri için bir CSS özel özelliği eklemek için çözümümüzü güncelleyeceğiz ve ayrıca degrade için renk değerlerini güncelleyeceğiz:

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

multiply değerinin orta tonlarda koyulaştırıcı bir etkisi vardır, ancak beyaz ve siyahı olduğu gibi tutar ve aşağıdaki görünümle sonuçlanır:

Her kart görüntüsü, kırmızı-turuncudan saf turuncuya doğru başlayan yeni degradeden güçlü bir turuncu renk tonuna sahiptir. Beyaz alanlar hala beyaz ve siyah alanlar hala siyah
Her kart görüntüsü, kırmızı-turuncudan saf turuncuya doğru başlayan yeni degradeden güçlü bir turuncu renk tonuna sahiptir. Beyaz alanlar hala beyaz ve siyah alanlar hala siyah. (Büyük önizleme)

Solmayı kaybetmiş olsak ve artık görüntünün alt kısmında sert bir kenar olsa da, degrademizin beyaz kısmı, degradenin kart içeriğinden önce bitmesini sağlamak için hala önemlidir.

Ekleyebileceğimiz ek bir değişiklik , filter kullanımı ve özellikle görüntü renklerini kaldırmak için grayscale() işlevini kullanmak ve bu nedenle degradenin görüntü renklendirmesinin tek kaynağı olmasını sağlamaktır.

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

grayscale(100) değerinin kullanılması, görüntünün doğal renklerinin tamamen kaldırılması ve siyah beyaza dönüştürülmesiyle sonuçlanır. multiply ile turuncu gradyanımızı kullanırken etkisinin önceki ekran görüntüsüyle karşılaştırma için güncelleme:

Artık her kart resminde hala turuncu gradyan var, ancak diğer tüm renkler kaldırılıyor ve gri tonları ile değiştiriliyor
Artık her kart resminde hala turuncu gradyan var, ancak diğer tüm renkler kaldırılıyor ve gri tonları ile değiştiriliyor. (Büyük önizleme)

En aspect-ratio Aşamalı Geliştirme Olarak Kullanın

Daha önce belirtildiği gibi, şu anda aspect-ratio yalnızca Chromium tarayıcılarının (Chrome ve Edge) en son sürümlerinde desteklenmektedir. Ancak, tüm tarayıcılar object-fit destekler ve bu, height kısıtlamalarımızla birlikte daha az ideal ancak yine de kabul edilebilir bir sonuç verir, burada Safari için görülmektedir:

Kart görüntüsünün yüksekliği sınırlıdır, ancak her kartın fark edilen yüksekliği biraz farklıdır
Kart görüntüsünün yüksekliği sınırlıdır, ancak her kartın fark edilen yüksekliği biraz farklıdır. (Büyük önizleme)

En aspect-ratio işlevi olmadan, buradaki sonuç, sonuçta görüntü yüksekliğinin sınırlandırılmasıdır, ancak her görüntünün doğal boyutları yine de kart görüntü yükseklikleri arasında bazı farklılıklara yol açar. Bunun yerine, bir max-height eklemeye geçmek veya max-height farklı kart boyutlarında daha duyarlı hale getirmeye yardımcı olmak için max() işlevini tekrar kullanmak isteyebilirsiniz.

Gradyan Efektlerini Genişletme

Degrade renk duraklarını bir CSS özel özelliği olarak tanımladığımızdan, bunları farklı bağlamlar altında değiştirmek için hazır erişimimiz var. Örneğin, kart üzerine gelindiğinde veya odakta çocuklarından biri varsa, degradeyi renklerden birini daha güçlü gösterecek şekilde değiştirebiliriz.

İlk olarak, her bir h3 kartını aşağıdaki gibi bir bağlantı içerecek şekilde güncelleyeceğiz:

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

Ardından, bağlantı odaktayken kart gradyanını değiştirmek için mevcut en yeni seçicilerimizden birini — :focus-within — kullanabiliriz. Olası etkileşimlerin daha fazla kapsamı için bunu :hover ile birleştireceğiz. Ve, kartın görüntü bölümünün kapsamını devralmak için tek bir renk atamak için max() fikrimizi yeniden kullanacağız. Bu özel efektin dezavantajı, gradyan durmalarının ve renk değişikliklerinin güvenilir bir şekilde canlandırılabilir olmamasıdır - ancak bunlar yakında CSS Houdini sayesinde olacaktır.

Rengi güncellemek ve yeni renk durağını eklemek için, bu yeni kuralda --card-gradient değerini yeniden atamamız yeterli:

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

max() değerlerimiz, geçiş yumuşatılmış kenarı korumak için white için kullanılan orijinal değerden daha düşüktür. Aynı değerleri kullanırsak, white buluşacak ve net bir düz kenar ayrımı oluşturacaktır.

Bu demoyu oluştururken, başlangıçta yakınlaştırma efekti için scale transform kullanan bir efekt denedim. Ancak, uygulanan mix-blend-mode nedeniyle, tarayıcının görüntüyü sürekli olarak yeniden boyamayacağını ve bunun da hoş olmayan bir titremeye neden olduğunu keşfettim. Tarayıcıdan yalnızca CSS'ye özgü efektler ve animasyonlar gerçekleştirmesini talep ederken her zaman ödünleşimler olacaktır ve yapabileceklerimiz çok havalı olsa da, efektlerinizin performans etkisini kontrol etmek her zaman en iyisidir.

Deneyerek İyi Eğlenceler!

Modern CSS, web tasarım araç takımlarımızı güncellemek için bize harika araçlar verdi, en son eklenen aspect-ratio . Öyleyse devam edin ve bazı eğlenceli duyarlı efektler için object-fit , aspect-ratio ve degradelerinize max() gibi işlevler ekleyerek denemeler yapın! Her şeyi tarayıcılar arası (şimdilik!) ve değişen görünüm alanları ve kapsayıcı boyutları arasında iki kez kontrol ettiğinizden emin olun.

İşte bugün incelediğimiz özellikleri ve efektleri içeren CodePen:

Stephanie Eckles'ın Kalem [CSS Gradyanları ve en boy oranı ile Duyarlı Görüntü Efektleri](https://codepen.io/smashingmag/pen/WNoERXo) konusuna bakın.

Stephanie Eckles'ın CSS Gradyanları ve en boy oranı ile Kaleme Duyarlı Görüntü Efektlerine bakın.

Daha fazlasını mı arıyorsunuz? Smashing ile ilgili CSS Kılavuzumuzu kontrol ettiğinizden emin olun →