Zephyrnet Logosu

Avatarınız İçin Süslü Bir Vurgulu Efekti

Tarih:

Birinin kafasının bir daire veya delikten dışarı çıkması gibi bir etkiyi biliyor musunuz? Bir dizi kırmızı halkadan fırlayarak veda ederken el salladığı ünlü Porky Pig animasyonu mükemmel bir örnektir ve Kilian Valkhof bunu bir süre önce CSS-Tricks'te yeniden yarattı..

Benzer bir fikrim var ama farklı bir şekilde ve biraz animasyonla uğraştım. Bence oldukça pratik ve kendi avatarınız gibi bir şey üzerinde kullanabileceğiniz düzgün bir gezinme efekti sağlıyor.

Bunu gördün mü? Avatarın içinde bulunduğu çemberin dışına çıktığı bir ölçeklendirme animasyonu yapacağız. Harika, değil mi? Koda bakmayın ve bu animasyonu birlikte adım adım oluşturalım.

HTML: Yalnızca bir öğe

Demo kodunu kontrol etmediyseniz ve kaç tane olduğunu merak ediyorsanız divBu sürecek, sonra burada duracağız, çünkü işaretlememiz tek bir resim öğesinden başka bir şey değil:

<img src="" alt="">

Evet, tek bir element! Bu alıştırmanın zorlu kısmı, mümkün olan en az miktarda kod kullanmaktır. Eğer olduysan beni takip ediyor bir süreliğine buna alışmalısın. Mümkün olan en küçük, bakımı en kolay kodla elde edilebilecek CSS çözümleri bulmak için çok çabalıyorum.

Yazdığım bir dizi makale burada, tek bir öğe içeren aynı HTML işaretlemesini kullanarak farklı vurgulu efektleri keşfettiğim CSS-Tricks'te. Degradeler, maskeleme, kırpma, ana hatlar ve hatta mizanpaj teknikleriyle ilgili ayrıntılara giriyorum. Bunları kontrol etmenizi şiddetle tavsiye ederim çünkü bu gönderideki birçok numarayı tekrar kullanacağım.

Saydam bir arka plana sahip kare bir görüntü dosyası, yaptığımız iş için en iyi sonucu verecektir. Bununla başlamak istersen, kullandığım şey burada.

Tasarımcı cang

Bunun mümkün olduğunca çok örneğini gerçek görseller kullanarak görmeyi umuyorum — bu nedenle, bir koleksiyon oluşturabilmemiz için işiniz bittiğinde lütfen nihai sonucunuzu yorumlarda paylaşın!

CSS'ye geçmeden önce, önce efekti inceleyelim. Fareyle üzerine gelindiğinde görüntü büyüyor, bu yüzden kesinlikle kullanacağız transform: scale() Orada. Avatarın arkasında bir daire var ve radyal bir gradyan işinizi görecektir. Son olarak, dairenin arkasında avatarın görünümünü oluşturan dairenin altında bir kenarlık oluşturmanın bir yoluna ihtiyacımız var.

Hadi çalışalım!

ölçek etkisi

Dönüşümü ekleyerek başlayalım:

img { width: 280px; aspect-ratio: 1; cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

Henüz karmaşık bir şey yok, değil mi? Hadi devam edelim.

Daire

Arka planın radyal bir gradyan olacağını söylemiştik. Bu mükemmel, çünkü radyal bir degradenin renkleri arasında katı çizgilerle bir daire çiziyormuşuz gibi görünmesini sağlayan sert duraklar oluşturabiliriz.

img { --b: 5px; /* border width */ width: 280px; aspect-ratio: 1; background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, #0000 ); cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

CSS değişkenine dikkat edin, --b, orada kullanıyorum. Radyal degradenin kırmızı kısmı için sert renk duraklarını tanımlamak için gerçekten sadece kullanılan "kenarlığın" kalınlığını temsil eder.

Bir sonraki adım, fareyle üzerine gelindiğinde degrade boyutuyla oynamaktır. Görüntü büyüdükçe dairenin boyutunu koruması gerekir. uyguladığımız için scale() dönüşüm, aslında ihtiyacımız var azaltmak aksi halde avatarla birlikte ölçeklendiği için dairenin boyutu. Bu nedenle, görüntü ölçeklenirken, küçültmek için degradeye ihtiyacımız var.

Bir CSS değişkeni tanımlayarak başlayalım, --f, "ölçek faktörü"nü tanımlar ve bunu dairenin boyutunu ayarlamak için kullanır. kullanıyorum 1 varsayılan değer olarak, çünkü bu görüntü ve dönüştürdüğümüz daire için ilk ölçektir.

İşte hileyi göstermek için bir demo. Perde arkasında neler olduğunu görmek için üzerine gelin:

Üçüncü bir renk ekledim. radial-gradient üzerine gelindiğinde degradenin alanını daha iyi belirlemek için:

radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, lightblue
);

Şimdi arka planımızı dairenin merkezine yerleştirmeli ve tüm yüksekliği kapladığından emin olmalıyız. Her şeyi doğrudan web sitesinde beyan etmeyi seviyorum background steno özelliği, böylece arka plan konumumuzu ekleyebilir ve bu değerlerin hemen ardından işaretleyerek tekrarlanmadığından emin olabiliriz. radial-gradient():

background: radial-gradient() 50% / calc(100% / var(--f)) 100% no-repeat;

Arka plan merkeze yerleştirilir (50%), eşit bir genişliğe sahiptir calc(100%/var(--f))ve eşit bir yüksekliğe sahip 100%.

Hiçbir şey ölçeklenmez --f eşittir 1 - yine, ilk ölçeğimiz. Bu sırada gradyan, kabın tüm genişliğini kaplar. Arttırdığımızda --f, öğenin boyutu büyür — sayesinde scale() transform — ve degradenin boyutu küçülür.

İşte tüm bunları demomuza uyguladığımızda elde ettiğimiz şey:

Yaklaşıyoruz! Üstte taşma efekti var, ancak yine de görüntünün alt kısmını gizlememiz gerekiyor, böylece dairenin önünde oturmak yerine dairenin dışına fırlıyormuş gibi görünüyor. Tüm bu işin zor kısmı bu ve bundan sonra yapacağımız şey de bu.

alt kenarlık

İlk önce bununla başa çıkmaya çalıştım border-bottom özelliği, ancak kenarlığın boyutunu dairenin boyutuna uydurmanın bir yolunu bulamadım. İşte alabildiğim en iyi şey ve bunun yanlış olduğunu hemen görebilirsiniz:

Asıl çözüm, kullanmaktır. outline mülk. Evet, outline, değil border. içinde önceki bir makale, nasıl olduğunu gösteriyorum outline güçlüdür ve harika vurgulu efektler oluşturmamıza izin verir. İle kombine outline-offset, etkimiz için tam olarak ihtiyacımız olan şeye sahibiz.

Fikir bir ayarlamaktır outline ve alt kenarlığı oluşturmak için ofsetini ayarlayın. Ofset, gradyan boyutunun yaptığı gibi ölçeklendirme faktörüne bağlı olacaktır.

Şimdi alt “sınırımıza” sahibiz (aslında bir outline) tam bir daire oluşturmak için degrade tarafından oluşturulan "kenarlık" ile birleştirilir. Hala bazı kısımlarını saklamamız gerekiyor. outline (üstten ve yanlardan), birazdan ele alacağız.

Görüntü boyutunu (--s) ve "kenarlık" rengi (--c):

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50% / calc(100% / var(--f)) 100% no-repeat; transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

Dairesel bir alt bordüre ihtiyacımız olduğu için, border-radius alt tarafta, outline eğimin eğriliğiyle eşleşmesi için.

Kullanılan hesaplama outline-offset göründüğünden çok daha basittir. Varsayılan olarak, outline çizilmiş dışında öğesinin kutusundan. Ve bizim durumumuzda, buna ihtiyacımız var üst üste gelmek eleman Daha doğrusu degradenin oluşturduğu daireyi takip etmesi gerekiyor.

Arka plan geçişinin diyagramı.

Öğeyi ölçeklendirdiğimizde daire ile kenar arasındaki boşluğu görüyoruz. Unutmayalım ki fikir, ölçek dönüşümü çalıştırıldıktan sonra daireyi aynı boyutta tutmaktır, bu da bize yukarıdaki şekilde gösterildiği gibi ana hattın ofsetini tanımlamak için kullanacağımız alanı bırakır.

İkinci öğenin ölçeklendiğini unutmayalım, bu nedenle sonucumuz da ölçeklendi… yani sonucu şuna bölmemiz gerekiyor: f gerçek ofset değerini elde etmek için:

Offset = ((f - 1) * S/2) / f = (1 - 1/f) * S/2

Dıştan içe doğru gitmek için taslağa ihtiyacımız olduğu için eksi işareti ekliyoruz:

Offset = (1/f - 1) * S/2

Ana hatların gradyanı nasıl takip ettiğini gösteren hızlı bir demo:

Zaten görmüş olabilirsiniz, ancak yine de alt taslağın dairenin içinden akmasına izin vermek yerine üst üste binmesine ihtiyacımız var. Bunu kenarlığın boyutunu ofsetten kaldırarak yapabiliriz:

outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2) - var(--b));

Şimdi üst kısmı anahattan nasıl çıkaracağımızı bulmamız gerekiyor. Başka bir deyişle, görüntünün yalnızca alt kısmını istiyoruz. outline.

İlk olarak, üstte çakışmayı önlemek için üstte boşluk ekleyelim:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; padding-block-start: calc(var(--s)/5); /* etc. */
}
img:hover { --f: 1.35; /* hover scale */
}

Bu üst dolgu için özel bir mantık yoktur. Fikir, taslağın avatarın kafasına değmemesini sağlamaktır. Her zaman aynı orana sahip olacak şekilde bu alanı tanımlamak için öğenin boyutunu kullandım.

Eklediğime dikkat edin content-box değer background:

background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50%/calc(100%/var(--f)) 100% no-repeat content-box;

Buna ihtiyacımız var çünkü dolgu ekledik ve arka planın içerik kutusuna ayarlanmasını istiyoruz, bu nedenle arka plana burada durmasını açıkça söylemeliyiz.

Karışıma CSS maskesi ekleme

Son bölüme geldik! Tek yapmamız gereken bazı parçaları saklamak ve işimiz bitti. Bunun için güveneceğimiz mask özellik ve tabii ki degradeler.

İşte neyi saklamamız gerektiğini veya daha doğru olması için neyi göstermemiz gerektiğini gösteren bir şekil.

Maskenin dairenin alt kısmına nasıl uygulandığı gösteriliyor.

Soldaki resim şu anda sahip olduğumuz, sağdaki ise istediğimiz şey. Yeşil kısım, nihai sonucu elde etmek için orijinal görüntüye uygulamamız gereken maskeyi göstermektedir.

Maskemizin iki bölümünü tanımlayabiliriz:

  • Altta, avatarın arkasındaki daireyi oluşturmak için kullandığımız radyal degradeyle aynı boyuta ve eğriliğe sahip dairesel bir kısım
  • Ana hattın içindeki alanı kaplayan üstte bir dikdörtgen. Ana hattın üst kısımdaki yeşil alanın dışında nasıl olduğuna dikkat edin - bu en önemli kısımdır, çünkü ana hattın yalnızca alt kısım görünecek şekilde kesilmesine izin verir.

İşte son CSS'miz:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ --_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; --_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); width: var(--s); aspect-ratio: 1; padding-top: calc(var(--s)/5); cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: var(--_o); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000) var(--_g); mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g); transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

Hadi bunu parçalayalım mask mülk. Yeni başlayanlar için, benzer bir radial-gradient() itibaren background mülkiyet orada. Yeni bir değişken oluşturdum, --_g, ortak parçaların işleri daha az karmaşık hale getirmesi için.

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

Sırada bir linear-gradient() orada da:

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

Bu, maskenin dikdörtgen kısmını oluşturur. Genişliği, radyal degradenin genişliğinden kenarlık kalınlığının iki katına eşittir:

calc(100% / var(--f) - 2 * var(--b))

Dikdörtgenin yüksekliği yarıya eşittir, 50%, öğenin boyutundan.

Ayrıca yatay merkeze yerleştirilmiş doğrusal gradyana da ihtiyacımız var (50%) ve üstten, ana hattın ofseti ile aynı değerde ofset. Başka bir CSS değişkeni oluşturdum, --_o, önceden tanımladığımız ofset için:

--_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b));

Buradaki kafa karıştırıcı şeylerden biri, bir negatif anahat için ofset (dışarıdan içeriye taşımak için) ancak pozitif degrade için ofset (yukarıdan aşağıya hareket etmek için). Ofseti neden çarptığımızı merak ediyorsanız, --_oIle, -1, Eh, artık şimdi biliyorsun!

İşte maskenin gradyan konfigürasyonunu gösteren bir demo:

Yukarıya gelin ve her şeyin birlikte nasıl hareket ettiğini görün. Ortadaki kutu, iki degradeden oluşan maske katmanını gösterir. Bunu sol görüntünün görünen kısmı olarak hayal edin ve sağdaki nihai sonucu elde edin!

Tamamlayan

Oof, işimiz bitti! Ve sadece kaygan bir fareyle üzerine gelme animasyonu elde etmekle kalmadık, aynı zamanda hepsini tek bir HTML ile yaptık. <img> eleman. Sadece bu kadar ve 20 satırdan az CSS hilesi!

Elbette, böylesine karmaşık bir etkiye ulaşmak için bazı küçük numaralara ve matematik formüllerine güvendik. Ancak ihtiyacımız olan parçaları önceden belirlediğimiz için tam olarak ne yapacağımızı biliyorduk.

Kendimize daha fazla HTML'ye izin verseydik, CSS'yi basitleştirebilir miydik? Kesinlikle. Ama yeni CSS hileleri öğrenmek için buradayız! Bu, CSS gradyanlarını, maskelemeyi, outline özelliğin davranışı, dönüşümleri ve bir sürü daha fazlası. Herhangi bir noktada kaybolmuş hissettiyseniz, kesinlikle kontrol edin benim dizim aynı genel kavramları kullanan. Bazen daha fazla örnek görmek ve bir noktayı eve götürmek için vakaları kullanmak yardımcı olur.

Sizi popüler CSS geliştiricilerinin fotoğraflarını kullanan son bir demo ile baş başa bırakacağım. Koleksiyona ekleyebilmem için bana kendi görselinle bir demo göstermeyi unutma!

spot_img

En Son İstihbarat

spot_img

Bizimle sohbet

Merhaba! Size nasıl yardım edebilirim?