Dalam proses pembuatanya, kita akan mencoba teknik baru dalam penyusunan layout, yakni menggunakan Flexbox. Teknik ini hadir pada CSS3 dan menjadi salah satu pendekatan populer dalam penyusunan layout yang responsif. Nantinya kalkulator yang kita kembangkan ini dapat digunakan dengan baik pada mobile device.
Box Model
Jadi apa sebenarnya itu flexbox atau flexible box model? Pada dasarnya flexbox merupakan mode layout yang mudah dan praktis untuk mengatur elemen dengan menggunakan sebuah container.
Sebelumnya kita sudah menggunakan teknik float dalam penyusunan layout. Float memang cukup mudah dipahami tetapi tak cukup praktis untuk digunakan. Passalnya, kita memerlukan pengukuran dimensi yang tepat agar elemen berada posisi yang diinginkan.
Dengan Flexbox kita dapat mengatur ukuran secara otomatis dan mampu beradaptasi dengan ukuran container-nya. Dengan kemampuan flexibelnya, tampilan layout yang disusun menggunakan flexbox menjadi mobile-friendly. Selain itu, flexbox dapat dikombinasikan dengan media query, sehingga ia dapat lebih optimal lagi digunakan pada peranti mobile.
Berikut beberapa konsep dari flexbox yang perlu kita ketahui:
- Dapat mengubah ukuran dimensi elemen dengan menyesuaikan ukuran yang cocok bagi ruang kosong yang ada pada container-nya.
- Flexbox is directional agnostic. ini berbeda dengan konsep block model di mana elemen selalu ditampilkan secara vertikal dengan membuat baris baru. Ini berbeda pula dengan konsep inline model di mana elemen selalu ditampilkan secara horizontal. Dengan flexbox kita dapat melakukan kedua hal tersebut dengan mudah.
- Dibuat untuk menyusun layout yang mobile friendly.
Flex Container
Flex container merupakan sebuah elemen yang menampung beberapa flex item. Karena Parent-child merupakan relasi yang wajib ada dalam penerapan flexbox, maka setiap flex item harus merupakan anak / child dari flex container.
Secara default deretan flex-item pada container ditampilkan secara horizontal. Ketika menggunakan flex, kita tidak perlu mengatur dimensi dari tiap flex item secara manual untuk mengisi ruang kosong pada container. Sebelum ada flexbox, hal ini jadi kendala umum. Alih-alih, kita harus melakukan perhitungan yang tepat agar tak terjadi overflow pada layout yang ditampilkan.
Untuk membuat sebuah flex container kita gunakan properti display dengan nilai flex. Dengan demikian seluruh anak dari container tersebut akan menjadi flex item. Berikut contoh penerapan flexbox untuk membuat tampilan seperti gambar di atas:
- <!doctype html>
- <html lang="en">
- <head>
- <style>
- .container {
- display: flex;
- /* Properti lainnya */
- width: 800px;
- height: 250px;
- background-color: #11C5C6;
- border: 2px solid black;
- padding: 20px;
- border-radius: 10px;
- margin: 0 auto;
- }
- .box {
- flex-grow: 1;
- /* properti lainnya */
- background-color: #FBDD1C;
- margin: 5px;
- border: 2px solid black;
- border-radius: 10px;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="box"></div>
- <div class="box"></div>
- <div class="box"></div>
- </div>
- </body>
- </html>
Output dari kode di atas adalah:
Flex Grow
Bisa kita lihat seluruh box di dalam container dapat menyesuaikan ukurannya sesuai ruang kosong yang ada pada container. Pada box, kita tidak menetapkan nilai dimensi seperti width dan height. Kita cukup menggunakan satu properti yakni flex-grow: 1;.
Properti flex-grow ini digunakan untuk memberitahu berapa banyak ukuran yang harus ditetapkan oleh flex-item. Nilai dari properti ini bukan nilai dari dimensi asli pada flex item, melainkan nilai yang relatif terhadap ruang kosong pada flex container.
Jika kita menetapkan nilai yang sama pada seluruh flex item, maka dimensi dari tiap flex item akan sama rata dan memenuhi ruang kosong yang ada pada container. Namun jika kita memberikan nilai yang berbeda dari salah satu itemnya, contohnya nilai yang lebih besar, maka flex item tersebut akan mencakup ukuran yang lebih besar. Flex item yang lain akan menyusut menyesuaikan agar tetap masuk pada ruang flex container. Contohnya seperti berikut:
- <!doctype html>
- <html lang="en">
- <head>
- <style>
- .container {
- display: flex;
- /* Properti lainnya */
- width: 800px;
- height: 250px;
- background-color: #11C5C6;
- border: 2px solid black;
- padding: 20px;
- border-radius: 10px;
- margin: 0 auto;
- }
- .box {
- /* properti lainnya */
- background-color: #FBDD1C;
- margin: 5px;
- border: 2px solid black;
- border-radius: 10px;
- }
- .first {
- flex-grow: 1;
- }
- .second {
- flex-grow: 2;
- }
- .third {
- flex-grow: 1;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="box first"></div>
- <div class="box second"></div>
- <div class="box third"></div>
- </div>
- </body>
- </html>
Cara kerja flex-grow mirip seperti potongan kue. Ruang kosong pada elemen akan dibagi-bagi sesuai besaran nilainya. Contoh di atas memberi kita gambaran seperti sebuah kue dengan luas total 4, kemudian kue tersebut dipotong menjadi 3 potong. Potongan yang tengah mendapatkan 2 bagian dan potongan yang lainnya masing - masing mendapatkan 1 bagian. Maka potongan yang tengah akan lebih besar dari potongan yang lain.
Betapa fleksibelnya bukan? Yang harus kita ingat, ketika kita mengubah ukuran dari suatu flex item, maka flex item yang lain pun akan terpengaruh
Flex Direction
Seperti yang sudah kita ketahui sebelumnya, Flexbox merupakan directional agnostic, di mana kita dapat mengubah arah flex-item ditempatkan pada container. Secara default deretan flex-item ditampilkan secara horizontal, namun kita dapat mengubahnya dengan menetapkan properti flex-direction pada container-nya.
- <!doctype html>
- <html lang="en">
- <head>
- <style>
- .container {
- display: flex;
- flex-direction: column;
- /* Properti lainnya */
- width: 800px;
- height: 250px;
- background-color: #11C5C6;
- border: 2px solid black;
- padding: 20px;
- border-radius: 10px;
- margin: 0 auto;
- }
- .box {
- /* properti lainnya */
- background-color: #FBDD1C;
- margin: 5px;
- border: 2px solid black;
- border-radius: 10px;
- }
- .first {
- flex-grow: 3;
- }
- .second {
- flex-grow: 2;
- }
- .third {
- flex-grow: 1;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="box first"></div>
- <div class="box second"></div>
- <div class="box third"></div>
- </div>
- </body>
- </html>
Output dari kode di atas adalah:
Ada empat nilai yang bisa digunakan untuk properti flex-direction, antara lain:
- row : merupakan nilai default, di mana deretan flex-item pada container ditampilkan secara horizontal.
- row-reverse : memiliki sifat yang sama seperti row, namun urutan flex item-nya ditukar.
- column : Deretan flex-item pada container ditampilkan secara vertikal.
- column-reverse : memiliki sifat yang sama seperti column, namun urutan flex item-nya ditukar.
Karena properti flex-direction ini, kita dapat membuat dua dimensional layout dengan menempatkan flex container di dalam flex container, dalam arti lain sebuah flex container dapat memiliki child berupa flex container lain.
- <!doctype html>
- <html lang="en">
- <head>
- <style>
- .flex-column {
- display: flex;
- flex-direction: column;
- /* properti lainnya */
- width: 800px;
- height: 300px;
- padding: 20px;
- margin: 0 auto;
- border: 2px solid black;
- border-radius: 10px;
- background-color: #11C5C6;
- }
- .flex-row {
- display: flex;
- flex-direction: row;
- flex-grow: 1;
- /* properti lainnya */
- padding: 20px;
- margin: 5px;
- background-color: #FBDD1C;
- border: 2px solid black;
- border-radius: 10px;
- }
- .box {
- flex-grow: 1;
- /* properti lainnya */
- margin: 5px;
- border: 2px solid black;
- border-radius: 10px;
- background-color: #fe899a;
- }
- </style>
- </head>
- <body>
- <div class="flex-column">
- <div class="flex-row">
- <div class="box"></div>
- <div class="box"></div>
- <div class="box"></div>
- </div>
- <div class="flex-row">
- <div class="box"></div>
- <div class="box"></div>
- <div class="box"></div>
- </div>
- </div>
- </body>
- </html>
Output dari kode di atas adalah:
Flex Basis
Selain menggunakan flex-grow, untuk menentukan ukuran flex item, kita bisa gunakan properti flex-basis. Properti ini mirip seperti width dalam menentukan dimensi box. Kita bisa menggunakan nilai satuan tetap seperti px, pt, pc, cm dll, atau kita juga bisa menggunakan satuan persentase %.
Flex-grow ini digunakan ketika kita ingin menetapkan ukuran awal pada sebuah flex-item. Alhasil, kita dapat mengatur ukuran dengan lebih leluasa. Flex-grow biasa digunakan ketika kita menerapkan nested flex-container dan terdapat perbedaan jumlah child pada container-nya. Untuk lebih mudah menggambarkannya, perhatikan contoh berikut:
- <!doctype html>
- <html lang="en">
- <head>
- <style>
- * {
- box-sizing: border-box;
- }
- .container {
- width: 800px;
- border: 2px solid black;
- margin: 0 auto;
- }
- .flex-column {
- display: flex;
- flex-direction: column;
- }
- .flex-row {
- display: flex;
- flex-direction: row;
- flex-grow: 1;
- }
- .box {
- flex-grow: 1;
- background-color: cornflowerblue;
- border: 2px solid black;
- padding: 40px;
- text-align: center;
- color: white;
- font-size: 1.5em;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="flex-column">
- <div class="flex-row">
- <div class="box">1</div>
- <div class="box">2</div>
- <div class="box">3</div>
- <div class="box">4</div>
- </div>
- <div class="flex-row">
- <div class="box">5</div>
- <div class="box">6</div>
- <div class="box">7</div>
- </div>
- </div>
- </div>
- </body>
- </html>
Output dari kode di atas adalah:
Pada contoh di atas kita memiliki satu buah flex-container column yang di dalamnya terdapat dua buah flex-container row. Kemudian flex-container row yang pertama memiliki empat buah flex-item, dan yang kedua memiliki tiga buah flex-item.
Standarnya ketika kita menggunakan nilai flex-grow: 1 pada seluruh flex-item yang ada, maka tampilan akan seperti gambar di atas. Namun bagaimana jika kita ingin mengatur flex-item di row kedua dengan tampilan berbeda seperti di bawah ini?
Jika kita menggunakan flex-grow, mungkin kita dapat memberikan nilai flex-grow: 2 pada box ke tujuh.
- ....
- <div class="box double">7</div>
- ...
- .....
- .double {
- flex-grow: 2;
- }
Namun hasilnya akan tampak seperti ini:
Sebabya, properti flex-grow tidak menjamin elemen yang menerapkan nilai 2 akan lebih besar 2 kali lipat dari nilai 1.
Flex-grow akan mencari nilai yang sesuai yang dapat dibagi pada flex-items. Agak terdengar aneh, bukan? Nah, temukan artikel yang cukup menarik yang membahas permasalahan ini pada tautan berikut.
Sebenarnya bisa saja kita menggunakan flex-grow untuk mendapatkan hasil yang diinginkan namun kita harus mencari nilai yang pas secara manual. Ini tentunya akan memakan waktu lebih.
Pada kasus seperti ini, solusinya adalah menggunakan properti flex-basis. Dengan properti ini kita dapat asumsikan bahwa total ruang kosong pada flex-container adalah 100%. Jika dibagi rata terhadap empat buah flex-item, maka tiap itemnya harus memiliki nilai 25%.
- doctype html>
- <html lang="en">
- <head>
- <style>
- * {
- box-sizing: border-box;
- }
- .container {
- width: 800px;
- border: 2px solid black;
- margin: 0 auto;
- }
- .flex-column {
- display: flex;
- flex-direction: column;
- }
- .flex-row {
- display: flex;
- flex-direction: row;
- flex-grow: 1;
- }
- .box {
- flex-basis: 25%;
- background-color: cornflowerblue;
- border: 2px solid black;
- padding: 40px;
- text-align: center;
- color: white;
- font-size: 1.5em;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="flex-column">
- <div class="flex-row">
- <div class="box">1</div>
- <div class="box">2</div>
- <div class="box">3</div>
- <div class="box">4</div>
- </div>
- <div class="flex-row">
- <div class="box">5</div>
- <div class="box">6</div>
- <div class="box">7</div>
- </div>
- </div>
- </div>
- </body>
- </html>
Output kode di atas adalah:
Maka seluruh flex-items akan memiliki ukuran yang sama. Tetapi pada flex-container baris kedua terdapat 25% ruang bebas, karena jumlah flex-itemnya hanya tiga. Kita bisa menggunakan ruang kosong tersebut untuk membuat box tujuh lebih besar dua kali lipat dengan menggunakan nilai flex-basis: 50%;
- ....
- <div class="box double">7</div>
- ...
- .....
- .double {
- flex-basis: 50%;
- }