Tutorial Flexbox dan Sass Grid: Cara Merampingkan Desain Responsif

Diterbitkan: 2022-03-11

Baru-baru ini, saya ditantang untuk membuat sistem grid saya sendiri dan, karena menemukan kembali roda selalu berguna sebagai pengalaman belajar, saya melakukannya. Saya tahu ini akan menjadi tantangan yang menarik, tetapi saya terkejut dengan betapa mudahnya ternyata!

Tutorial Grid Sass dan Flexbox

Dalam eksperimen ini, kita akan melihat tata letak Flexbox dan bagaimana tata letak tersebut memungkinkan implementasi tata letak yang anggun tanpa melakukan peretasan gila apa pun. Juga, jika Anda tidak terbiasa dengan Sass, kita akan melihat cara kerjanya dan menggunakan beberapa utilitas Sass yang praktis. Anda bahkan mungkin mempelajari sesuatu yang baru tentang grid CSS seperti yang merupakan bagian dari Bootstrap.

Pengenalan Sass dan Flexbox yang Sangat Singkat

Sass pada dasarnya adalah alat yang memungkinkan Anda untuk menghindari beberapa kekurangan CSS, ini adalah bahasa skrip yang diinterpretasikan ke CSS. Sintaksnya terlihat sangat familier jika Anda sudah menulis gaya CSS tetapi kotak peralatannya menyertakan variabel, mixin untuk kegunaan ulang dan jika, untuk, masing-masing dan sementara arahan di antara yang lainnya. Salah satu hal terpenting tentang Sass adalah bahwa setiap kode CSS yang valid adalah Sass yang valid, sehingga Anda dapat mengubah basis kode Anda secara bertahap.

Contoh sederhana dari for loop:

 @for $i from 1 through 3 { .a-numbered-class-#{$i} { width: (20 * $i) * 1px; } }

Loop sederhana ini beralih dari 1 hingga 3 dan membuat kelas. Indeks iterasi akan dengan mudah disimpan di $i . Kita juga dapat mengerjakan matematika dan mencetak .a-numbered-class-X sebanyak tiga kali dengan lebar yang berbeda setiap kali. Kode ini menghasilkan:

 .a-numbered-class-1 { width: 20px; } .a-numbered-class-2 { width: 40px; } .a-numbered-class-3 { width: 60px; }

Seperti yang dapat kita lihat, kita dapat mengabstraksi banyak pekerjaan yang harus Anda lakukan di CSS. Di CSS, Anda harus menyalin dan menempel dan memodifikasi secara manual, yang jelas lebih rawan kesalahan dan kurang elegan, Jika Anda belum mencobanya, jangan buang waktu lagi!

Flexbox adalah singkatan dari Flexible Box, sistem tata letak CSS3 yang memposisikan dan mendistribusikan elemen secara dinamis. Ini adalah alat yang sangat kuat yang memungkinkan tata letak yang fleksibel dengan sedikit usaha. Untuk detail selengkapnya tentang cara mempelajari Flexbox, lihat Panduan Lengkap Chris Coyier untuk Flexbox.

kisi-kisi

Pindah ke grid itu sendiri, mari kita mulai dengan elemen dasarnya. Mereka akan terinspirasi oleh elemen grid Bootstrap: Containers, Rows, dan Columns, masing-masing terdapat di dalam yang pertama.

Kami akan menggunakan konvensi penamaan BEM untuk nama kelas. Konvensi BEM cukup mudah digunakan dan menambahkan banyak informasi tentang elemen dan konteksnya. Secara singkat, Anda memiliki:

  • Blocks , yang “mengenkapsulasi entitas mandiri yang memiliki arti tersendiri”: .block .
  • Elemen , yang merupakan “bagian dari blok dan tidak memiliki arti yang berdiri sendiri” yang dilambangkan dengan nama blok, dua garis bawah, dan elemen: .block__elem
  • Pengubah , seperti “Bendera pada balok atau elemen”, yang diwakili dengan dua tanda hubung: .block .block--mod .

Wadah, Baris, dan Kolom

Wadah

Ini adalah elemen terluar dari grid, itu akan berisi elemen baris kita. Ada dua jenis container: .container dan .container--fluid .

Perilaku .container didefinisikan dengan menjadi 100% lebar di bawah titik tertentu, memiliki lebar tetap maksimum di atasnya dan memiliki margin kiri dan kanan yang sama:

 $grid__bp-md: 768; .container { max-width: $grid__bp-md * 1px; margin: 0 auto; }

Mainkan dengannya di sini dengan memperluas dan mengontrak jendela "keluaran"

Untuk wadah cairan, yang selalu memiliki lebar 100%, kami hanya mengganti properti tersebut dengan pengubah:

 &--fluid { margin: 0; max-width: 100%; }

Mainkan di sini.

Itu mudah! Kami sekarang memiliki kedua wadah yang diimplementasikan. Mari kita beralih ke elemen berikutnya.

Baris

Baris akan menjadi pengatur horizontal konten kami.

Kami akan menggunakan Flexbox untuk memposisikan elemen turunan baris, membuatnya terbungkus sehingga tidak meluap dan memberi mereka lebar 100% di dalam baris (sehingga kami dapat menyusunnya nanti).

 &__row { display: flex; flex-wrap: wrap; width: 100%; }

Ini akan memposisikan elemen anak berdampingan dan membungkusnya menjadi baris baru jika jumlah lebarnya lebih besar dari dirinya sendiri. Kita sekarang hanya perlu menambahkan beberapa div dan akan terlihat seperti ini:

Elemen baris

Mainkan di sini dengan memperluas dan mengontrak jendela "output".

Hal-hal mulai terbentuk, tetapi ini belum menjadi kisi CSS. Itu hilang…

kolom

Kolom adalah tempat tinggal konten situs. Mereka menentukan berapa banyak bagian baris yang dibagi dan berapa banyak yang mereka tempati. Kita akan melakukan tata letak dua belas kolom. Ini berarti kita dapat membagi baris menjadi satu atau hingga dua belas bagian.

Untuk mulai dengan, beberapa matematika dasar. Ketika kita ingin memiliki satu kolom, lebarnya harus 100%. Jika kita ingin dua belas kolom. Maka masing-masing harus menempati 8.333…% atau 100/12 dari lebarnya.

Dengan Flexbox, untuk mendistribusikan konten dengan cara ini, kita dapat menggunakan flex-basis .

Untuk membagi dalam empat kolom, kita sekarang akan menambahkan sesuatu seperti:

 flex-basis: (100 / 4 ) * 1%;

Dengan cara ini, kita bisa membuat elemen masing-masing menempati 25% dari lebar—atau berapa pun persentase yang kita inginkan.

Mainkan di sini.

Mari kita membuatnya lebih dinamis. Karena kita ingin ini mencerminkan kemungkinan kelas kita, sebut .col-1 , kelas untuk kolom div yang akan memiliki lebar 8,333% karena dua belas di antaranya harus muat sebelum mereka harus membungkus ke baris baru. Persentase akan meningkat secara keseluruhan hingga .col-12 , yang akan menempati 100%.

 $grid__cols: 12; @for $i from 1 through $grid__cols { .col-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } }

Untuk memperjelas apa yang terjadi, katakanlah kita ingin membagi lebar menjadi empat bagian yang sama. Kita membutuhkan .col-3 karena cocok 4 kali dalam 12, itu berarti .col-3 harus memiliki basis fleksibel 25%:

 100 / ($grid__cols / $i) 100 / (12 / 3) = 25

Ini sudah mulai terlihat seperti kotak!

Tampak seperti kisi-kisi!

Mainkan di sini.

Kolom Tergantung Lebar Layar

Kami sekarang ingin dapat memiliki elemen yang memiliki lebar tertentu di ponsel tetapi berbeda di tablet dan seterusnya. Kami akan menggunakan breakpoint tertentu tergantung pada lebar jendela. UI kami akan bereaksi pada breakpoint tersebut dan beradaptasi dengan tata letak ideal yang disesuaikan dengan ukuran layar perangkat yang berbeda. Kami akan menamai breakpoint berdasarkan ukuran: kecil (sm), sedang (md) dan seterusnya, .col-sm-12 akan menjadi elemen yang menempati 12 kolom setidaknya sampai sm breakpoint.

Mari kita ganti nama kelas .col-* .col-sm-* . Karena grid kami akan menjadi yang pertama untuk seluler, kami akan menerapkan propertinya ke semua ukuran layar. Untuk yang kita butuhkan untuk berperilaku berbeda dengan layar yang lebih besar, kita akan menambahkan kelas: .col-md-* .

Bayangkan sebuah elemen dengan .col-sm-12 dan .col-md-4 . Perilaku yang diharapkan adalah bahwa di bawah breakpoint "md" (medium) itu akan memiliki lebar 100% dan di atasnya akan memiliki 33,333%—kejadian yang sangat umum, karena di seluler Anda mungkin perlu menumpuk elemen di atas daripada di samping satu sama lain ketika lebar Anda jauh lebih terbatas.

Menumpuk kolom setelah mencapai breakpoint

Untuk ini, kita perlu menambahkan kueri media (ekspresi yang berisi kode yang hanya akan dieksekusi di atas atau di bawah lebar tertentu atau pada perangkat tertentu) pada titik henti sementara dan membuat kolom md seperti yang kita lakukan sebelumnya untuk sm :

 @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%; } } }

Mainkan di sini.

Itu sudah mendekati sesuatu yang berguna. Itu agak BASAH (Mengerti? Ini bukan KERING…), jadi mari kita membuatnya lebih abstrak.

Seperti yang kita lihat, kita akan memerlukan kueri media untuk setiap titik henti sementara, jadi mari buat mixin yang menerima titik henti sementara yang secara dinamis membuat kueri media. Itu bisa terlihat seperti ini:

 @mixin create-mq($breakpoint) { @if($breakpoint == 0) { @content; } @else { @media screen and (min-width: $breakpoint *1px) { @content; } } }

Sekarang, mari kita bungkus apa yang kita miliki untuk membuat kelas __col dalam mixin yang disebut create-col-classes dan gunakan mixin create-mq .

 @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%; } } } }

Dan itu saja. Untuk menggunakannya, sekarang kami mendefinisikan breakpoint kami di peta Sass, dan mengulanginya.

 $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); }

Sistem grid kami pada dasarnya sudah selesai! Kami telah mendefinisikan kelas .container__col-sm-* yang akan menjadi default dan kami dapat mengubah perilakunya di layar yang lebih besar dengan container__col-md-* dan container__col-lg-* .

Kita bahkan bisa membuat sarang! Mainkan di sini.

Hal yang menyenangkan tentang ini adalah bahwa jika kita sekarang ingin memiliki semua breakpoint yang sama dengan Bootstrap v4 kita hanya perlu melakukan:

 $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 );

Dan itu saja! Mainkan di sini.

Perhatikan bagaimana Bootstrap mengambil pendekatan mobile-first yang lebih lengkap daripada yang kita bahas sebelumnya. Ukuran jendela terkecil tidak memiliki akhiran seperti sm atau md , alasannya adalah bahwa kelas yang setara dengan .container__col-X tidak hanya akan diterapkan dari lebar jendela 0 hingga 576px; jika kita tidak menimpanya secara eksplisit, itu akan menjadi jumlah kolom di setiap ukuran jendela. Jika tidak, kita bisa menambahkan kelas .container__col-sm-Y untuk membuatnya menjadi lebar kolom Y di antara sm breakpoints.

Offset

Offset akan menambahkan margin kiri sehubungan dengan kolom sebelumnya. Sebuah .container__col-offset-4 akan menambahkan margin-left: 33.333% pada semua ukuran layar. .container__col-md-offset-4 akan melakukan hal yang sama tetapi di atas breakpoint md .

Implementasinya sekarang sepele; kami menambahkan properti -offset pada loop yang sama saat kami membuat kelas, tetapi alih-alih flex-bases , kami menulis properti margin-left . Kita harus melakukan tambahan untuk -offset-0 juga, karena kita mungkin ingin menghapus margin pada layar yang lebih besar:

 @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%; } } } }

Kami sekarang memiliki offset yang berfungsi penuh! Mainkan di sini.

Kemampuan untuk ditampilkan

Terkadang kita ingin menampilkan/menyembunyikan elemen di bawah atau di atas titik tertentu. Untuk ini, kita dapat membuat kelas tersedia seperti Bootstrap v4.

Misalnya, kelas .hidden-md-up akan menyembunyikan elemen apa pun dengan kelas ini dari titik putus md ke atas; sebaliknya, .hidden-md-down akan menyembunyikannya dari breakpoint ke bawah.

Kode untuk ini sederhana sekali lagi: Kami hanya mengulangi breakpoint kami dan membuat kelas .hidden-* dengan a for each breakpoint. Kami memodifikasi kelas create-mq menjadi sedikit lebih abstrak, meskipun:

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

Sebagai catatan tambahan, bukankah ini salah satu dari sedikit kegunaan yang baik untuk !important ? Perhatikan bahwa elemen mungkin memiliki spesifisitas yang lebih besar secara sewenang-wenang dengan aturan display: block :, tetapi kami masih ingin menyembunyikannya di bawah atau di atas breakpoint. Jika Anda tidak setuju dengan pendekatan ini, beri tahu saya di komentar!

Jadi itu saja: Kami memiliki sistem tampilan sekarang.

Mainkan di sini.

Kesimpulan

Meskipun "kerangka kerja" ini belum siap produksi, ini menunjukkan betapa kuatnya tata letak Flexbox dan betapa praktisnya Sass. Hanya dengan beberapa baris kode, kami mengimplementasikan fungsionalitas inti dari kerangka/kisi CSS.

Semoga ini juga menjadi pelajaran bahwa versi dasar dari hampir semua perangkat lunak dapat diimplementasikan dengan sangat mudah. Ini adalah masalah nyata dari dunia nyata yang mulai bertambah dan membuatnya sulit.

Saya membuat repo GitHub tempat Anda dapat mengirimkan masalah atau menarik permintaan.

Fitur apa yang ingin Anda lihat diterapkan? Bisakah implementasinya disederhanakan atau lebih elegan?

Jangan ragu untuk memberi tahu saya pendapat Anda di komentar di bawah.