BEM Untuk Pemula: Mengapa Anda Membutuhkan BEM
Diterbitkan: 2022-03-10BEM membuat kode Anda dapat diskalakan dan dapat digunakan kembali, sehingga meningkatkan produktivitas dan memfasilitasi kerja tim. Bahkan jika Anda adalah satu-satunya anggota tim, BEM dapat berguna untuk Anda. Namun demikian, banyak pengembang percaya bahwa pendekatan sistem seperti BEM memberikan batasan tambahan pada proyek mereka dan membuat proyek Anda kelebihan beban, rumit, dan lambat.
Kami akan mengumpulkan semua aspek utama BEM dalam bentuk yang ringkas. Artikel ini membantu Anda memahami ide dasar BEM hanya dalam 20 menit, dan untuk menolak prasangka bahwa pendekatan sistem merugikan proyek Anda.
BEM Besar terdiri dari Metodologi , Teknologi , Perpustakaan , dan Alat . Dalam artikel ini, kita akan berbicara lebih banyak tentang metodologi itu sendiri karena ini adalah pengalaman terkonsentrasi dari sejumlah besar pengembang dan membawa pendekatan sistematis untuk proyek apa pun.
Untuk menunjukkan kepada Anda beberapa kasus praktis BEM, kami akan menyentuh teknologi BEM dan melewatkan perpustakaan dan alat sepenuhnya.
Dari teori ke praktik:
- Alasan Utama Mengapa Kami Tidak Menggunakan Selector Kecuali Kelas
- Dasar-dasar BEM
- Blok Dan Elemen
- Pengubah dan Campuran
- Blok Dalam Struktur File
- Keuntungan Metodologi yang Tidak Jelas
- Kasus Praktis: BEM Tidak Hanya Untuk CSS
- BEM Adalah Sistem yang Dapat Disesuaikan
Jadi, apakah BEM itu pahlawan atau penjahat? Terserah kamu! Tapi baca dulu artikelnya.
Alasan Utama Mengapa Kami Tidak Menggunakan Selector Kecuali Kelas
Salah satu aturan dasar metodologi BEM adalah hanya menggunakan pemilih kelas. Di bagian ini, kami akan menjelaskan alasannya.
- Mengapa kita tidak menggunakan ID?
- Mengapa kita tidak menggunakan pemilih tag?
- Mengapa kita tidak menggunakan pemilih universal?
- Mengapa kita tidak menggunakan reset CSS?
- Mengapa kita tidak menggunakan pemilih bersarang?
- Mengapa kita tidak menggabungkan tag dan kelas dalam pemilih?
- Mengapa kita tidak menggunakan penyeleksi gabungan-
- Mengapa kita tidak menggunakan penyeleksi atribut?
Kami Tidak Menggunakan ID (Pemilih ID)
ID memberikan nama unik untuk elemen HTML. Jika namanya unik, Anda tidak dapat menggunakannya kembali di antarmuka. Ini mencegah Anda menggunakan kembali kode.
Kesalahpahaman Umum
- ID diperlukan untuk menggunakan JavaScript.
Peramban modern dapat bekerja dengan ID atau kelas. Semua jenis pemilih diproses dengan kecepatan yang sama di browser. - ID digunakan dengan tag
<label>
.
Jika Anda menempatkan<label>
di dalam kontrol, itu tidak memerlukan ID. Alih-alih<input id="ID"><label for="ID">Text</label>
, cukup gunakan<label><input type="...">Text</label>
.
Kami Tidak Menggunakan Pemilih Tag
Markup halaman HTML tidak stabil: Desain baru dapat mengubah kumpulan bagian, level heading (misalnya, dari <h1>
ke <h3>
) atau mengubah paragraf <p>
menjadi tag <div>
. Setiap perubahan ini akan merusak gaya yang ditulis untuk tag. Bahkan jika desainnya tidak berubah, set tag terbatas. Untuk menggunakan tata letak yang ada di proyek lain, Anda harus menyelesaikan konflik antara gaya yang ditulis untuk tag yang sama.
Kumpulan tag semantik yang diperluas juga tidak dapat memenuhi semua kebutuhan tata letak.
Contohnya adalah ketika header halaman berisi logo. Sebuah klik pada logo membuka halaman utama situs ( index
). Anda dapat menandainya dengan tag dengan menggunakan tag <img>
untuk gambar dan tag <a>
untuk tautan.
<header> <a href="/"> <img src="img.logo.png" alt="Logo"> </a> </header>
Untuk membedakan antara tautan logo dan tautan biasa dalam teks, Anda memerlukan gaya tambahan. Sekarang hapus garis bawah dan warna biru dari tautan logo:
header a { ... }
Tautan logo tidak perlu ditampilkan di halaman utama, jadi ubah markup halaman indeks:
<header> <!-- the <a> tag is replaced with <span> --> <span> <img src="img.logo.png" alt="Logo"> </span> </header>
Anda tidak perlu menghapus garis bawah dan warna biru untuk tag <span>
. Jadi mari kita buat aturan umum untuk tautan logo dari halaman yang berbeda:
header a, header span { ... }
Sepintas, kode ini tampak baik-baik saja, tetapi bayangkan jika desainer menghapus logo dari tata letak. Nama pemilih tidak membantu Anda memahami gaya mana yang harus dihapus dari proyek dengan logo. Pemilih "tajuk a" tidak menunjukkan hubungan antara tautan dan logo. Pemilih ini bisa menjadi milik tautan di menu header atau, misalnya, ke tautan ke profil penulis. Pemilih "rentang tajuk" dapat dimiliki oleh bagian mana pun dari tajuk.
Untuk menghindari kebingungan, cukup gunakan pemilih kelas logo
untuk menulis gaya logo:
.logo { ... }
Kami Tidak Menggunakan Reset CSS
Reset CSS adalah seperangkat aturan CSS global yang dibuat untuk seluruh halaman. Gaya ini memengaruhi semua node tata letak, melanggar independensi komponen, dan membuatnya lebih sulit untuk digunakan kembali.
Di BEM, "reset" dan "normalisasi" bahkan tidak digunakan untuk satu blok. Penyetelan ulang dan normalisasi membatalkan gaya yang ada dan menggantinya dengan gaya lain, yang harus Anda ubah dan perbarui nanti dalam hal apa pun. Akibatnya, pengembang harus menulis gaya yang menggantikan gaya yang baru saja disetel ulang.
Kami Tidak Menggunakan Pemilih Universal ( *
)
Pemilih universal menunjukkan bahwa proyek memiliki gaya yang memengaruhi semua node dalam tata letak. Ini membatasi penggunaan kembali tata letak di proyek lain:
- Anda juga harus mentransfer gaya dengan tanda bintang ke proyek. Namun dalam kasus ini, pemilih universal mungkin memengaruhi gaya dalam proyek baru.
- Gaya dengan tanda bintang harus ditambahkan ke tata letak yang Anda transfer.
Selain itu, pemilih universal dapat membuat kode proyek tidak dapat diprediksi. Misalnya, ini dapat memengaruhi gaya komponen perpustakaan universal.
Gaya umum tidak menghemat waktu Anda. Seringkali pengembang memulai dengan mengatur ulang semua margin untuk komponen ( * { margin: 0; padding: 0; }
), tetapi kemudian mereka masih mengaturnya sama seperti pada tata letak (misalnya, margin: 12px; padding: 30px;
).
Kami Tidak Menggunakan Selektor Bersarang
Selektor bersarang meningkatkan penggabungan kode dan mempersulit penggunaan kembali kode.
Metodologi BEM tidak melarang pemilih bersarang, tetapi menyarankan untuk tidak menggunakannya terlalu banyak. Misalnya, penyarangan sesuai jika Anda perlu mengubah gaya elemen bergantung pada status blok atau tema yang ditetapkan.
.button_hovered .button__text { text-decoration: underline; } .button_theme_islands .button__text { line-height: 1.5; }
Kami Tidak Menggunakan Selektor Gabungan
Selektor gabungan lebih spesifik daripada selektor tunggal, yang membuatnya lebih sulit untuk mendefinisikan kembali blok.
Perhatikan kode berikut:
<button class="button button_theme_islands">...</button>
Katakanlah Anda menetapkan aturan CSS di pemilih .button.button_theme_islands
untuk melakukan lebih sedikit penulisan. Kemudian Anda menambahkan pengubah "aktif" ke blok:
<button class="button button_theme_islands button_active">...</button>
Pemilih .button_active
tidak mendefinisikan ulang properti blok yang ditulis sebagai .button.button_theme_islands
karena .button.button_theme_islands
lebih spesifik daripada .button_active
. Untuk mendefinisikannya kembali, gabungkan pemilih pengubah blok dengan pemilih .button
dan nyatakan di bawah .button.button_theme_islands
karena kedua penyeleksi sama-sama spesifik:
.button.button_theme_islands {} .button.button_active {}
Jika Anda menggunakan pemilih kelas sederhana, Anda tidak akan mengalami masalah dalam mendefinisikan ulang gaya:
.button_theme_islands {} .button_active {} .button {}
Kami Tidak Menggabungkan Tag Dan Kelas Dalam Pemilih
Menggabungkan tag dan kelas dalam pemilih yang sama (misalnya, button.button
) membuat aturan CSS lebih spesifik, sehingga lebih sulit untuk mendefinisikannya kembali.
Perhatikan kode berikut:
<button class="button">...</button>
Katakanlah Anda menetapkan aturan CSS di pemilih button.button
. Kemudian Anda menambahkan pengubah active
ke blok:
<button class="button button_active">...</button>
Pemilih .button_active
tidak mendefinisikan ulang properti blok yang ditulis sebagai button.button
karena button.button
lebih spesifik daripada .button_active
. Untuk membuatnya lebih spesifik, Anda harus menggabungkan pemilih pengubah blok dengan tag button.button_active
.
Saat proyek berkembang, Anda mungkin mendapatkan blok dengan input.button
, span.button
atau a.button
. Dalam hal ini, semua pengubah blok button
dan semua elemen bersarangnya akan memerlukan empat deklarasi berbeda untuk setiap instance.
Kemungkinan Pengecualian
Dalam kasus yang jarang terjadi, metodologi memungkinkan penggabungan tag dan pemilih kelas. Misalnya, ini dapat digunakan untuk mengatur gaya komentar di sistem CMS yang tidak dapat menghasilkan tata letak yang benar.
Anda dapat menggunakan komentar untuk menulis teks, menyisipkan gambar, atau menambahkan markup. Untuk membuatnya cocok dengan desain situs, pengembang dapat menentukan gaya sebelumnya untuk semua tag yang tersedia bagi pengguna dan menurunkannya ke blok bersarang:
<div class="content"> ... <!-- the user's text --> </div> CSS rules: .content a { ... } .content p { font-family: Arial, sans-serif; text-align: center; }
Kami Tidak Menggunakan Pemilih Atribut
Selektor atribut kurang informatif daripada selektor kelas. Sebagai bukti, pertimbangkan contoh dengan formulir pencarian di header:
<header> <form action="/"> <input name="s"> <input type="submit"> </form> </header>
Coba gunakan atribut pemilih untuk menulis gaya formulir:
header input[type=submit], header input[type=checkbox] { width: auto; margin-right: 20px; } header input[type=checkbox] { margin: 0; }
Dalam contoh ini, Anda tidak dapat mengetahui dengan pasti dari nama pemilih bahwa gaya tersebut termasuk dalam formulir pencarian. Menggunakan kelas membuatnya lebih jelas. Kelas tidak memiliki batasan yang mencegah Anda menulis dengan jelas. Misalnya, Anda dapat menulisnya seperti ini:
.form .search { ... }
Sekarang kodenya kurang ambigu, dan jelas bahwa gaya termasuk dalam formulir pencarian.
Tetapi pemilih bersarang masih membuat aturan CSS lebih spesifik dan mencegah Anda mentransfer tata letak antar proyek. Untuk menghilangkan sarang, gunakan prinsip BEM.
Ringkasan : class
adalah satu-satunya pemilih yang memungkinkan Anda untuk mengisolasi gaya setiap komponen dalam proyek; meningkatkan keterbacaan kode dan tidak membatasi penggunaan ulang tata letak.
Isolasi gaya CSS adalah titik awal paling sering dari perjalanan BEM. Namun hanya ini yang bisa diberikan BEM kepada Anda. Untuk memahami bagaimana komponen independen yang terisolasi diatur dalam BEM, Anda perlu mempelajari konsep dasar, yaitu Blok, Elemen, Pengubah, dan Campuran. Mari kita lakukan ini di bagian selanjutnya.
Dasar-dasar BEM
- Blok Dan Elemen
- Pengubah dan Campuran
- Blok Dalam Struktur File
Blok Dan Elemen
Metodologi BEM adalah seperangkat aturan universal yang dapat diterapkan terlepas dari teknologi yang digunakan, seperti CSS, Sass, HTML, JavaScript atau React.
BEM membantu menyelesaikan tugas-tugas berikut:
- Gunakan kembali tata letak;
- Pindahkan fragmen tata letak di dalam proyek dengan aman;
- Pindahkan tata letak yang sudah jadi di antara proyek;
- Buat kode yang stabil, dapat diprediksi, dan jelas;
- Kurangi waktu debugging proyek.
Dalam proyek BEM, antarmuka terdiri dari blok yang dapat menyertakan elemen. Blok adalah komponen independen dari halaman. Sebuah elemen tidak dapat berada di luar blok, jadi ingatlah bahwa setiap elemen hanya dapat dimiliki oleh satu blok.
Dua huruf pertama dalam BEM adalah singkatan dari kunci B dan elemen E. Nama blok selalu unik. Ini mengatur namespace untuk elemen dan menyediakan koneksi yang terlihat antara bagian-bagian blok. Nama blok panjang tetapi jelas untuk menunjukkan hubungan antar komponen dan untuk menghindari kehilangan bagian apa pun dari komponen ini saat mentransfer tata letak.
Untuk melihat kekuatan penuh penamaan BEM, pertimbangkan contoh ini dengan formulir. Menurut metodologi BEM, formulir diimplementasikan menggunakan blok form
. Dalam HTML, nama blok disertakan dalam atribut class
:
<form class="form" action="/">
Semua bagian formulir (blok form
) yang tidak masuk akal dengan sendirinya dianggap sebagai elemennya. Jadi kotak pencarian ( search
) dan tombol ( submit
) adalah elemen dari blok form
. Kelas juga menunjukkan bahwa elemen milik blok:
<form class="form" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>
Perhatikan bahwa nama blok dipisahkan dari nama elemen dengan pemisah khusus. Dalam skema penamaan klasik BEM, dua garis bawah digunakan sebagai pemisah. Apa pun bisa berfungsi sebagai pemisah. Ada konvensi penamaan alternatif, dan setiap pengembang memilih salah satu yang cocok untuk mereka. Yang penting adalah bahwa pemisah memungkinkan Anda untuk membedakan blok dari elemen dan pengubah secara terprogram.
Nama pemilih memperjelas bahwa untuk memindahkan formulir ke proyek lain, Anda perlu menyalin semua komponennya:
.form__search {} .form__submit {}
Menggunakan blok dan elemen untuk nama kelas memecahkan masalah penting: Ini membantu kita menyingkirkan pemilih bersarang. Semua selektor dalam proyek BEM memiliki bobot yang sama. Itu berarti lebih mudah untuk mendefinisikan ulang gaya yang ditulis menurut BEM. Sekarang, untuk menggunakan formulir yang sama di proyek lain, Anda cukup menyalin tata letak dan gayanya.
Ide penamaan komponen BEM adalah Anda dapat secara eksplisit mendefinisikan hubungan antara blok dan elemen-elemennya.
Pengubah dan Campuran
Secara resmi, " M " adalah singkatan dari Modifier, tetapi juga menyiratkan satu gagasan penting lagi dalam BEM: "campuran". Baik pengubah dan campuran membuat perubahan pada blok dan elemennya. Mari kita lihat lebih dekat ini.
pengubah
Pengubah mendefinisikan tampilan, status, dan perilaku blok atau elemen. Menambahkan pengubah adalah opsional. Pengubah memungkinkan Anda menggabungkan fitur blok yang berbeda, karena Anda dapat menggunakan sejumlah pengubah. Tetapi blok atau elemen tidak dapat diberi nilai yang berbeda dari pengubah yang sama.
Mari kita jelajahi cara kerja pengubah.
Bayangkan proyek membutuhkan formulir pencarian yang sama seperti pada contoh di atas. Seharusnya memiliki fungsi yang sama tetapi terlihat berbeda (misalnya, formulir pencarian di header dan footer halaman harus berbeda). Hal pertama yang dapat Anda lakukan untuk mengubah tampilan formulir adalah dengan menulis gaya tambahan:
header .form {} footer .form {}
header .form
selector memiliki bobot lebih dari form
selector, yang berarti bahwa satu aturan akan menimpa aturan lainnya. Tetapi seperti yang telah kita diskusikan, pemilih bersarang meningkatkan penggabungan kode dan mempersulit penggunaan kembali, jadi pendekatan ini tidak berhasil untuk kita.
Di BEM, Anda dapat menggunakan pengubah untuk menambahkan gaya baru ke blok:
<!-- Added the form_type_original modifier--> <form class="form form_type_original" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>
Baris <form class="form form_type_original"></form>
menunjukkan bahwa blok diberi pengubah type
dengan nilai original
. Dalam skema klasik, nama pengubah dipisahkan dari blok atau nama elemen dengan garis bawah.
Bentuknya bisa memiliki warna, ukuran, jenis, atau tema desain yang unik. Semua parameter ini dapat diatur dengan pengubah:
<form class="form form_type_original form_size_m form_theme_forest">
<form class="form form_type_original form_size_m form_theme_forest">
Bentuk yang sama dapat terlihat berbeda tetapi tetap dengan ukuran yang sama:
<form class="form form_type_original form_size_m form_theme_forest"></form> <form class="form form_type_original form_size_m form_theme_sun"></form>
Tetapi penyeleksi untuk setiap pengubah akan tetap memiliki bobot yang sama:
.form_type_original {} .form_size_m {} .form_theme_forest {}
Penting : Pengubah hanya berisi gaya tambahan yang mengubah implementasi blok asli dalam beberapa cara. Ini memungkinkan Anda untuk mengatur tampilan blok universal hanya sekali, dan menambahkan hanya fitur-fitur yang berbeda dari kode blok asli ke dalam gaya pengubah.
.form { /* universal block styles */ } .form_type_original { /* added styles */ }
Inilah sebabnya mengapa pengubah harus selalu berada di simpul DOM yang sama dengan blok dan elemen yang terkait dengannya.
<form class="form form_type_original"></form>
Anda dapat menggunakan pengubah untuk menerapkan komponen universal dalam kasus yang sangat spesifik. Kode blok dan elemen tidak berubah. Kombinasi pengubah yang diperlukan dibuat pada simpul DOM.
Campuran
Campuran memungkinkan Anda untuk menerapkan pemformatan yang sama ke elemen HTML yang berbeda dan menggabungkan perilaku dan gaya beberapa entitas sambil menghindari duplikasi kode. Mereka dapat mengganti blok pembungkus abstrak.
Campuran berarti Anda meng-host beberapa entitas BEM (blok, elemen, pengubah) pada satu simpul DOM. Mirip dengan pengubah, campuran digunakan untuk mengubah blok. Mari kita lihat beberapa contoh kapan Anda harus menggunakan campuran.
Blok dapat berbeda tidak hanya secara visual tetapi juga secara semantik. Misalnya formulir pencarian, formulir pendaftaran, dan formulir pemesanan kue semuanya adalah formulir. Dalam tata letak, mereka diimplementasikan dengan blok "form" tetapi mereka tidak memiliki gaya yang sama. Tidak mungkin menangani perbedaan seperti itu dengan pengubah. Anda dapat menentukan gaya umum untuk blok tersebut tetapi Anda tidak akan dapat menggunakan kembali kode tersebut.
.form, .search, .register { ... }
Anda dapat menggunakan campuran untuk membuat blok yang berbeda secara semantik untuk bentuk yang sama:
<form class="form" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>
Pemilih kelas .form
menjelaskan semua gaya yang dapat diterapkan ke formulir apa pun (pesanan, pencarian, atau pendaftaran):
.form {}
Sekarang Anda dapat membuat formulir pencarian dari formulir universal. Untuk melakukan ini, buat kelas search
tambahan di proyek. Kelas ini hanya akan bertanggung jawab untuk pencarian. Untuk menggabungkan gaya dan perilaku kelas .form
dan .search
, tempatkan kelas ini pada satu simpul DOM:
<form class="form search" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>
Dalam hal ini, kelas .search
adalah blok terpisah yang mendefinisikan perilaku. Blok ini tidak dapat memiliki pengubah yang bertanggung jawab atas bentuk, tema, dan ukuran. Pengubah ini sudah termasuk dalam bentuk universal. Campuran membantu menggabungkan gaya dan perilaku blok ini.
Mari kita ambil satu contoh lagi di mana semantik komponen diubah. Berikut adalah menu navigasi di header halaman di mana semua entri adalah tautan:
<nav class="menu"> <a class="link" href=""></a> <a class="link" href=""></a> <a class="link" href=""></a> </nav>
Fungsi tautan sudah diterapkan di blok link
, tetapi tautan menu harus berbeda secara visual dari tautan dalam teks. Ada beberapa cara untuk mengubah tautan menu:
- Buat pengubah entri menu yang mengubah entri menjadi tautan:
<nav class="menu"> <a class="menu__item menu__item_link" href=""></a> <a class="menu__item menu__item_link" href=""></a> <a class="menu__item menu__item_link" href=""></a> </nav>
Dalam hal ini, untuk mengimplementasikan pengubah, Anda harus menyalin perilaku dan gaya blok `link`. Ini akan menyebabkan duplikasi kode. - Gunakan campuran blok universal `link` dan elemen `item` dari blok `menu`:
<nav class="menu"> <a class="link menu__item" href=""></a> <a class="link menu__item" href=""></a> <a class="link menu__item" href=""></a> </nav>
Dengan gabungan dua entitas BEM, kini Anda dapat menerapkan fungsionalitas tautan dasar dari blok `link` dan aturan CSS tambahan dari blok `menu`, dan menghindari duplikasi kode.
Geometri dan Pemosisian Eksternal: Menyerahkan Pembungkus HTML Abstrak
Campuran digunakan untuk memposisikan blok relatif terhadap blok lain atau untuk memposisikan elemen di dalam blok. Di BEM, gaya yang bertanggung jawab untuk geometri dan pemosisian diatur di blok induk. Mari kita ambil blok menu universal yang harus ditempatkan di header. Dalam tata letak, blok harus memiliki indentasi 20px dari blok induk.
Tugas ini memiliki beberapa solusi:
- Tulis gaya dengan indentasi untuk blok menu:
.menu { margin-left: 20px; }
Dalam hal ini, blok "menu" tidak universal lagi. Jika Anda harus menempatkan menu di footer halaman, Anda harus mengedit gaya karena indentasinya mungkin akan berbeda. - Buat pengubah blok menu:
<div> <ul class="menu menu_type_header"> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> </ul> </div>
.menu_type_header { margin-left: 20px; } .menu_type_footer { margin-left: 30px; }
Dalam hal ini, proyek akan menyertakan dua jenis menu, meskipun tidak demikian. Menunya tetap sama. - Tentukan posisi eksternal blok: susun blok `menu` di pembungkus abstrak (misalnya, blok `wrap`) dengan menyetel semua indentasi:
<div class="wrap"> <ul class="menu"> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> </ul> </div>
Untuk menghindari godaan untuk membuat pengubah dan mengubah gaya blok untuk memposisikan blok pada halaman, Anda perlu memahami satu hal:Indentasi dari blok induk bukan merupakan fitur blok bersarang. Ini adalah fitur dari blok induk. Itu harus tahu bahwa blok bersarang harus diindentasi dari perbatasan dengan sejumlah piksel.
- Gunakan campuran. Informasi tentang pemosisian blok bersarang disertakan dalam elemen blok induk. Kemudian elemen blok induk dicampur ke dalam blok bersarang. Dalam hal ini, blok bersarang tidak menentukan indentasi apa pun dan dapat dengan mudah digunakan kembali di tempat mana pun.
Mari kita lanjutkan dengan contoh kita:
<div> <ul class="menu header__menu"> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> </ul> </div>
Dalam hal ini, geometri eksternal dan posisi blok menu
diatur melalui elemen header__menu
. Blok menu
tidak menentukan indentasi apa pun dan dapat dengan mudah digunakan kembali.
Elemen blok induk (dalam kasus kami ini adalah header__menu
) melakukan tugas blok pembungkus yang bertanggung jawab untuk pemosisian eksternal blok.
Blok Dalam Struktur File
Semua proyek BEM memiliki struktur file yang serupa. Struktur file yang familier memudahkan pengembang untuk menavigasi proyek, beralih antar proyek, dan memindahkan blok dari satu proyek ke proyek lainnya.
Pelaksanaan setiap blok disimpan dalam folder proyek terpisah. Setiap teknologi (CSS, JavaScript, tes, template, dokumentasi, gambar) berada dalam file terpisah.
Misalnya, jika tampilan blok input
diatur dengan CSS, kode disimpan dalam file input.css
.
project common.blocks/ input/ input.css # The "input" block implementation with CSS input.js # The "input" block implementation with JavaScript
Kode untuk pengubah dan elemen juga disimpan dalam file blok yang terpisah. Pendekatan ini memungkinkan Anda untuk memasukkan dalam build hanya pengubah dan elemen yang diperlukan untuk implementasi blok.
project common.blocks/ input/ input.css # The "input" block implementation with CSS input.js # The "input" block implementation with JavaScript input_theme_sun.css # The "input_theme_sun" modifier implementation input__clear.css # The "input__clear" element implementation with CSS input__clear.js # The "input__clear" element implementation with JavaScript
Untuk meningkatkan navigasi proyek, gabungkan pengubah blok dengan beberapa nilai dalam direktori.
Struktur file dari setiap proyek BEM terdiri dari level redefinisi (Anda dapat mempelajarinya lebih lanjut di sini). Level redefinisi memungkinkan Anda untuk:
- Bagi proyek ke dalam platform;
- Perbarui pustaka blok yang disertakan dalam proyek dengan mudah;
- Gunakan blok umum untuk mengembangkan banyak proyek;
- Ubah tema desain tanpa mempengaruhi logika proyek;
- Lakukan eksperimen dalam proyek langsung.
Menggunakan blok dan menyimpan semua teknologi blok dalam folder yang sama memudahkan pemindahan blok antar proyek. Untuk memindahkan semua gaya dan perilaku blok bersama dengan tata letak, cukup salin folder blok ke proyek baru.
Keuntungan Metodologi yang Tidak Jelas
Kenyamanan Pengembangan Paralel
Di BEM, tata letak apa pun dibagi menjadi beberapa blok. Karena blok independen, mereka dapat dikembangkan secara paralel oleh beberapa pengembang.
Pengembang membuat blok sebagai komponen universal yang dapat digunakan kembali di proyek lain.
Contohnya adalah perpustakaan blok komponen-bem, yang berisi blok universal, seperti tautan, tombol, dan bidang input. Lebih mudah untuk membuat blok yang lebih kompleks dari komponen universal. Misalnya, pemilih atau kotak centang.
Menggunakan blok dalam tata letak proyek membantu Anda menghemat waktu dalam mengintegrasikan kode yang ditulis oleh beberapa pengembang, menjamin keunikan nama komponen, dan memungkinkan Anda menguji blok pada tahap pengembangan.
Menguji Tata Letak
Ini bermasalah untuk menguji fungsionalitas seluruh halaman, terutama dalam proyek dinamis yang terhubung ke database.
Dalam BEM, setiap blok dicakup oleh tes. Pengujian adalah teknologi implementasi blok, seperti Javascript atau CSS. Blok diuji pada tahap pengembangan. Lebih mudah untuk memeriksa kebenaran satu blok dan kemudian merakit proyek dari blok yang diuji. Setelah itu, yang harus Anda lakukan adalah memastikan bahwa pembungkus blok berfungsi dengan benar.
Bangun Proyek yang Dapat Disesuaikan
Untuk pengembangan yang nyaman, semua blok dan teknologi dalam proyek BEM ditempatkan di folder dan file terpisah. Untuk menggabungkan file sumber menjadi satu file (misalnya, untuk meletakkan semua file CSS di project.css
, semua file JS di project.js
, dan seterusnya), kami menggunakan proses build.
Build melakukan tugas-tugas berikut:
- Menggabungkan file sumber yang tersebar di seluruh sistem file proyek;
- Hanya menyertakan blok, elemen, dan pengubah yang diperlukan (entitas BEM) dalam proyek;
- Mengikuti urutan untuk memasukkan entitas;
- Memproses kode file sumber selama pembuatan (misalnya mengkompilasi kode KURANG ke kode CSS).
Untuk menyertakan hanya entitas BEM yang diperlukan dalam build, Anda perlu membuat daftar blok, elemen, dan pengubah yang digunakan pada halaman. Daftar ini disebut deklarasi .
Karena blok BEM dikembangkan secara independen dan ditempatkan di file terpisah dalam sistem file, mereka tidak 'tahu' apa pun tentang satu sama lain. Untuk membangun blok berdasarkan blok lain, tentukan dependensi. Ada teknologi BEM yang bertanggung jawab untuk ini: file deps.js
File dependensi memberi tahu mesin pembuat blok tambahan mana yang harus disertakan dalam proyek.
Kasus Praktis: BEM Tidak Hanya Untuk CSS
Di bagian sebelumnya, semua contoh kode adalah untuk CSS. Tetapi BEM memungkinkan Anda untuk mengubah perilaku blok dan representasinya dalam HTML dengan cara deklaratif yang sama seperti di CSS.
Cara Menggunakan Templat Di BEM
Dalam HTML, markup blok diulang setiap kali blok muncul di halaman. Jika Anda membuat markup HTML secara manual dan kemudian perlu memperbaiki kesalahan atau membuat perubahan, Anda perlu memodifikasi markup untuk setiap instance blok. Untuk menghasilkan kode HTML dan menerapkan perbaikan secara otomatis, BEM menggunakan template; blok bertanggung jawab atas cara mereka disajikan dalam HTML.
Template memungkinkan Anda untuk:
- Kurangi waktu yang digunakan untuk debugging proyek, karena perubahan template secara otomatis diterapkan ke semua blok proyek;
- Ubah tata letak blok;
- Pindahkan blok dengan tata letak saat ini ke proyek lain.
BEM menggunakan mesin template bem-xjst yang memiliki dua mesin:
- BEMHTML
Mengubah deskripsi BEMJSON halaman menjadi HTML. Template dijelaskan dalam file .bemhtml.js. - BEMTREE
Mengubah data menjadi BEMJSON. Template dijelaskan dalam format BEMJSON dalam file .bemtree.js .
Jika templat tidak ditulis untuk blok, mesin templat menyetel tag <div>
untuk blok secara default.
Bandingkan deklarasi blok dan output HTML:
Pernyataan:
{ block: 'menu', content: [ { elem: 'item', content: { block: 'link'} }, { elem: 'item', elemMods: { current: true }, // Set the modifier for the menu item content: { block: 'link' } } ] }
HTML:
<div class="menu"> <div class="menu__item"> <div class="link"></div> </div> <div class="menu__item menu__item_current"> <div class="link"></div> </div> </div>
Untuk mengubah tata letak blok menu
, Anda perlu menulis template untuk blok:
- Mari kita ubah tag blok
menu
:block('menu')( tag()('menu') // Set the "menu" tag for the menu block )
HTML yang dimodifikasi:<menu class="menu"> <!-- Replace the "div" tag with the "menu" tag for the "menu" block --> <div class="menu__item"> <div class="link"></div> </div> <div class="menu__item menu__item_current"> <div class="link"></div> </div> </menu>
Mirip dengan CSS, template diterapkan ke semua blok "menu" di halaman. - Tambahkan elemen tambahan (
menu__inner
) yang berfungsi sebagai pembungkus bagian dalam dan bertanggung jawab atas tata letak elemen di blokmenu
. Awalnya elemenmenu__inner
tidak disertakan dalam deklarasi, jadi kita harus menambahkannya saat template dibuat.
Template BEM ditulis dalam JavaScript, jadi Anda juga dapat menggunakan JavaScript untuk menambahkan elemen baru ke template:block('menu')( tag()('menu'), content()(function() { return { elem: 'inner', content: this.ctx.content }; }) )
<menu class="menu"> <!-- Replace the "div" tag with the "menu" tag for the "menu" block --> <div class="menu__inner"> <div class="menu__item"> <div class="link"></div> </div> <div class="menu__item menu__item_current"> <div class="link"></div> </div> </div> </menu>
- Ganti tag untuk semua elemen
inner
danitem
:block('menu')( tag()('menu'), content()(function() { return { elem: 'inner', content: this.ctx.content } }), elem('inner')( tag()('ul') ), elem('item')( tag()('li') ) )
<menu class="menu"> <ul class="menu__inner"> <li class="menu__item"> <div class="link"></div> </li> <li class="menu__item menu__item_current"> <div class="link"></div> </li> </ul> </menu>
- Setel tag
<a>
untuk semua tautan di halaman:block('menu')( tag()('menu'), content()(function() { return { elem: 'inner', content: this.ctx.content } }), elem('inner')( tag()('ul') ), elem('item')( tag()('li') ) ); block('link')( tag()('a') );
<menu class="menu"> <ul class="menu__inner"> <li class="menu__item"> <a class="link"></a> </li> <li class="menu__item menu__item_current"> <a class="link"></a> </li> </ul> </menu>
- Ubah template yang ada. Aturan dalam template diterapkan dengan cara yang sama seperti di CSS: aturan yang lebih rendah menimpa aturan yang lebih tinggi. Tambahkan aturan baru ke template, dan ubah tag tautan dari
<a>
menjadi<span>
:block('link')( tag()('a') ); block('link')( tag()('span') );
<menu class="menu"> <ul class="menu__inner"> <li class="menu__item"> <span class="link"></span> </li> <li class="menu__item menu__item_current"> <span class="link"></span> </li> </ul> </menu>
BEM Adalah Sistem yang Dapat Disesuaikan
Metodologi BEM memberi Anda aturan ketat untuk membuat sistem di proyek Anda. Tetapi pada saat yang sama, banyak aturan BEM dapat disesuaikan. Metodologi BEM memungkinkan Anda untuk mengubah konvensi penamaan, memilih struktur file yang paling nyaman atau menambahkan teknologi apa pun yang ingin Anda blokir.
Sekarang Anda dapat menyetel sistem dan membuat superhero BEM Anda sendiri!
Bagaimana Mendapatkan Lebih Banyak Dari BEM
Untuk mulai mempelajari prinsip-prinsip BEM, kunjungi situs web kami. Jika Anda memiliki pertanyaan yang ingin Anda ajukan kepada tim, bergabunglah dengan saluran Telegram kami atau buka diskusi di Forum BEM kami.