CSS Izgarası ile Zor Bir Mizanpaj Problemini Çözme

Faydalı Alternatif Metin Yazma

Geçen yıl çalışırken Çamuriçin bir sitede CSS üzerinde çalıştım. Warner Brothers Leavesden Park stüdyoları. Katkımın büyük bir kısmı, çeşitli bileşen düzenleri oluşturmak için CSS Izgarası kullanmayı içeriyordu ve bu site için oluşturduğum düzenler, bazı konuşmalarıma ve makalelerime konu oldu.

Bu makale, benzersiz bir düzene ve bir dizi kısıtlamaya sahip belirli bir bileşen üzerine bir vaka çalışmasıdır. Bilinmeyen içeriğin yanı sıra çok sayıda gereksinim için çalışan bir düzen oluşturmak, doğru çözümü bulmak için yanal düşünmeyi ve çok fazla problem çözmeyi gerektiriyordu.

Böyle bir bileşen şöyle görünür:

Bir resim veya video, hem yatay hem de dikey olarak ortalanmış büyük bir başlık ve bir metin bloğundan oluşur. Bu durumda metin bloğu görüntünün üstüne hizalanır, ancak içerik yazarı tarafından seçilirse görüntünün altına eşit olarak hizalanabilir.

Çok zahmetli değil, düşünebilirsiniz ve modern yerleşim yöntemleriyle yeterince basit olmalıdır. Ancak bu bileşen bir dizi kısıtlamayla birlikte gelir:

  • Başlık, bileşen içinde yatay olarak ortalanmalı ve görüntü üzerinde dikey olarak ortalanmalıdır.
  • Metin bloğu görüntünün üstüne veya altına hizalanmalıdır, meğer ki metin kullanılabilir alandan daha uzundur, bu durumda yukarıya (veya alta hizalanmışsa aşağı doğru) uzanmalıdır.
  • Görüntü boyutları bilinmiyor ve bir en-boy oranıyla sınırlandırılmamış – başka bir deyişle, içerik yazarları, kırpılmalarına neden olmadan herhangi bir boyuttaki görüntüleri yükleyebilir.
  • Başlığın ve metin bloğunun uzunluğu da bilinmemektedir.

Tasarımın kendisi 24 sütunlu bir ızgaradan ve bileşenin birden fazla varyantından oluşuyordu – burada görüntü ve metin bloğu çeşitli farklı ızgara sütunlarına hizalanabiliyordu. Bu makalenin amacı doğrultusunda şimdilik sütun eksenine odaklanmayacağız, çünkü buradaki birincil odak ızgara öğelerinin satır ekseninde hizalanmasıdır.

Her öğe için sınırlayıcı kutuyu daha kolay görmemizi sağlayan aynı bileşenin basitleştirilmiş bir görünümünü oluşturdum. (Pembe dış çizginin bileşenin sınırlayıcı kutusu olduğunu hayal edin.)

Bileşen düzeninin basitleştirilmiş gösterimi

Izgara kabı ve doğrudan çocuklar (ızgara öğelerimiz) için aşağıdaki işaretlemeyi varsayalım – bu makalenin amacı doğrultusunda bu öğelerin içindeki her şeyi yok sayacağız, böylece sadece düzene odaklanabiliriz:

<article class="grid">
<div class="grid__heading">Heading</div>
<figure class="grid__image"></figure>
<div class="grid__text"></div>
</article>

Izgaramızı tanımlamak ve öğeleri sütun eksenine yerleştirmek için aşağıdaki CSS’ye sahibiz:

.grid {
display: grid;
grid-template-columns: minmax(0, 1fr) repeat(24, minmax(0, 60px)) minmax(0, 1fr);
column-gap: 20px;
}

.grid__heading {
/* Using a negative line for the grid-column-end value allows us to easily center the position of the heading when we have a large grid */
grid-column: 5 / -5;
}

.grid__image {
grid-column: 2 / 16;
}

.grid__text {
grid-column: span 5 / -1;
}

için kullandığımız değerleri merak ediyorsanız grid-template-columns malım, sahibim burada bir açıklama.

Şimdi grid satırlarımızı tanımlamamız gerekiyor. İlk düşüncem şuydu: grid-template-rows mülk aşağıdaki gibidir:

.grid {
grid-template-rows: 1fr auto 1fr;
}

Bu bize değeri olan bir merkezi satır verir. auto başlığımız için (bunun ne kadar süreceğini bilmediğimiz ve parçanın içeriğe uyacak şekilde büyümesini istediğimiz için) ve çevreleyen iki satır 1fr. Bu iki dış sıra, mevcut alanın eşit bir oranını alacaktır. eğer ayarlarsak row-gap: 40px (kısa yolu kullanarak gap burada grid-row-gap ve grid-column-gap) sonra başlık ile metin bloğu arasındaki boşluğu korumak için başlığın üstünde ve altında 40 piksellik bir oluk alırız.

Satır izlerinin vurgulandığı bileşen

Burada gerçekten yararlı olacak olan Grid ile esnek hizalama özelliklerini de kullanabiliriz. kullanıyorum align-items: center ızgara öğelerimizi yatay olarak ortalamak için. Bunu neden yapmamız gerektiği henüz belli değil, ancak metin içeriğimiz mevcut alandan daha uzunsa bunun daha kullanışlı hale geldiğini yakında göreceğiz.

.grid {
/* ...Other grid code */
grid-template-rows: 1fr auto 1fr;
gap: 40px 20px;
align-items: center;
}

Artık grid öğelerini satır eksenine yerleştirebiliriz:

.grid__heading {
grid-row: 2;
}

.grid__image {
/* From the start of the grid to the end */
grid-row: 1 / -1;
}

.grid__text {
grid-row: 1;
}

Tüm öğelerimiz şu anda ızgara kutularında merkezi olarak hizalanmıştır, ancak kullanırsam align-self: flex-start metin bloğunda, başlık ve görüntü merkezi olarak hizalanırken (nedeniyle) bu öğe bileşenin üstüne hizalanacaktır. align-items: centerkılavuzun kendisinde belirttiğimiz).

.grid__text {
grid-row: 1;
align-self: flex-start;
}

Çok uzak çok iyi. Görünüşe göre bu düzeni çiviledik. Tek bir sorun var: Metin bloğu, başlık ve görüntünün üst kısmı arasındaki boşluktan daha uzun olduğunda, bileşen onu yerleştirmek için genişler, görüntüyü iter ve aşağı doğru yönelir (istediğimiz şey budur) – ama ne yazık ki alt kısmı ızgara da genişler ve bize görüntünün altında fazladan boşluk verir:

Kılavuzun altında oluşturulan fazladan boşluk gösteriliyor

Üst üste yığılmış birkaç bileşenimiz varsa, aralarındaki dikey boşluk eşit olmayacaktır. Bu ideal değil. İstediğimiz, bileşenin altta değil üstte (metin bloğumuzun yanında) dikey olarak büyümesidir.

Üst sıranın yüksekliği ile aynı ızgara sadece arttı
Fikir çözümü: üst sıra iz boyutu artar, ancak alt sıra olmaz

Bunu düzeltmek için yaratıcı düşünmek zorunda kaldım! Çözümü adım adım inceleyelim.

Her şeyden önce, üç satırlık iz boyutunu şu şekilde değiştireceğiz: auto:

.grid {
grid-template-rows: auto auto auto;
gap: 40px 20px;
align-items: center;
}

Ardından, mevcut satırlarımızın üzerine yüksekliği olan fazladan bir satır ekleyebiliriz. 1fr. kullanarak ne olacağı belki de o kadar açık değildir. fr satır eksenindeki birim. Sütun ekseninde, ızgaramızın genişliğini biliyoruz (varsayılan olarak %100 olacaktır), bu nedenle bir sütun izini hayal etmek kolaydır. 1fr bu boşluğun bir kısmını doldurur. Sıra ekseni söz konusu olduğunda, bu durumda ızgaramızın yüksekliği, şu anda ilk ızgara satırından son ızgara çizgisine kadar yerleştirilmiş olan en uzun ızgara öğesinin – resmin – yüksekliğine göre belirlenecektir.

.grid {
grid-template-rows: 1fr auto auto auto;
gap: 40px 20px;
align-items: center;
}

Eklediğimiz satır aslında gizli bir satırdır – şuraya daralacaktır: 0 içine içerik yerleştirmediğimiz sürece.

Kılavuzun üst kısmındaki gizli satır

Öğe yerleşimine bakmadan önce ızgara kapsayıcımıza yapmamız gereken birkaç şey daha var. biz ayarlayacağız row-gap 0’a getirin ve başlık satırı ile bitişik satırları arasına 40 piksellik parçalar ekleyin. Biz de kaldırabiliriz align-items: centerçünkü artık ihtiyacımız olmayacak.

.grid {
grid-template-rows: 1fr auto 40px auto 40px auto;
gap: 0 20px;
}

Artık ızgaramızın altı satırı olduğu için, ızgara öğelerimizi satır ekseninde nereye yerleştireceğimizi görselleştirmek o kadar kolay değil. İzlenmesi gereken daha çok ızgara çizgisi var! Izgara hatlarımızı adlandırmak burada çok yardımcı olacaktır. Ardından, ızgara öğelerimizi yerleştirmek için bu satır adlarına başvurabiliriz.

.grid {
grid-template-rows:
[text-start] 1fr [image-start] auto [text-end] 40px [heading-start] auto [heading-end] 40px
auto [image-end];
gap: 0 20px;
}

.grid__heading {
grid-row: heading;
}

.grid__image {
grid-row: image;
}

.grid__text {
grid-row: text;
align-self: flex-start;
}

Kartal gözlü okuyucular, metin bloğumuzun artık iki parçaya yayıldığını (1 ızgara satırından başlayarak) ve görüntümüzün artık ızgara satırı 1’de değil, bunun yerine satır 2’de başladığını fark edebilir. Ancak görsel olarak değişen bir şey yok.

Metin bloğuna daha uzun bir metin paragrafı eklediğimizde, bu değişikliklerin faydasını görebiliriz. Eklediğimiz gizli satır genişlerken, resim ve başlık birbiriyle merkezi olarak hizalı kalırken – en önemlisi, olmadan ızgaranın altına ek alan ekleniyor!

Metin bloğu daha uzun olduğunda gizli satır genişliyor
Metin içeriği uzadıkça kılavuzun üst satırı genişler

Umarım şimdi neden ayarlamamız gerektiği daha açıktır. row-gap 0’a getirin ve bunun yerine oluklarımız olarak fazladan izler kullanın: eğer 40 pikselimiz olsaydı row-gap, bu, metin içeriği daha kısa olduğunda ve bu nedenle ilk parça tamamen çöktüğünde bile ızgaranın en üstünde görünür olacaktı. Maalesef farklı değerler ayarlayamıyoruz. gap özellikler tek bir eksende, aksi takdirde bu ekstra satırlara ihtiyacımız olmazdı.

Farklı bir bileşen varyantı için – metin bloğunun üst yerine başlığın altında olduğu durumlarda – sadece grid-template-rows başlangıç ​​yerine gizli satırı ve bitişi dahil etme özelliği.

.grid--text-bottom {
grid-template-rows:
[media-start] auto 40px
[heading-start] auto [heading-end] 40px [text-start] auto [media-end] 1fr [text-end];
gap: 0 20px;
}

İşte tam demo:

Kalemi Gör CSS Izgara Karmaşık Bileşeni Michelle Barker tarafından (@michellebarker) üzerinde kod kalemi.

Bu çözüm aslında üretimde uygulanmadı – bunu ancak çok sonra anladım! Yaygın bir yerleşim sorunu olmamasına rağmen, umarım bu, Grid ile olağandışı düzenler oluşturmak için kullanılabilecek bazı hileleri ve yöntemleri gösterir.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.