CSS Gradyanları ve en boy oranı ile Duyarlı Görüntü Efektleri Oluşturun
Yayınlanan: 2022-03-10aspect-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:
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:
Ö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.
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:
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 4 ⁄ 3 resim oranıyla başlayacağız, ancak herhangi bir oranı seçebilirsiniz. Örneğin, bir kare için 1 ⁄ 1 veya standart video yerleştirmeleri için 16 ⁄ 9 .
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.
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:
Ş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:
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:
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:
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:
Daha fazlasını mı arıyorsunuz? Smashing ile ilgili CSS Kılavuzumuzu kontrol ettiğinizden emin olun →