RTL Styling 101 - Panduan terperinci untuk gaya CSS RTL



Terjemahan " RTL Styling 101 - Panduan lengkap tentang cara mendesain RTL di CSS " oleh Ahmad Shadid.

Lebih dari 292 juta orang di seluruh dunia berbicara bahasa Arab sebagai bahasa ibu mereka. Saya milik mereka, jadi saya kadang-kadang mengembangkan situs yang harus mendukung kedua arah penulisan teks: dari kiri ke kanan (LTR - Kiri ke Kanan) dan dari kanan ke kiri (Kanan Ke Kiri).

Pengantar Styling RTL


CSS menggunakan arah LTR secara default. Jika Anda memeriksa gaya peramban untuk elemen html, Anda akan melihat bahwa untuk properti dir (atau "direction"), nilai ltr adalah nilai default. Berikut ini adalah contoh dasar untuk menunjukkan perbedaan antara markup LTR dan RTL.



Perhatikan blok RTL - tidak seperti LTR, teks di dalamnya dibaca dari kanan ke kiri. Dalam contoh sederhana ini, browser menampilkannya dengan benar. Untuk mengubah arah bahasa dokumen, Anda perlu menambahkan atribut dir ke elemen root.

<html dir="rtl">...</html> 

Ketika nilai dir berubah, maka semua elemen bersarang harus secara otomatis beralih berikutnya: pos, paragraf, tautan, gambar, dan formulir.

Perlu juga disebutkan bahwa atribut dir dapat diatur ke "auto", yang secara otomatis akan mengubah arah elemen berdasarkan analisis kontennya. Menurut spesifikasi HTML:
Penulis mendesak nilai ini untuk digunakan hanya sebagai upaya terakhir, ketika arah teks benar-benar tidak diketahui dan tidak ada cara untuk secara efektif menentukan ini di sisi server.


Selain mengatur atribut dir = rtl untuk elemen HTML, kami juga dapat menambahkan arah: rtl sebagai gaya CSS.

 .element { direction: rtl; } 

Namun, CSSWG (kelompok kerja CSS) merekomendasikan mendefinisikan arah dengan tepat sebagai atribut untuk elemen root HTML untuk memastikan bahwa markup sudah benar, terlepas dari apakah CSS ada atau tidak.

Contoh mengubah arah penandaan


Mari kita lihat contoh yang lebih rinci untuk lebih memahami bagaimana mengubah arah penandaan dari LTR ke RTL.



 <article class="media"> <img class="media__photo" src="blueberry-cheesecake.jpg" alt=""> <div class="media__content"> <h2>Blueberry Cheesecake</h2> <p>...</p> <p><a href="#" class="link">View Recipe</a></p> </div> </article> 

Awalnya, saya menggunakan float lama yang bagus untuk membenarkan-kiri gambar di markup LTR dan, tentu saja, menerapkan clearfix.

 .media:after { content: ""; display: block; clear: both; } .media img { float: left; width: 200px; margin-right: 16px; } 

Kemudian kami menambahkan dir = "rtl" untuk elemen yang mengandung teks Arab. Hasil berikut diperoleh:



Semua elemen disejajarkan di sisi kanan, kecuali untuk gambar. Ini terjadi karena properti gambar diatur ke float: left dan margin-right: 16px. Untuk memperbaikinya, ganti gaya berikut

 .media[dir="rtl"] img { float: right; margin-right: 0; margin-left: 16px; } 


Konten bahasa Inggris dan Arab di tata letak LTR


Apa yang terjadi jika beberapa teks memiliki campuran kata-kata bahasa Inggris dan Arab, dan markupnya ada di arah LTR? Hasilnya aneh



Browser tidak akan menampilkan judul dengan benar. Penutur bahasa Arab akan membingungkan. Kata-kata dalam judul ini harus dalam urutan yang ditunjukkan pada gambar di bawah ini. Mulai dari kanan.



Untuk menghindari masalah ini, atur arah bahasa yang sesuai jika memungkinkan. Jika elemen diatur ke atribut dir = "rtl", itu akan ditampilkan seperti yang diharapkan.




Situasi mungkin menjadi lebih rumit jika judulnya panjang. Di bawah ini saya menambahkan sedikit dan hasilnya tidak terduga. Saya menunjukkan nomor dengan urutan yang benar. Sekali lagi, mulai dari kanan.



Ketika atribut dir = "rtl" disetel untuk elemen, judul menjadi benar. Artinya, kalimatnya terlihat benar secara tata bahasa, dan kata-katanya diatur dalam urutan yang benar.




Flexbox


Flexbox pada dasarnya memperhitungkan mode penulisan yang diatur dalam dokumen. Faktor ini digunakan untuk menentukan bagaimana blok akan berbaris di halaman secara default. Misalnya, di situs berbahasa Inggris mereka akan bergerak dari kiri ke kanan, dan dalam bahasa Cina dari atas ke bawah. Untuk bahasa Inggris dan Arab, properti mode penulisan default adalah horizontal-tb.

Menurut Mozilla Developer Network (MDN), nilai tb horizontal berarti yang berikut:

Konten diposisikan secara horizontal dari kiri ke kanan, secara vertikal dari atas ke bawah. Garis horizontal berikutnya di bawah yang sebelumnya.

Ketika arah halaman berubah menjadi RTL, flexbox secara tepat memperluas aliran elemen-elemennya. Ini adalah keuntungan besar! Gambar di bawah ini menunjukkan bagaimana sumbu flexbox berputar, tergantung pada nilai properti arah.



Dalam contoh di bawah ini, saya membuat tiga elemen dan memberi nomor untuk menunjukkan perbedaan ketika mengubah arah halaman.

 <div class="element"> <div class="item"^_^gt lt^_^/div> <div class="item"^_^gt lt^_^/div> <div class="item"^_^gt lt^_^/div> </div> 

 .element { display: flex; flex-direction: row; /* Default value, added for clarity */ } 





Kotak CSS


Seperti flexbox, css grid tergantung pada mode penulisan dokumen, yang memberi kita keuntungan yang sama seperti ketika menggunakan flexbox.

Pada contoh di bawah ini, untuk arah LTR, bilah sisi harus di sebelah kiri dan utama di sebelah kanan. Untuk RTL, yang terjadi adalah sebaliknya. Ketika kami menggunakan CSS Grid, pembangunan kembali ini akan dilakukan secara otomatis sesuai dengan arahan yang ditetapkan pada halaman ini.

 <div class="element"> <div class="side">Side</div> <div class="main">Main</div> </div> 

 .element { display: grid; grid-template-columns: 220px 1fr; grid-gap: 1rem; } 


Kesalahan utama saat beralih ke arah RTL


Pengembang non-Arab membuat kesalahan umum yang langsung terlihat oleh penutur asli.

1. Penspasian surat


Dalam bahasa Inggris, adalah umum untuk menggunakan properti penspasian huruf untuk mengontrol penspasian huruf dalam sebuah kata. Pertimbangkan contoh berikut dengan konten dalam bahasa Inggris. Terlihat sangat normal.



Namun, jika Anda menambahkan spasi huruf yang sama ke teks Arab, itu akan terlihat sangat aneh. Pertimbangkan contoh kehidupan nyata berikut ini.



Perhatikan bahwa dalam teks yang menerapkan properti penspasian huruf, huruf setiap kata dipisahkan satu sama lain. Ini salah. Huruf Arab harus terlihat terhubung, dan menjaga jarak huruf yang sama seperti dalam bahasa Inggris mencegah hal ini. Pastikan bahwa ketika bekerja dengan situs multibahasa, jangan lupa untuk mengatur properti penspasian surat: 0 di tempat yang tepat.



2. Transparansi teks


Dalam desain situs web, teks sering dibuat transparan. Misalnya, untuk menandai kepentingan sekundernya. Ini berfungsi untuk Bahasa Inggris. Namun, jika konten dalam bahasa Arab, masalah mungkin timbul karena cara rendering teks yang aneh.



Tempat muncul di mana warna garis karakter berubah karena tumpang tindih mereka. Dalam contoh ini, properti penspasian surat tidak disetel, sehingga tidak memengaruhi masalah. Solusinya adalah mengatur warna tanpa tembus cahaya (yang biasanya diatur melalui RGBa atau opacity).


3. Perbedaan ukuran kata dalam berbagai bahasa


Terkadang, ketika situs diterjemahkan ke dalam bahasa Arab, ukuran elemen berubah karena fakta bahwa beberapa kata setelah terjemahan menjadi lebih besar atau lebih kecil. Perhatikan contoh berikut, di mana saya mensimulasikan navigasi situs Majalah Smashing.



Dalam versi bahasa Arab, beberapa kata hampir sama ukurannya dengan versi bahasa Inggris mereka, beberapa persis sama, dan beberapa lebih besar. Untuk membuatnya lebih jelas, berikut ini adalah perbandingan dari setiap kata dan terjemahan bahasa Arabnya.



Anda mungkin bertanya-tanya mengapa saya berbicara tentang perbedaan ukuran kata dalam berbagai bahasa, karena ini normal dan diharapkan. Pertimbangkan contoh LinkedIn di dunia nyata berikut ini.



Tombol "Selesai" diterjemahkan ke dalam bahasa Arab sebagai "تم", itulah sebabnya ia menjadi sangat kecil dan umumnya terlihat aneh. Khusus untuk kasus seperti itu, akan lebih baik untuk mengatur properti min-width untuk tombol. Saya menambahkannya melalui panel pengembang untuk menunjukkan bagaimana tampilannya:



Berikut adalah contoh yang sangat mirip dari Twitter:



Harap dicatat bahwa masalah di atas dengan LinkedIn dan Twitter ditemukan pada saat penulisan (13 Desember 2019).

4. Pemotongan teks


Saya pernah bekerja pada proyek multibahasa dan mengalami masalah terkait dengan memotong teks ke arah yang salah. Perhatikan contoh berikut.



Pemotongan untuk teks bahasa Inggris salah. Ini harus terjadi di akhir elemen, bukan di awal. Untuk mengatasi masalah ini, Anda perlu mengatur atribut dir = "auto" untuk elemen ini, dan kemudian browser akan secara otomatis menganalisis konten dan memutuskan nilai dir yang akan diterapkan.

 <p dir="auto">أهلاً وسهلاً بكم في المقال الذي يتحدث عن تصميم صفحات الويب للغة العربية</p> <p dir="auto">Welcome to the article that explains how to design for RTL pages.</p> 





5. Memilih font RTL yang buruk


Kehadiran versi RTL situs tidak berarti bahwa Anda dapat membatasi diri untuk menentukan font sistem yang diinstal oleh pengguna secara default. Anda perlu menganggap ini serius untuk memastikan keterbacaan yang baik. Contoh memilih font yang gagal adalah Twitter:



Dari sudut pandang berbahasa Arab, kata "تغريد" sulit dibaca karena beberapa alasan:
  • font yang tidak terlalu bagus
  • kegemukan merusak keterbacaan
  • titik-titik kata sangat kecil dan terlalu dekat dengan huruf


Saya memberikan beberapa contoh yang terlihat jauh lebih jelas:



6. Mencampur Angka Hindi dan Arab


Dalam bahasa Arab, ada dua cara untuk menulis angka:
  • Bahasa Hindi: ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩
  • Bahasa Arab: 0 1 2 3 4 5 6 7 8 9

Angka-angka yang digunakan dalam bahasa Inggris diwarisi dari bahasa Arab: “0, 1, 2, 3, 4, 5, 6, 7, 8, 9”. Teks yang berisi angka harus cocok dengan hanya satu dari dua opsi: baik Hindi atau Arab.

Menurut Wikipedia:
Alasan bahwa di Eropa dan Amerika jumlahnya disebut "Arab" adalah karena mereka diperkenalkan di Eropa pada abad ke-10 oleh orang-orang berbahasa Arab dari Afrika Utara.

Contoh berikut berisi campuran angka Hindi dan Arab. Pendekatan ini tampaknya tidak konsisten dan gaya tunggal harus digunakan sebagai gantinya.



Momen yang mungkin tidak bekerja dengan RTL


1. Garis tinggi (garis-tinggi)


Biasanya, font terpisah diatur untuk markup RTL. Dalam hal ini, periksa bagaimana konten terlihat pada satu atau beberapa baris. Dalam contoh berikut, ada lebih sedikit ruang di antara baris untuk teks Arab daripada untuk bahasa Inggris, meskipun mereka memiliki nilai yang sama untuk properti tinggi garis.



Penting untuk mempertimbangkan ini dan menetapkan nilai yang benar untuk tinggi baris untuk teks Arab.



Twitter, misalnya, memiliki tombol dengan konten yang dipotong. Hanya karena nilai tinggi garis yang salah.



Perhatikan bahwa pada gambar pertama, diakritik Arab dipotong. Ini disebut kasra dan sangat penting untuk pembacaan kata yang benar. Pada gambar berikutnya, saya mengoreksi ketinggian garis dan sekarang karakter ditampilkan sepenuhnya, tanpa memotong.

2. Tautan yang digarisbawahi


Dengan kata-kata Arab, garis bawah standar tautan dari CSS terlihat buruk. Ini disebabkan oleh kekhasan menulis kata dan huruf dalam bahasa Arab dan ditunjukkan pada gambar berikut:



Saya menandai area bermasalah dengan lingkaran merah. Garis bawah tumpang tindih dengan titik-titik surat. Ini adalah close-up:



Poin yang ditandai dengan lingkaran merah tumpang tindih dengan garis bawah, membuat pembacaan menjadi sulit. Solusinya adalah menyesuaikan garis bawah dengan CSS.

2.1. Tipografi (dekorasi teks)


Dimungkinkan untuk mengubah gaya dan warna garis bawah menggunakan properti teks-dekorasi-gaya dan warna-dekorasi-warna yang baru. Namun, tidak ada jaminan bahwa ini akan berfungsi dengan benar pada semua keluarga dan ukuran font. Pada saat penulisan, Firefox adalah browser dengan dukungan terbaik untuk fitur-fitur ini.

 .link-2 { text-decoration-color: rgba(21, 132, 196, 0.2); text-decoration-style: normal; text-underline-offset: 4px; text-decoration-thickness: 2px; } 



2.2 Bayangan (bayangan kotak)


Dukungan browser untuk properti bayangan kotak jauh lebih baik daripada dekorasi teks. Anda dapat memeriksa dukungan untuk salah satu properti dekorasi teks baru, dan jika browser tidak mendukungnya, terapkan fallback menggunakan properti bayangan kotak.
 .link-3 { color: #000; text-decoration-color: rgba(21, 132, 196, 0.2); text-decoration-style: normal; text-underline-offset: 4px; text-decoration-thickness: 2px; box-shadow: inset 0 -5px 0 0 rgba(#1584c4, 0.2); } @supports (text-decoration-color: red){ .link-3 { box-shadow: none; } } 


3. Line break


Jika Anda menggunakan properti word-break, Anda perlu memeriksa kebenaran operasinya. Lihatlah contoh berikut:



Area yang dilingkari adalah kata-kata Arab yang dipatahkan oleh jeda baris karena penggunaan kata-istirahat. Dan dalam bahasa Arab, bungkus kata tidak digunakan, karena huruf dari setiap kata harus terhubung satu sama lain.

4. Singkatan


Dalam bahasa Inggris, singkatan sering digunakan, misalnya, selama berhari-hari dalam seminggu. Dengan demikian, "Sabtu" menjadi "Sabtu".



Dalam bahasa Arab, ini pada prinsipnya tidak mungkin, karena huruf-huruf dari kata itu harus dihubungkan.



Ikon dua arah


Ikon simetris tidak perlu dibalik ketika beralih antara tata letak LTR dan RTL. Berikut ini beberapa contohnya:



Pada saat yang sama, untuk beberapa ikon, penting untuk mengubah arah dalam versi RTL situs sehingga mereka dipahami dengan benar oleh pengguna.



Membalik item


Saat mengerjakan beberapa komponen, saya perlu cara untuk membaliknya dengan cepat. Di Sketch, saya menyalin komponen dan membaliknya dengan perintah yang sesuai. Fungsionalitas yang sama tersedia di Adobe XD dan Figma.



Untuk melihat apa yang saya maksud, berikut adalah animasi yang menunjukkan apa yang saya lakukan setelah membalik komponen.



Fitur Desain untuk RTL


Pada bagian ini, saya akan memeriksa komponen yang paling umum dan menunjukkan bagaimana mereka harus terlihat dalam mode RTL.

Ikon Tombol


Ada situasi ketika tombol memiliki ikon yang membuka menu tindakan tambahan. Dalam hal ini, lokasi ikon harus dibalik dalam tata letak RTL.



Bidang input


Beberapa kolom input formulir harus tetap rata meskipun dalam mode RTL. Misalnya, masukan bidang email atau nomor telepon.



Remah roti


Panah antara bagian dalam remah roti juga harus diputar.



Judul halaman


Komponen tajuk halaman berisi bagian awal dan akhir. Keduanya harus diputar dalam RTL



Tabel


Tabel juga harus diputar.



Bookmark


Jika ikon di sebelah kiri nama dalam bookmark dalam mode LTR, komponen ini perlu diperluas dalam RTL.



Kartu


Untuk kartu horizontal, gambar dan teks perlu ditukar dalam RTL



Pemberitahuan munculan


Seperti yang Anda harapkan, ikon "tutup" dan "peringatan" harus ditukar



Properti Boolean CSS


Menurut MDN:
Properti Logical dan Nilai CSS adalah modul yang mewakili properti logis dan nilai yang menyediakan kemampuan untuk mengontrol tata letak menggunakan arah dan dimensi fisik daripada logis.

Mari kita ambil contoh sederhana. Misalkan kita perlu menyelaraskan satu baris teks ke kanan. Tambahkan yang berikut ini:
 .page-header { text-align: right; } 

Dan untuk RTL:
 [dir="rtl"] .nav-item { text-align: left; } 

Bagaimana jika ada cara untuk menambahkan hanya satu nilai untuk properti perataan teks, yang akan mengubah sisi perataan, mengingat arah halaman? Properti logis CSS datang untuk menyelamatkan!
 .page-header { text-align: end; } 


Saat menggunakannya, sisi yang ditentukan oleh properti perataan teks akan didasarkan pada arah halaman. Demo

Untuk membuatnya lebih mudah untuk melihat perbedaan antara awal dan akhir, saya menyiapkan diagram di bawah ini. Nilai awal setara dengan nilai kiri di LRT dan nilai kanan di RTL. Sama dengan akhir, justru sebaliknya.



Sekarang setelah Anda memiliki gagasan umum tentang cara kerjanya, mari kita lihat contoh dan cara tambahan untuk menerapkan properti logis dari CSS.

Padding logis




Misalkan kita memiliki bidang input dengan ikon pencarian di sebelah kanan. Kami harus mengatur bantalan di kedua sisi. Padding di sebelah kanan akan sedikit lebih besar untuk menghindari overlay ikon pada teks.

 .input--search { padding-inline-start: 1rem; padding-inline-end: 2.5rem; } 

Margin logis



Margin di sebelah kanan ikon harus logis, jadi kami menggunakan margin-inline-end untuk ini.
 .page-header__avatar { margin-inline-end: 1rem; } 

Bingkai logis (perbatasan)



Seringkali bingkai digunakan untuk menunjukkan elemen navigasi aktif. Dalam contoh di atas, bingkai diatur di sisi kiri setiap elemen. Bagaimana cara menerapkan ini menggunakan properti logis?

 .nav__item { border-inline-start: 3px solid transparent; } .nav__item.is-active { border-color: #1e9ada; } 

Pembulatan sudut secara logis (garis batas)




Pada gambar di atas, latar belakang elemen navigasi dibulatkan hanya untuk sudut kanan dan kiri atas. Ini dapat diimplementasikan menggunakan properti logis:

 .nav__item { border-start-end-radius: 30px; border-end-end-radius: 30px; background-color: transparent; } .nav__item.is-active { background-color: #ecf6fb; } 


Sifat logis lembar cheat


Jika ragu tentang pilihan analog logis dari properti yang menentukan sisi, Anda dapat mengintip lembar contekan di bawah ini. Harap dicatat bahwa itu hanya berisi properti-properti logis yang mungkin berguna ketika bekerja dengan mode LTR dan RTL. Saya menyusun lembar contekan ini berdasarkan artikel yang bagus dari Adrian Roselli.

https://codepen.io/shadeed/pen/2981e62691e67452d9f282a5351d7c79

Selain itu, Adrian membuat demo yang membuatnya lebih mudah untuk memahami perbedaan antara properti logis dan directional.



Dukungan browser


Dukungan browser cukup bagus untuk properti padding, margin dan text-align. Namun, masih belum cukup untuk properti radius batas. Di bawah ini adalah tabel dukungan dari situs Can I Use :




Meskipun dukungannya belum sempurna (dan tidak akan pernah ada), saya menyarankan Anda untuk mulai menggunakan properti logis dengan fallback sekarang. Sebagai contoh

 .input--search { padding-left: 1rem; padding-right: 2.5rem; padding-inline-start: 1rem; padding-inline-end: 2.5rem; } 

Juga, Anda dapat menggunakan plugin PostCSS Logical , yang menambahkan fallback untuk setiap properti logis yang digunakan.

Konvensi penamaan CSS


Hindari memberi nama kelas CSS yang dilampirkan ke elemen mereka. Gunakan nama yang dapat diekstraksi menjadi komponen yang dapat digunakan kembali. Perhatikan contoh berikut:
 <div class="c-section"> <p><a href="#" class="see-link">See more</a></p> </div> <div class="c-section"> <p><a href="#" class="see-link">Learn more</a></p> </div> 


Tautannya sama di kedua blok, tetapi namanya berbeda. Di blok kedua, kelas lihat-tautan tidak masuk akal. Nama yang bagus mungkin c-link. Awalan c– diganti untuk komponen, saya mengadopsi metode ini dari kerangka kerja ITCSS.

Sekarang setelah Anda memahami idenya, kami juga dapat menerapkannya pada gaya RTL. Contoh di bawah ini menunjukkan bagian dengan dua anak



Alih-alih memberikan nama elemen seperti .c-page-header__left dan .c-page-header__right, saya menyebutnya .c-page-header__start dan .c-page-header__end. Ini lebih berorientasi masa depan dan tidak menyiratkan bahwa situs ini dibuat hanya dalam mode LTR atau RTL.

Alat Otomasi


Ada alat yang hebat untuk membuat bekerja dengan markup LTR dan RTL lebih mudah.

1. Bi-App-Sass


Bi-App-Sass dari Anas Nakava memungkinkan Anda untuk menulis satu versi gaya yang dikompilasi menjadi dua lembar gaya yang berbeda: satu untuk LRT dan satu untuk markup RTL.

Alat ini dapat berguna untuk proyek-proyek besar. . :
 .elem { display: flex; @include margin-left(10px); @include border-right(2px solid #000); } 


CSS .

app-ltr.css:
 .elem { display: flex; margin-left: 10px; border-right: 2px solid #000; } 


app-rtl.css:
 .elem { display: flex; margin-right: 10px; border-left: 2px solid #000; } 


, , GitHub ( 2015).

2. RTLCSS


RTLCSS LTR RTL.

, CSS-. , 50+ Sass-, RTLCSS CSS- RTL .



, , RTL- .



. , . , . , .



 .header__main, .header__sub { display: flex; justify-content: space-between; } 


CSS Flexbox , , , RTL-.



– . border-right. , . , .



 .c-brand:after { content: ""; display: inline-block; vertical-align: middle; width: 3px; height: 38px; border-radius: 5px; background: #e4e4e4; margin-inline-start: 1.25rem; } 


:



(, ). , LTR.



, padding margin. , :



 .topics-heading { margin-inline-end: 1.5rem; } .topics-list { margin-inline-end: 1rem; } .c-topic { padding-inline-start: 0.5rem; } .c-topic:not(:last-child) { margin-inline-end: 10px; } .c-topic__counter { margin-inline-start: 1rem; } 


, CSS left right.

«See All». . :
  • ,

SVG . translate, RTL. , . margin.

 .c-link svg { margin-inline-start: 4px; transition: 0.15s ease-in; } .c-link:hover svg { margin-inline-start: 8px; } 

margins , . , ,
 .c-link:hover svg { transform: translateX(6px); } /* I'm using dir=rtl in the header for the purpose of clarity. It should be added to the root element. */ .c-header[dir="rtl"] .c-link svg { transform: scaleX(-1); } .c-header[dir="rtl"] .c-link:hover svg { transform: scaleX(-1) translateX(6px); } 


, RTL scaleX(-1), . rotate(180deg), .



. :

 .c-input--search { background-image: url("data:image/svg+xml..."); background-position: right 6px center; } .c-header[dir="rtl"] .c-input--search { /* We replace the original icon with a flipped one. */ background-image: url("data:image/svg+xml..."); background-position: right 6px center; } 

, , . , padding .



LTR RTL :



. -. (LTR RTL). .



CodePen


Kholoud . Adebiyi Adedotun Lukman Šime Vidas .

Source: https://habr.com/ru/post/id484886/


All Articles