# Memahami penggunaan CSS Flexbox

CSS Flexbox adalah model tata letak web yang dirancang untuk konten satu dimensi (disusun dalam bentuk baris atau kolom). Model tata letak ini menurut saya perlu dikuasai karena sudah cukup menyelesaikan persoalan desain web yang umum.

Setidaknya ada 14 *property* yang termasuk ke dalam CSS Flexbox. Omong-omong, artikel ini mengambil referensi dari dua artikel yang ditulis oleh CSS-Tricks berjudul [A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) dan [Understanding flex-grow, flex-shrink, and flex-basis](https://css-tricks.com/understanding-flex-grow-flex-shrink-and-flex-basis/), sehingga saya sangat menyarankan kamu untuk membacanya juga nanti.

Sebelum mulai, berikut saya lampirkan kode latihan jika kamu ingin sambil mempraktikkannya:

```html
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Flexbox | divClassId</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <main>
    <!-- 1. Property display: flex -->
    <div class="container display">
      <article class="card">
        <p>HTML adalah bahasa <em>markup</em> yang digunakan untuk menyusun struktur web.</p>
      </article>
      <article class="card">
        <p>CSS adalah bahasa <em>stylesheet</em> yang digunakan untuk mengatur tampilan atau visual web.</p>
      </article>
      <article class="card">
        <p>JavaScript adalah bahasa pemrograman yang digunakan pada web agar bisa tampil dinamis dan interaktif.</p>
      </article>
    </div>

    <!-- 2. Property flex-direction -->
    <div class="container flex-direction">
      
    </div>

    <!-- 3. Property flex-wrap -->
    <div class="container flex-wrap">
      
    </div>

    <!-- 4. Property flex-flow -->
    <div class="container flex-flow">
      
    </div>

    <!-- 5. Property justify-content -->
    <div class="container justify-content">
      
    </div>

    <!-- 6. Property align-items -->
    <div class="container align-items">
      
    </div>

    <!-- 7. Property align-content -->
    <div class="container align-content">
      
    </div>

    <!-- 8. Property gap -->
    <div class="container gap">
      
    </div>

    <!-- 9. Property order -->
    <div class="container order">
      
    </div>

    <!-- 10. Property align-self -->
    <div class="container align-self">
      
    </div>

    <!-- 11. Property flex-grow -->
    <div class="container flex-grow">
      
    </div>

    <!-- 12. Property flex-shrink -->
    <div class="container flex-shrink">
      
    </div>

    <!-- 13. Property flex-basis -->
    <div class="container flex-basis">
      
    </div>

    <!-- 14. Property flex -->
    <div class="container flex">
      
    </div>
  </main>
</body>
</html>
```

```css
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --color-black: #111111;
  --color-dark-green: #0b6758;
  --color-light-green: #0d7968;
  --color-white: #fcfcfc;
}

html {
  height: 100%;
}

body {
  background-color: var(--color-black);
  font-family: sans-serif;
  height: 100%;
  line-height: 1.5;
}

.container {
  padding: 10px;
}

.container:nth-child(odd) {
  background-color: var(--color-dark-green);
}

.container:nth-child(even) {
  background-color: var(--color-light-green);
}

.card {
  background-color: var(--color-white);
  border-radius: 10px;
  color: var(--color-black);
  margin: 10px;
  padding: 20px;
  width: calc(25% - 20px);
}

/* 1. Property display: flex */


/* 2. Property flex-direction */


/* 3. Property flex-wrap */


/* 4. Property flex-flow */


/* 5. Property justify-content */


/* 6. Property align-items */


/* 7. Property align-content */


/* 8. Property gap */


/* 9. Property order */


/* 10. Property flex-grow */


/* 11. Property flex-grow */


/* 12. Property flex-shrink */


/* 13. Property flex-basis */


/* 14. Property flex */


```

Berikut penjelasan untuk setiap *property* CSS Flexbox:

## 1. *Property* `display: flex`

Jika kita langsung menjalankan latihan di atas tentu tampilan *card* akan tersusun ke bawah karena efek dari *property* `display: block` bawaan elemen `<article>`. Namun, jika kita tambahkan `display: flex` pada elemen *container*-nya, maka *card* sekarang akan tersusun ke samping.

```css
/* 1. Property display: flex */
.display {
  display: flex;
}
```

![Contoh tampilan yang menggunakan property display: flex](https://cdn.hashnode.com/res/hashnode/image/upload/v1658224714301/NARr5L1XQ.png align="center")

Ini adalah cara mengaktifkan CSS Flexbox pada suatu elemen HTML. Bisa dilihat pula bahwa CSS Flexbox mengambil alih penerapan tata letak pada elemen-elemen di dalam *container*, termasuk jika di dalamnya ada elemen yang memiliki nilai `inline` pada *property* `display`-nya (seperti `<span>`).

## 2. *Property* `flex-direction`

Ketika menambahkan `display: flex` pada elemen *container* semua elemen di dalamnya akan otomatis ditampilkan dalam bentuk baris. Apakah ini murni efek yang dibawa *property* tersebut? Jawabannya, tentu tidak.

Ketika *property* tersebut ditambahkan, dibalik layar secara otomatis beberapa *property* juga ikut ditambahkan, salah satunya adalah `flex-direction`. *Property* ini memiliki nilai bawaan `row` yang menyebabkan *card* tersusun ke samping.

Beberapa nilai lain yang bisa kita gunakan, yaitu:

- `column`: Nilai ini akan menampilkan susunan *card* dalam bentuk kolom dari atas ke bawah.
- `row-reverse`: Serupa dengan nilai `row`, tapi akan ditampilkan dari kanan ke kiri.
- `column-reverse`: Serupa dengan nilai `column`, tapi akan ditampilkan dari bawah ke atas.

```css
/* 2. Property flex-direction */
.flex-direction {
  display: flex;
  flex-direction: column;
}
```

![Contoh tampilan yang menggunakan property flex-direction](https://cdn.hashnode.com/res/hashnode/image/upload/v1658224819673/GA0L5Ju-EM.png align="center")

## 3. *Property* `flex-wrap`

Kalau kamu coba menambahkan beberapa *card* lagi, kamu akan melihat semua *card* ditampilkan dalam satu baris yang sama dan ukuran lebarnya menjadi lebih kecil dari yang seharusnya. Ini terjadi karena CSS Flexbox memang hanya dirancang untuk konten satu dimensi saja.

Untuk mengatasinya, kita perlu mengubah nilai bawaan `flex-wrap` dari `nowrap` menjadi `wrap`. Dengan begitu, ketika beberapa *card* sudah memenuhi lebar dari elemen *container*, maka *card* lainnya akan tampil di bawahnya, tapi masih dalam satu kelompok baris yang sama.

```css
/* 3. Property flex-wrap */
.flex-wrap {
  display: flex;
  flex-wrap: wrap;
}
```

![Contoh tampilan yang menggunakan property flex-wrap](https://cdn.hashnode.com/res/hashnode/image/upload/v1658224858244/EgSb4zoaC.png align="center")

Ada juga nilai `wrap-reverse` yang serupa dengan nilai `wrap`, tapi akan ditampilkan sebaliknya.

## 4. *Property* `flex-flow`

`flex-flow` adalah *shorthand* atau penulisan ringkas dari `flex-direction` dan `flex-wrap` dengan nilai bawaannya adalah `row nowrap`.

```css
/* 4. Property flex-flow */
.flex-flow {
  display: flex;
  flex-flow: column wrap;

  /* Tambahan agar efeknya terlihat */
  height: 300px;
}
```

![Contoh tampilan yang menggunakan property flex-flow](https://cdn.hashnode.com/res/hashnode/image/upload/v1658224883972/7zJ_xc4TZ.png align="center")

## 5. *Property* `justify-content`

`justify-content` akan mengatur bagaimana susunan *card* ditampilkan di dalam baris jika ada ruang yang tersisa. Beberapa nilai yang perlu diketahui, antara lain:

- `flex-start` *(default)*: Nilai ini akan menampilkannya di awal berdasarkan nilai dari `flex-direction`. Jika nilainya tidak diubah, maka susunan *card* akan tampil di kiri.
- `flex-end`: Nilai ini akan menampilkannya di akhir berdasarkan nilai dari `flex-direction`. Jika nilainya tidak diubah, maka akan tampil di kanan.
- `center`: Nilai ini akan menampilkannya tepat di tengah.
- `space-between`: Nilai ini akan menampilkan *card* pertama di awal dan *card* terakhir di akhir baris, lalu membagi ruang yang tersisa untuk *card-card* di antara keduanya.
- `space-around`: Nilai ini akan membagi rata ruang yang tersisa terlebih dahulu kepada setiap *card*. Itu sebabnya ruang pada sisi *card* awal dan *card* akhir yang berbatasan tepi tidak sama dengan ruang antara *card*, karena ruang antara *card* merupakan gabungan dua ruang.
- `space-evenly`: Nilai ini akan membagi rata ruang yang tersisa baik antara sesama *card* maupun antara *card* dan tepinya.

```css
/* 5. Property justify-content */
.justify-content {
  display: flex;
  justify-content: space-evenly;
}
```

![Contoh tampilan yang menggunakan property justify-content](https://cdn.hashnode.com/res/hashnode/image/upload/v1658224911746/Pmm1CSr0h.png align="center")

## 6. *Property* `align-items`

Sejak awal kamu pasti sudah menyadari bahwa terdapat ruang kosong pada *card* pertama dan kedua. Ini terjadi karena teks pada *card* ketiga cukup panjang sehingga tinggi *card* pertama dan kedua meregang mengikuti tinggi *card* ketiga.

Bukan hanya itu, jika kita menetapkan *property* `height` pada elemen *container*, maka ruang kosong bisa saja terjadi di semua *card* agar tingginya dapat memenuhi tinggi *container*-nya. Efek ini disebabkan oleh `align-items` yang nilai bawaannya adalah `stretch`.

Beberapa nilai yang bisa kita gunakan untuk menghilangkan efek tersebut, antara lain:

- `flex-start`: Nilai ini akan menempatkan *card* pada batas atas dari *card* lain yang lebih tinggi.
- `flex-end`: Nilai ini akan menempatkan *card* pada batas bawahnya.
- `center`: Nilai ini akan menempatkan *card* di tengahnya.

```css
/* 6. Property align-items */
.align-items {
  align-items: center;
  display: flex;
}
```

![Contoh tampilan yang menggunakan property align-items](https://cdn.hashnode.com/res/hashnode/image/upload/v1658224948763/Ij1nSvgYt.png align="center")

## 7. *Property* `align-content`

`align-content` serupa dengan `justify-content`. Bedanya, ini berlaku vertikal dan hanya bisa digunakan ketika elemen *container* menetapkan `height` dan `flex-wrap` dengan nilai selain `nowrap`.

Beberapa nilai yang perlu diketahui, antara lain:

- `stretch` *(default)*: Nilai ini akan meregangkan tinggi *card* agar memenuhi tinggi elemen *container*.
- `flex-start`: Nilai ini akan menampilkannya di awal berdasarkan nilai dari `flex-direction`. Jika nilainya tidak diubah, maka susunan *card* akan tampil di atas.
- `flex-end`: Nilai ini akan menampilkannya di akhir berdasarkan nilai dari `flex-direction`. Jika nilainya tidak diubah, maka akan tampil di bawah.
- `center`: Nilai ini akan menampilkannya tepat di tengah.
- `space-between`: Nilai ini akan menampilkan baris *card* pertama di awal dan baris *card* terakhir di akhir, lalu membagi ruang yang tersisa untuk baris-baris *card* di antara keduanya.
- `space-around`: Nilai ini akan membagi rata ruang yang tersisa terlebih dahulu kepada setiap baris *card*. Itu sebabnya ruang pada sisi baris *card* awal dan baris *card* akhir yang berbatasan tepi tidak sama dengan ruang antara baris *card*, karena ruang antara baris *card* merupakan gabungan dua ruang.
- `space-evenly`: Nilai ini akan membagi rata ruang yang tersisa baik antara sesama baris *card* maupun antara baris *card* dan tepinya.

```css
/* 7. Property align-content */
.align-content {
  align-content: center;
  display: flex;

   /* Tambahan agar efeknya terlihat */
  flex-wrap: wrap;
  height: 400px;
}
```

![Contoh tampilan yang menggunakan property align-content](https://cdn.hashnode.com/res/hashnode/image/upload/v1658224974525/ZvD2n4bhW.png align="center")

## 8. *Property* `gap`

`gap` akan memberikan jarak di antara *card* yang saling bertemu.

```css
/* 8. Property gap */
.gap {
  display: flex;
  gap: 20px;
}

.gap > .card {
  /* Tambahan agar efeknya terlihat */
  margin: 0;
}
```

![Contoh tampilan yang menggunakan property gap](https://cdn.hashnode.com/res/hashnode/image/upload/v1658225006849/HRdrbcYLM.png align="center")

## 9. *Property* `order`

`order` akan mengatur urutan tampilan *card*. Tidak seperti *property* sebelumnya yang ditambahkan pada elemen *container*, *property* ini (termasuk *property* CSS Flexbox setelah ini) ditambahkan pada elemen *card*.

```css
/* 9. Property order */
.order {
  display: flex;
}

.order > .card:nth-child(1) {
  order: 1;
}
```

![Contoh tampilan yang menggunakan property order](https://cdn.hashnode.com/res/hashnode/image/upload/v1658225051626/QPzBkMM-C.png align="center")

Perlu diingat bahwa semakin besar nilai yang diberikan, maka akan semakin akhir *card* ditampilkan. Jika ada *card* dengan nilai `order` yang sama, maka urutannya akan kembali didasarkan pada urutan penulisan elemennya di berkas HTML.

## 10. *Property* `align-self`

`align-self` serupa dengan `align-items` (termasuk nilai-nilainya). Bedanya, ini hanya untuk mengatur salah satu *card*-nya saja.

```css
/* 10. Property flex-grow */
.align-self {
  display: flex;
}

.align-self > .card:nth-child(2) {
  align-self: center;
}
```

![Contoh tampilan yang menggunakan property align-self](https://cdn.hashnode.com/res/hashnode/image/upload/v1658225077592/4N_nLie7n.png align="center")

## 11. *Property* `flex-grow`

`flex-grow` akan membuat lebar *card* adaptif terhadap ruang kosong yang tersisa di dalam barisnya. Secara bawaan nilai dari *property* ini adalah `0` sehingga lebar *card* tetap mematuhi nilai yang sudah ditetapkan pada *property* `width`-nya.

```css
/* 11. Property flex-grow */
.flex-grow {
  display: flex;
}

.flex-grow > .card:nth-child(2) {
  flex-grow: 1;
}
```

![Contoh tampilan yang menggunakan property flex-grow](https://cdn.hashnode.com/res/hashnode/image/upload/v1658225108304/CkQz1wQmM.png align="center")

## 12. *Property* `flex-shrink`

Pada penjelasan tentang `flex-wrap`, kita sudah melihat bahwa tanpa *property* tersebut beberapa *card* yang baru ditambahkan akan tampil dalam satu baris yang sama, dan ukuran lebarnya akan mengecil untuk menyesuaikan dengan lebar elemen *container*. Efek ini disebabkan oleh `flex-shrink` yang nilai bawaannya adalah `1`.

Jika kita coba ubah nilai *property* ini menjadi `0` dan tidak menggunakan `flex-wrap`, maka efek mengecil tersebut akan hilang dan setelah sejumlah *card* sudah memenuhi lebar elemen *container*, *card-card* selanjutnya akan tembus melewati batasnya.

```css
/* 12. Property flex-shrink */
.flex-shrink {
  display: flex;
}

.flex-shrink > .card {
  flex-shrink: 0;
}
```

![Contoh tampilan yang menggunakan property flex-shrink](https://cdn.hashnode.com/res/hashnode/image/upload/v1658225134614/7fGxK5uhP.png align="center")

## 13. *Property* `flex-basis`

`flex-basis` akan mengatur lebar *card* seperti halnya yang dilakukan `width`. Bedanya, efek dari *property* ini fleksibel tergantung nilai dari `flex-direction` pada elemen *container*, di mana jika diberi nilai `column`, maka `flex-basis` akan mengatur tinggi *card*.

Nilai bawaan dari *property* ini adalah `auto` yang akan merujuk kembali pada nilai `width` dan `height` yang telah ditetapkan.

```css
/* 13. Property flex-basis */
.flex-basis {
  display: flex;
}

.flex-basis > .card:nth-child(2) {
  /* Kode berikut akan mengatur lebar card
  sebesar 50%, kemudian dikurangi 20px
  untuk margin-nya */
  flex-basis: calc(50% - 20px);
}
```

![Contoh tampilan yang menggunakan property flex-basis](https://cdn.hashnode.com/res/hashnode/image/upload/v1658225167023/Oa4Rk8WnP.png align="center")

## 14. *Property* `flex`

`flex` adalah *shorthand* dari penulisan `flex-grow`, `flex-shrink`, dan `flex-basis`. Nilai bawaan dari *property* ini adalah `0 1 auto` yang artinya:

- Nilai pertama (`0`) adalah `flex-grow`
- Nilai kedua (`1`) adalah `flex-shrink`
- Nilai ketiga (`auto`) adalah `flex-basis`

Karena kita sudah membahas tentang ketiga *property* tersebut, dapatkah kamu menciptakan tampilan berikut menggunakan `flex`?

![Contoh tampilan yang menggunakan property flex](https://cdn.hashnode.com/res/hashnode/image/upload/v1658225190871/T11hvEKdX.png align="center")

Berikut adalah kode versi saya:

```css
/* 14. Property flex */
.flex {
  display: flex;
  flex-wrap: wrap;
}

.flex > .card:nth-child(1),
.flex > .card:nth-child(2) {
  flex: 0 0 calc(50% - 20px);
}

.flex > .card:nth-child(3) {
  flex: 0 0 calc(100% - 20px);
}

.flex > .card:nth-child(5) {
  flex: 0 0 calc(75% - 20px);
}

.flex > .card:nth-child(6) {
  flex: 0 0 1700px;
}
```

---

Demikian pembahasan tentang CSS Flexbox ini. Semoga bermanfaat.
