Flexbox ve Sass Grid Eğitimi: Duyarlı Tasarım Nasıl Kolaylaştırılır
Yayınlanan: 2022-03-11Son zamanlarda, kendi ızgara sistemimi yaratmam istendi ve tekerleği yeniden icat etmek her zaman bir öğrenme deneyimi olarak faydalı olduğundan, bunun için gittim. İlginç bir meydan okuma olacağını biliyordum, ama ne kadar kolay olduğu beni şaşırttı!
Bu deneyde, Flexbox mizanpajlarını ve bunların herhangi bir çılgın hile yapmadan mizanpajların zarif uygulamalarına nasıl izin verdiğini inceleyeceğiz. Ayrıca, Sass'a aşina değilseniz, nasıl çalıştığını göreceğiz ve bazı kullanışlı Sass yardımcı programlarını kullanacağız. Bootstrap'ın parçası olan gibi CSS ızgaraları hakkında yeni bir şeyler bile öğrenebilirsiniz.
Sass ve Flexbox'a Çok Kısa Bir Giriş
Sass, temel olarak CSS'nin bazı eksikliklerinden kaçınmanıza izin veren bir araçtır, CSS'ye yorumlanan bir betik dilidir. Halihazırda CSS stilleri yazıyorsanız, sözdizimi çok tanıdık gelir, ancak araç kutusu değişkenler, yeniden kullanılabilirlik için karışımlar ve diğerleri arasında if, for her ve while yönergeleri içerir. Sass ile ilgili en kullanışlı şeylerden biri, geçerli herhangi bir CSS kodunun geçerli Sass olmasıdır, böylece kod tabanınızı aşamalı olarak dönüştürebilirsiniz.
Basit bir for döngüsü örneği:
@for $i from 1 through 3 { .a-numbered-class-#{$i} { width: (20 * $i) * 1px; } }
Bu basit döngü 1'den 3'e kadar yinelenir ve sınıflar oluşturur. Yinelemenin dizini kolayca $i
içinde saklanacaktır. Ayrıca matematik yapabilir ve .a-numbered-class-X
her seferinde farklı genişlikte üç kez yazdırabiliriz. Bu kod çıktıları:
.a-numbered-class-1 { width: 20px; } .a-numbered-class-2 { width: 40px; } .a-numbered-class-3 { width: 60px; }
Gördüğümüz gibi CSS'de yapmanız gereken birçok işi soyutlayabiliyoruz. CSS'de, manuel olarak kopyalayıp yapıştırmanız ve değiştirmeniz gerekir, bu açıkça hataya daha açık ve daha az zariftir, Henüz denemediyseniz, daha fazla zaman kaybetmeyin!
Flexbox, öğeleri dinamik olarak konumlandıran ve dağıtan bir CSS3 yerleşim sistemi olan Esnek Kutu anlamına gelir. Minimum çabayla esnek düzenlere izin veren çok güçlü bir araçtır. Flexbox'ın nasıl öğrenileceği hakkında daha fazla ayrıntı için Chris Coyier'in Flexbox için Tam Kılavuzuna bakın.
Izgara
Izgaranın kendisine geçerek, temel unsurlarıyla başlayalım. Bootstrap'in ızgara öğelerinden ilham alacaklar: Her biri bir öncekinin içinde bulunan Kapsayıcılar, Sıralar ve Sütunlar.
Sınıfların adları için BEM adlandırma kurallarını kullanacağız. BEM kurallarının kullanımı oldukça basittir ve öğe ve bağlamı hakkında birçok bilgi ekler. Kısaca, sahip olduğunuz:
- “Kendi başına anlamlı olan bağımsız bir varlığı kapsülleyen” bloklar :
.block
. - Bir blok adı, iki alt çizgi ve öğe ile gösterilen "bir bloğun parçaları olan ve bağımsız bir anlamı olmayan" öğeler :
.block__elem
- İki tire ile temsil edilen "Bloklardaki veya öğelerdeki bayraklar" gibi değiştiriciler: .block
.block .block--mod
.
Konteynerler
Bu, ızgaranın en dıştaki öğesidir, satır öğelerimizi içerecektir. İki tür kapsayıcı vardır: .container
ve .container--fluid
.
.container
davranışı, belirli bir noktanın altındaki genişliğin %100'ü, üzerinde maksimum sabit genişliğe sahip olması ve sol ve sağ eşit kenar boşluklarına sahip olmasıyla tanımlanır:
$grid__bp-md: 768; .container { max-width: $grid__bp-md * 1px; margin: 0 auto; }
"Çıkış" penceresini genişletip daraltarak onunla burada oynayın
Her zaman %100 genişliğe sahip olan sıvı kabı için, bu özellikleri bir değiştirici ile geçersiz kılıyoruz:
&--fluid { margin: 0; max-width: 100%; }
Onunla burada oyna.
Kolaydı! Artık her iki kapsayıcıyı da uyguladık. Bir sonraki öğeye geçelim.
satırlar
Satırlar, içeriğimizin yatay düzenleyicileri olacaktır.
Bir satırın alt öğelerini konumlandırmak için Flexbox'ı kullanacağız, böylece taşmamaları için onları saracağız ve onlara satırın içinde %100 genişlik vereceğiz (böylece daha sonra iç içe yerleştirebiliriz).
&__row { display: flex; flex-wrap: wrap; width: 100%; }
Bu, alt öğeleri yan yana konumlandıracak ve genişliklerinin toplamı kendisinden büyükse onları yeni satırlara saracaktır. Şimdi sadece bazı div'ler eklememiz gerekiyor ve şöyle görünecek:
"Çıktı" penceresini genişletip daraltarak onunla burada oynayın.
İşler şekillenmeye başlıyor, ancak bu henüz bir CSS ızgarası değil. Kayıp…
sütunlar
Sütunlar, site içeriğinin bulunduğu yerdir. Sıranın kaç parçaya bölündüğünü ve ne kadar kapladığını tanımlarlar. On iki sütunlu bir yerleşim yapacağız. Bu, satırı bir veya on iki parçaya bölebileceğimiz anlamına gelir.
Başlangıç olarak, bazı temel matematik. Bir sütuna sahip olmak istediğimizde genişliği %100 olmalıdır. On iki sütun istiyorsak. O zaman her biri genişliğin %8.333'ünü veya 100/12'sini işgal etmelidir.
Flexbox ile içeriği bu şekilde dağıtmak için flex-basis
kullanabiliriz.
Dört sütuna bölmek için şimdi şöyle bir şey ekleyeceğiz:
flex-basis: (100 / 4 ) * 1%;
Bu şekilde, elemanların her birinin genişliğin %25'ini ya da istediğimiz yüzdeyi işgal etmesini sağlayabiliriz.
Onunla burada oyna.
Bunu daha dinamik hale getirelim. Bunun olası sınıflarımızı yansıtmasını istediğimiz için, on iki tanesinin yeni bir satıra kaydırılmadan önce sığması gerektiğinden, genişliğin %8.333'üne sahip olacak bir sütun div için bir sınıf olan .col-1
çağıralım. Yüzde, %100'ü kaplayacak olan .col-12
kadar baştan sona artacaktır.
$grid__cols: 12; @for $i from 1 through $grid__cols { .col-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } }
Neler olduğunu netleştirmek için, genişliği dört eşit parçaya bölmek istediğimizi varsayalım. 12'de 4 kez sığacağı için .col-3
ihtiyacımız olacak, bu da .col-3
%25 esnek temele sahip olması gerektiği anlamına gelir:
100 / ($grid__cols / $i) 100 / (12 / 3) = 25
Bu zaten bir ızgara gibi görünmeye başladı!
Onunla burada oyna.
Ekran Genişliğine Bağlı Sütunlar
Artık mobilde belirli bir genişliğe sahip, tabletlerde ise farklı bir elemana sahip olmak istiyoruz. Pencerenin genişliğine bağlı olarak belirli kesme noktaları kullanacağız. Kullanıcı arayüzümüz bu kesme noktalarına tepki verecek ve farklı cihazların ekran boyutlarına uygun ideal bir düzene uyum sağlayacaktır. Kesme noktalarını boyuta göre adlandıracağız: küçük (sm), orta (md) vb., .col-sm-12
, sm
kesme noktasına kadar en az 12 sütun kaplayan bir öğe olacaktır.

.col-*
sınıfını .col-sm-*
olarak yeniden adlandıralım. Izgaramız önce mobil olacağından, özelliklerini tüm ekran boyutlarına uygulayacağız. Daha büyük ekranlarda farklı davranmamız gerekenler için sınıfı ekleyeceğiz: .col-md-*
.
.col-sm-12
ve .col-md-4
içeren bir öğe hayal edin. Beklenen davranış, "md" (orta) kesme noktasının altında %100 genişliğe ve bunun üzerinde %33.333'e sahip olması olacaktır; bu çok yaygın bir durumdur, çünkü mobil cihazlarda öğeleri yan yana değil üstte yığmanız gerekebilir. genişliğiniz çok daha sınırlı olduğunda birbirinize.
Bunun için, kesme noktasında bir medya sorgusu (yalnızca belirli bir genişliğin üzerinde veya altında veya belirli bir aygıtta yürütülecek kodu içeren bir ifade) eklememiz ve daha önce sm
için yaptığımız gibi md
sütunlarımızı oluşturmamız gerekecek:
@media screen and (min-width: $grid__bp-md * 1px) { @for $i from 1 through $grid__cols { &__col-md-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } } }
Onunla burada oyna.
Bu zaten yararlı bir şeye yaklaşıyor. Bu biraz ISLAK (Anladın mı? KURU değil…), o yüzden daha soyut yapalım.
Gördüğümüz gibi, her kesme noktası için bir medya sorgusuna ihtiyacımız olacak, bu yüzden dinamik olarak medya sorguları oluşturan bir kesme noktası alan bir karışım oluşturalım. Bunun gibi görünebilir:
@mixin create-mq($breakpoint) { @if($breakpoint == 0) { @content; } @else { @media screen and (min-width: $breakpoint *1px) { @content; } } }
Şimdi, __col
sınıflarını oluşturmak için sahip olduklarımızı create-col-classes
adlı bir karışıma saralım ve create-mq
karışımını kullanalım.
@mixin create-col-classes($modifier, $grid__cols, $breakpoint) { @include create-mq($breakpoint) { @for $i from 1 through $grid__cols { &__col#{$modifier}-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } } } }
Ve bu kadar. Bunu kullanmak için şimdi kesme noktalarımızı bir Sass haritasında tanımlıyor ve yineliyoruz.
$map-grid-props: ('-sm': 0, '-md': $grid__bp-md, '-lg': $grid__bp-lg); @each $modifier , $breakpoint in $map-grid-props { @include create-col-classes($modifier, $grid__cols, $breakpoint); }
Izgara sistemimiz temelde tamamlandı! Varsayılan olacak bir .container__col-sm-*
sınıfı tanımladık ve daha büyük ekranlardaki davranışını container__col-md-*
ve container__col-lg-*
ile değiştirebiliriz.
Hatta sıraları iç içe geçirebiliriz! Onunla burada oyna.
Bununla ilgili güzel olan şey, şimdi Bootstrap v4 ile aynı kesme noktalarına sahip olmasını istiyorsak, yapmamız gereken tek şey:
$grid__bp-sm: 576; $grid__bp-md: 768; $grid__bp-lg: 992; $grid__bp-xl: 1200; $map-grid-props: ( '': 0, '-sm': $grid__bp-sm, '-md': $grid__bp-md, '-lg': $grid__bp-lg, '-xl': $grid__bp-xl );
Ve bu kadar! Onunla burada oyna.
Bootstrap'in ilk başta tartıştığımızdan daha eksiksiz bir mobil öncelikli yaklaşımı nasıl benimsediğine dikkat edin. En küçük pencere boyutlarının sm
veya md
gibi bir son eki yoktur, bunun nedeni, .container__col-X
eşdeğer sınıfın yalnızca 0 ila 576 piksellik bir pencere genişliğinde uygulanmayacağıdır; üzerine açıkça yazmazsak, her pencere boyutunda bu sütun sayısı olacaktır. Aksi takdirde, sm
kesme noktaları arasında Y sütunlarının genişliğini yapmak için .container__col-sm-Y
sınıfını ekleyebiliriz.
Ofsetler
Ofsetler, önceki sütuna göre bir marj bırakacaktır. Bir .container__col-offset-4
, tüm ekran boyutlarında margin-left: 33.333%
. .container__col-md-offset-4
aynısını yapacak, ancak md
kesme noktasının üzerinde olacak.
Uygulama artık önemsizdir; sınıfları oluşturduğumuz döngüye bir -offset
özelliği ekleriz, ancak flex-bases
yerine margin-left
özelliğini yazarız. Daha büyük ekranlarda kenar boşluğunu temizlemek isteyebileceğimiz için -offset-0
için de fazladan bir tane yapmalıyız:
@mixin create-col-classes($modifier, $grid-cols, $breakpoint) { @include create-mq($breakpoint) { &__col#{$modifier}-offset-0 { margin-left: 0; } @for $i from 1 through $grid-cols { &__col#{$modifier}-#{$i} { flex-basis: (100 / ($grid-cols / $i) ) * 1%; } &__col#{$modifier}-offset-#{$i} { margin-left: (100 / ($grid-cols / $i) ) * 1%; } } } }
Artık tamamen işlevsel ofsetlerimiz var! Onunla burada oyna.
görüntülenebilirlik
Bazen belirli bir noktanın altında veya üstünde bir öğeyi görüntülemek/gizlemek isteriz. Bunun için Bootstrap v4'teki gibi sınıfları kullanılabilir hale getirebiliriz.
Örneğin, .hidden-md-up
sınıfı, bu sınıfa sahip herhangi bir öğeyi md
kesme noktasından yukarıya doğru gizleyecektir; tersine, .hidden-md-down
onu kesme noktasından aşağıya gizleyecektir.
Bunun kodu yine basit: Sadece kesme noktalarımızı yineliyoruz for each
bir .hidden-*
sınıfı oluşturuyoruz. Yine de create-mq
sınıfını biraz daha soyut olacak şekilde değiştirdik:
@each $modifier , $breakpoint in $map-grid-props { @if($modifier == '') { $modifier: '-xs'; } @include create-mq($breakpoint - 1, 'max') { .hidden#{$modifier}-down { display: none !important; } } @include create-mq($breakpoint, 'min') { .hidden#{$modifier}-up { display: none !important; } } }
Ek bir not olarak, bu, !important
için birkaç iyi kullanımdan biri değil mi? Öğenin bir display: block
kuralıyla keyfi olarak daha fazla özgüllüğe sahip olabileceğine dikkat edin, ancak yine de onu kesme noktasının altına veya üstüne gizlemek isteriz. Bu yaklaşıma katılmıyorsanız, yorumlarda bana bildirin!
İşte bu kadar: Artık bir görüntülenebilirlik sistemimiz var.
Onunla burada oyna.
Çözüm
Bu "çerçeve" üretime hazır olmasa da, Flexbox düzenlerinin ne kadar güçlü olabileceğini ve Sass'ın ne kadar kullanışlı olduğunu gösteriyor. Yalnızca birkaç satır kodla, bir CSS çerçevesinin/ızgarasının temel işlevlerini uyguladık.
Hemen hemen her yazılımın temel bir sürümünün çok kolay bir şekilde uygulanabileceği bir ders olarak da hizmet edebilir. Toplanmaya başlayan ve onu zorlaştıran, gerçek dünyanın somut sorunlarıdır.
Sorunları gönderebileceğiniz veya istekleri çekebileceğiniz bir GitHub deposu oluşturdum.
Hangi özelliklerin uygulandığını görmek istersiniz? Uygulama basitleştirilebilir veya daha zarif olabilir mi?
Aşağıdaki yorumlar hakkındaki düşüncelerinizi bana bildirmekten çekinmeyin.