Membungkus konten di sekitar jalur kustom
Sejak lama, desainer web terpaksa berkreasi dalam batasan persegi panjang. Sebagian besar konten di web masih terjebak dalam kotak sederhana karena sebagian besar upaya kreatif untuk membuat tata letak non-persegi panjang berakhir dengan frustrasi. Hal ini akan berubah dengan diperkenalkannya CSS Shapes, yang tersedia mulai Chrome 37. CSS Shapes memungkinkan desainer web menggabungkan konten di sekitar jalur kustom, seperti lingkaran, elips, dan poligon, sehingga terbebas dari batasan persegi panjang.
Bentuk dapat ditentukan secara manual atau dapat disimpulkan dari gambar.
Mari kita lihat contoh yang sangat sederhana.
Mungkin Anda pernah sama naifnya dengan saya saat pertama kali mengambangkan gambar dengan bagian transparan, berharap konten akan membungkus dan mengisi celah, tetapi kecewa karena bentuk pembungkus persegi panjang tetap ada di sekitar elemen. CSS Shapes dapat digunakan untuk mengatasi masalah ini.
<img class="element" src="image.png" />
<p>Lorem ipsum…</p>
<style>
.element{
shape-outside: url(image.png);
shape-image-threshold: 0.5;
float: left;
}
</style>
Deklarasi CSS shape-outside: url(image.png) memberi tahu browser untuk mengekstrak bentuk dari gambar.
Properti shape-image-threshold menentukan tingkat opasitas minimum piksel yang akan digunakan untuk membuat bentuk. Nilainya harus berada dalam rentang antara 0.0 (sepenuhnya transparan) dan 1.0 (sepenuhnya buram). Jadi, shape-image-threshold: 0.5 berarti hanya piksel dengan opasitas 50% ke atas yang akan digunakan untuk membuat bentuk.
Properti float adalah kuncinya di sini. Meskipun properti shape-outside menentukan bentuk area yang akan dibungkus konten, tanpa float, Anda tidak akan melihat efek bentuk tersebut.
Elemen memiliki area float di sisi yang berlawanan dengan nilai float-nya. Misalnya, jika elemen dengan gambar cangkir kopi di-float ke kiri, area float akan dibuat di sebelah kanan cangkir. Meskipun Anda dapat merekayasa gambar dengan celah di kedua sisi, konten hanya akan mengelilingi bentuk di sisi berlawanan yang ditentukan oleh properti float, kiri atau kanan, tidak pernah keduanya.
Pada masa mendatang, shape-outside dapat digunakan pada elemen yang tidak mengambang dengan pengenalan CSS Exclusions.
Membuat bentuk secara manual
Selain mengekstrak bentuk dari gambar, Anda juga dapat membuat kode secara manual. Anda dapat memilih dari beberapa nilai fungsional untuk membuat bentuk: circle(), ellipse(), inset(), dan polygon(). Setiap fungsi bentuk menerima sekumpulan koordinat dan dipasangkan dengan kotak referensi yang menetapkan sistem koordinat. Kita akan membahas lebih lanjut tentang kotak referensi sebentar lagi.
Fungsi circle()
Notasi lengkap untuk nilai bentuk lingkaran adalah circle(r at cx cy) dengan r adalah radius lingkaran, sedangkan cx dan cy adalah koordinat pusat lingkaran pada sumbu X dan sumbu Y. Koordinat untuk pusat lingkaran bersifat opsional. Jika Anda menghilangkannya, pusat elemen (persimpangan diagonalnya) akan digunakan sebagai default.
.element{
shape-outside: circle(50%);
width: 300px;
height: 300px;
float: left;
}
Pada contoh di atas, konten akan diletakkan di luar jalur melingkar. Argumen tunggal 50% menentukan radius lingkaran, yang dalam kasus khusus ini, berjumlah setengah dari lebar atau tinggi elemen. Mengubah dimensi elemen akan memengaruhi radius bentuk lingkaran. Ini adalah contoh dasar bagaimana CSS Shapes dapat menjadi responsif.
Sebelum melangkah lebih jauh, perlu diingat bahwa CSS Shapes hanya memengaruhi bentuk area float di sekitar elemen. Jika elemen memiliki latar belakang, elemen tersebut tidak akan dipotong oleh bentuk. Untuk mencapai efek tersebut, Anda harus menggunakan properti dari CSS Masking - baik clip-path atau mask-image. Properti clip-path sangat berguna karena mengikuti notasi yang sama dengan CSS Shapes, sehingga Anda dapat menggunakan kembali nilai.
Ilustrasi di seluruh dokumen ini menggunakan kliping untuk menyoroti bentuk dan membantu Anda memahami efeknya.
Kembali ke bentuk lingkaran.
Saat menggunakan persentase untuk radius lingkaran, nilai sebenarnya dihitung dengan formula yang sedikit lebih kompleks: sqrt(width^2 + height^2) / sqrt(2). Hal ini berguna untuk dipahami karena akan membantu Anda membayangkan bentuk lingkaran yang dihasilkan jika dimensi elemen tidak sama.
Semua jenis unit CSS dapat digunakan dalam koordinat fungsi bentuk - px, em, rem, vw, vh, dan sebagainya. Anda dapat memilih yang cukup fleksibel atau kaku untuk kebutuhan Anda.
Anda dapat menyesuaikan posisi lingkaran dengan menetapkan nilai eksplisit untuk koordinat pusatnya.
.element{
shape-outside: circle(50% at 0 0);
}
Tindakan ini akan memosisikan pusat lingkaran di titik awal sistem koordinat. Apa yang dimaksud dengan sistem koordinat? Di sinilah kami memperkenalkan kotak referensi.
Kotak referensi untuk CSS Shapes
Kotak referensi adalah kotak virtual di sekitar elemen, yang menetapkan sistem koordinat yang digunakan untuk menggambar dan memosisikan bentuk. Origin sistem koordinat berada di sudut kiri atas dengan sumbu X mengarah ke kanan dan sumbu Y mengarah ke bawah.
Ingat bahwa shape-outside mengubah bentuk area float yang akan dibungkus oleh konten. Area float meluas ke tepi luar kotak yang ditentukan oleh properti margin. Ini disebut margin-box dan merupakan kotak referensi default untuk bentuk jika tidak ada yang disebutkan secara eksplisit.
Dua deklarasi CSS berikut memiliki hasil yang sama:
.element{
shape-outside: circle(50% at 0 0);
/* identical to: */
shape-outside: circle(50% at 0 0) margin-box;
}
Kita belum menetapkan margin pada elemen. Pada tahap ini, dapat diasumsikan bahwa origin sistem koordinat dan pusat lingkaran berada di sudut kiri atas area konten elemen. Hal ini berubah saat Anda menetapkan margin:
.element{
shape-outside: circle(50% at 0 0) margin-box;
margin: 100px;
}
Origin sistem koordinat kini berada di luar area konten elemen (100 px ke atas dan 100 px ke kiri), begitu juga dengan pusat lingkaran. Nilai yang dihitung dari radius lingkaran juga bertambah untuk memperhitungkan peningkatan permukaan sistem koordinat yang ditetapkan oleh kotak referensi margin-box.
Hanya satu kotak referensi yang dapat digunakan pada waktu tertentu dengan deklarasi shape-outside. Setiap kotak referensi akan memengaruhi bentuk dengan cara yang berbeda dan terkadang tidak kentara. Ada artikel lain yang membahas lebih dalam dan membantu Anda memahami kotak referensi untuk Bentuk CSS.
Fungsi ellipse()
Elips terlihat seperti lingkaran yang pipih. Nilai ini didefinisikan sebagai ellipse(rx ry at cx cy), dengan rx dan ry adalah radius elips pada sumbu X dan sumbu Y, sedangkan cx dan cy adalah koordinat untuk pusat elips.
.element{
shape-outside: ellipse(150px 300px at 50% 50%);
width: 300px;
height: 600px;
}
Nilai persentase akan dihitung dari dimensi sistem koordinat. Tidak perlu matematika yang rumit di sini. Anda dapat menghilangkan koordinat untuk pusat elips dan koordinat tersebut akan disimpulkan dari pusat sistem koordinat.
Jari-jari pada sumbu X dan Y juga dapat ditentukan dengan kata kunci: farthest-side menghasilkan jari-jari yang sama dengan jarak antara pusat elips dan sisi kotak referensi yang paling jauh darinya, sedangkan closest-side berarti kebalikannya - menggunakan jarak terpendek antara pusat dan sisi.
.element{
shape-outside: ellipse(closest-side farthest-side at 50% 50%);
/* identical to: */
shape-outside: ellipse(150px 300px at 50% 50%);
width: 300px;
height: 600px;
}
Hal ini mungkin berguna saat dimensi elemen (atau kotak referensi) dapat berubah dengan cara yang tidak dapat diprediksi, tetapi Anda ingin bentuk elips beradaptasi.
Kata kunci farthest-side dan closest-side yang sama juga dapat digunakan untuk radius dalam fungsi bentuk circle().
Fungsi polygon()
Jika lingkaran dan elips terlalu membatasi, fungsi bentuk poligon membuka berbagai opsi. Formatnya adalah polygon(x1 y1, x2 y2, ...), tempat Anda menentukan pasangan koordinat x y untuk setiap verteks (titik) poligon. Jumlah minimum pasangan untuk menentukan poligon adalah tiga, yaitu segitiga.
.element{
shape-outside: polygon(0 0, 0 300px, 300px 600px);
width: 300px;
height: 600px;
}
Titik diletakkan pada sistem koordinat. Untuk poligon responsif, Anda dapat menggunakan nilai persentase untuk beberapa atau semua koordinat.
.element{
/* polygon responsive to font-size*/
shape-outside: polygon(0 0, 0 100%, 100% 100%);
width: 20em;
height: 40em;
}
Ada parameter fill-rule opsional, diimpor dari SVG, yang menginstruksikan browser cara mempertimbangkan “insideness” poligon jika ada jalur yang berpotongan sendiri atau bentuk tertutup. Joni Trythall menjelaskan dengan sangat baik cara kerja properti fill-rule di SVG. Jika tidak ditentukan, fill-rule akan ditetapkan secara default ke nonzero.
.element{
shape-outside: polygon(0 0, 0 100%, 100% 100%);
/* identical to: */
shape-outside: polygon(nonzero, 0 0, 0 100%, 100% 100%);
}
Fungsi inset()
Fungsi bentuk inset() memungkinkan Anda membuat bentuk persegi panjang untuk membungkus konten. Hal ini mungkin terdengar berlawanan dengan intuisi mengingat premis awal bahwa CSS Shapes membebaskan konten web dari kotak sederhana. Mungkin saja. Saya belum menemukan kasus penggunaan untuk inset() yang belum dapat dicapai dengan float dan margin atau dengan polygon(). Meskipun demikian, inset() memberikan ekspresi yang lebih mudah dibaca untuk bentuk persegi panjang daripada polygon().
Notasi lengkap untuk fungsi bentuk inset adalah inset(top right bottom left border-radius). Empat argumen posisi pertama adalah offset ke dalam dari tepi elemen. Argumen terakhir adalah radius batas untuk bentuk persegi panjang. Kolom ini bersifat opsional, jadi Anda dapat mengosongkannya. Properti ini mengikuti notasi singkat border-radius yang sudah Anda gunakan di CSS.
.element{
shape-outside: inset(100px 100px 100px 100px);
/* yields a rectangular shape which is 100px inset on all sides */
float: left;
}
Membuat bentuk dari kotak referensi
Jika Anda tidak menentukan fungsi bentuk untuk properti shape-outside, Anda dapat mengizinkan browser memperoleh bentuk dari kotak referensi elemen. Kotak referensi default adalah margin-box. Sejauh ini tidak ada yang aneh, begitulah cara kerja float. Namun, dengan menerapkan teknik ini, Anda dapat menggunakan kembali geometri elemen. Mari kita lihat properti border-radius.
Jika Anda menggunakannya untuk membulatkan sudut elemen mengambang, Anda akan mendapatkan efek pemangkasan, tetapi area mengambang tetap berbentuk persegi panjang. Tambahkan shape-outside: border-box untuk mengelilingi kontur yang dibuat oleh border-radius.
.element{
border-radius: 50%;
shape-outside: border-box;
float: left;
}
Tentu saja, Anda dapat menggunakan semua kotak referensi dengan cara ini. Berikut adalah penggunaan lain untuk bentuk turunan - kutipan yang di-offset.
Anda dapat mencapai efek kutipan bergeser hanya dengan menggunakan properti float dan margin. Namun, hal itu mengharuskan Anda memosisikan elemen kutipan di hierarki HTML pada titik yang ingin Anda render.
Berikut cara mendapatkan efek kutipan yang sama dengan fleksibilitas tambahan:
.pull-quote{
shape-outside: content-box;
margin-top: 200px;
float: left;
}
Kita secara eksplisit menetapkan kotak referensi content-box untuk sistem koordinat bentuk. Dalam hal ini, jumlah konten dalam kutipan menentukan bentuk yang akan dibungkus oleh konten luar. Properti margin-top digunakan di sini untuk memosisikan (menggeser) kutipan, terlepas dari posisinya di hierarki HTML.
Margin bentuk
Anda akan melihat bahwa menggabungkan konten di sekitar bentuk dapat membuatnya terlalu dekat dengan elemen. Anda dapat menambahkan spasi di sekitar bentuk dengan properti shape-margin.
.element{
shape-outside: circle(40%);
shape-margin: 1em;
float: left;
}
Efeknya mirip dengan yang biasa Anda dapatkan dari penggunaan properti margin reguler, tetapi shape-margin hanya memengaruhi ruang di sekitar nilai shape-outside. Properti ini akan menambahkan spasi di sekitar bentuk hanya jika ada ruang untuknya dalam sistem koordinat. Itulah sebabnya dalam contoh di atas, radius lingkaran ditetapkan ke 40%, bukan 50%. Jika radius ditetapkan ke 50%, lingkaran akan menggunakan semua ruang dalam sistem koordinat sehingga tidak ada ruang untuk efek shape-margin. Ingat, bentuk pada akhirnya dibatasi oleh margin-box elemen (elemen ditambah margin di sekitarnya). Jika bentuknya lebih besar dan meluap, bentuk tersebut akan dipotong ke margin-box dan Anda akan mendapatkan bentuk persegi panjang.
Penting untuk dipahami bahwa shape-margin hanya menerima satu nilai positif. Tidak memiliki notasi panjang. Apa itu shape-margin-top untuk lingkaran?
Menganimasikan bentuk
Anda dapat menggabungkan bentuk CSS dengan banyak fitur CSS lainnya, seperti transisi dan animasi. Namun, perlu ditekankan bahwa pengguna merasa sangat terganggu saat tata letak teks berubah saat mereka sedang membaca. Perhatikan baik-baik pengalaman pengguna jika Anda memutuskan untuk menganimasikan bentuk.
Anda dapat menganimasikan radius dan pusat untuk bentuk circle() dan ellipse() asalkan ditentukan dalam nilai yang dapat diinterpolasi oleh browser. Perjalanan dari circle(30%) ke circle(50%) dapat dilakukan. Namun, menganimasikan antara circle(closest-side) hingga circle(farthest-side) akan menghambat browser.
.element{
shape-outside: circle(30%);
transition: shape-outside 1s;
float: left;
}
.element:hover{
shape-outside: circle(50%);
}
Efek yang lebih menarik dapat dicapai saat menganimasikan bentuk polygon(), dengan catatan penting bahwa poligon harus memiliki jumlah verteks yang sama di antara kedua status animasi. Browser tidak dapat melakukan interpolasi jika Anda menambahkan atau menghapus verteks.
Salah satu triknya adalah menambahkan jumlah maksimum verteks yang Anda perlukan dan memosisikannya dalam satu cluster dalam status animasi tempat Anda menginginkan lebih sedikit tepi yang terlihat pada bentuk.
.element{
/* four vertices (looks like rectangle) */
shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transition: shape-outside 1s;
}
.element:hover{
/* four vertices, but second and third overlap (looks like triangle) */
shape-outside: polygon(0 0, 100% 50%, 100% 50%, 0 100%);
}
Menggabungkan konten di dalam bentuk
Draf awal spesifikasi CSS Shapes menyertakan properti shape-inside yang memungkinkan Anda menggabungkan konten di dalam bentuk. Bahkan ada implementasi di Chrome dan Webkit untuk sementara waktu. Namun, menggabungkan konten yang diposisikan secara arbitrer di dalam jalur kustom memerlukan lebih banyak upaya dan riset untuk mencakup semua kemungkinan skenario dan menghindari bug. Oleh karena itu, properti shape-inside telah ditunda ke CSS Shapes Level 2 dan penerapannya telah ditarik.
Namun, dengan sedikit usaha dan kompromi, Anda masih dapat mencapai efek penggabungan konten di dalam bentuk kustom. Triknya adalah menggunakan dua elemen mengambang dengan shape-outside, yang diposisikan di sisi yang berlawanan dari penampung. Komprominya adalah Anda harus menggunakan satu atau dua elemen kosong yang tidak memiliki makna semantik, tetapi berfungsi sebagai penyangga untuk menciptakan ilusi bentuk di dalamnya.
<div>
<div class='left-shape'></div>
<div class='right-shape'></div>
Lorem ipsum...
</div>
Posisi elemen strut .left-shape dan .right-shape di bagian atas penampung sangat penting karena elemen tersebut akan di-float ke kiri dan ke kanan untuk mengapit konten.
.left-shape{
shape-outside: polygon(0 0, ...);
float: left;
width: 50%;
height: 100%;
}
.right-shape{
shape-outside: polygon(50% 0, ...);
float: right;
width: 50%;
height: 100%;
}
Gaya ini membuat dua strut mengambang menggunakan semua ruang dalam elemen, tetapi properti shape-outside menyisakan ruang untuk konten lainnya.
Jika CSS Shapes tidak didukung oleh browser, hal ini akan menghasilkan efek yang buruk dengan mendorong semua konten ke bawah. Oleh karena itu, penting untuk menggunakan fitur ini dengan cara progressive enhancement.
Dalam contoh animasi bentuk sebelumnya, Anda akan melihat bahwa teks yang bergeser dapat mengganggu. Tidak semua kasus penggunaan memerlukan bentuk animasi. Namun, Anda dapat menganimasikan properti lain yang berinteraksi dengan Bentuk CSS untuk menambahkan efek jika diperlukan.
Dalam demonstrasi CSS Shapes Alice in Wonderland, kami menggunakan posisi scroll untuk mengubah margin atas konten. Teks terjepit di antara dua elemen mengambang. Saat bergerak ke bawah, elemen tersebut harus diatur ulang sesuai dengan shape-outside dari dua elemen mengambang. Hal ini memberikan kesan bahwa teks tersebut masuk ke dalam lubang kelinci dan menambah pengalaman bercerita. Berisiko tidak beralasan? Mungkin. Tapi kelihatannya keren.
Karena tata letak teks dilakukan secara native oleh browser, performanya lebih baik daripada menggunakan solusi JavaScript. Namun, mengubah margin-top saat men-scroll akan memicu banyak peristiwa tata letak ulang dan render, dan hal ini dapat mengurangi performa secara signifikan. Gunakan dengan hati-hati. Namun, menggunakan CSS Shapes tanpa menganimasikannya tidak akan menurunkan performa secara signifikan.
Progressive enhancement
Mulailah dengan berasumsi bahwa browser tidak memiliki dukungan CSS Shapes dan kembangkan asumsi tersebut saat Anda mendeteksi fitur tersebut. Modernizr adalah solusi yang baik untuk melakukan deteksi fitur dan ada pengujian untuk Bentuk CSS di bagian 'Deteksi non-inti'.
Beberapa browser menyediakan deteksi fitur di CSS melalui aturan @supports tanpa memerlukan library eksternal. Google Chrome, yang juga mendukung Bentuk CSS, memahami aturan @supports. Berikut cara menggunakannya untuk melakukan progressive enhancement:
.element{
/* styles for all browsers */
}
@supports (shape-outside: circle(50%)){
/* styles only for browsers which support CSS Shapes */
.element{
shape-outside: circle(50%);
}
}
Lea Verou telah menulis lebih lanjut tentang cara menggunakan aturan @supports CSS.
Disambiguasi dari CSS Exclusions
Apa yang kita kenal sekarang sebagai CSS Shapes dulunya disebut CSS Exclusions and Shapes pada masa-masa awal spesifikasi. Perubahan penamaan mungkin tampak seperti nuansa, tetapi sebenarnya sangat penting. CSS Exclusions, yang kini menjadi spesifikasi terpisah, memungkinkan penggabungan konten di sekitar elemen yang diposisikan secara arbitrer, tanpa memerlukan properti float. Bayangkan menggabungkan konten di sekitar elemen yang diposisikan secara absolut; itulah kasus penggunaan untuk CSS Exclusions. Bentuk CSS hanya menentukan jalur yang akan dibungkus oleh konten.
Jadi, bentuk dan pengecualian bukanlah hal yang sama, tetapi keduanya saling melengkapi. CSS Shapes tersedia di browser saat ini, sedangkan CSS Exclusions belum diimplementasikan dengan interaksi bentuk.
Alat untuk menggunakan Bentuk CSS
Anda dapat membuat jalur di alat penulisan gambar klasik, tetapi tidak ada satu pun, pada saat penulisan ini, yang mengekspor sintaksis yang diperlukan untuk nilai CSS Shapes. Meskipun demikian, bekerja seperti itu tidak akan terlalu praktis.
CSS Shapes dimaksudkan untuk digunakan di browser, tempat elemen ini bereaksi terhadap elemen lain di halaman. Sangat berguna untuk memvisualisasikan efek pengeditan bentuk pada konten di sekitarnya. Ada beberapa alat untuk membantu Anda dalam alur kerja ini:
Brackets: Ekstensi CSS Shapes Editor untuk Brackets menggunakan mode pratinjau langsung editor kode untuk menempatkan editor interaktif guna mengedit nilai bentuk.
Google Chrome: Ekstensi CSS Shapes Editor untuk Google Chrome memperluas Developer Tools browser dengan kontrol untuk membuat dan mengedit bentuk. Alat ini menempatkan editor interaktif di atas elemen yang dipilih.
Inspektur di Google Chrome memiliki dukungan bawaan untuk menandai bentuk. Arahkan kursor ke elemen dengan properti shape-outside dan elemen tersebut akan menyala untuk mengilustrasikan bentuknya.
Bentuk dari gambar: Jika Anda lebih suka membuat gambar dan meminta browser mengekstrak bentuk dari gambar tersebut, Rebecca Hauck telah menulis tutorial yang bagus untuk Photoshop.
Polyfill: Google Chrome adalah browser utama pertama yang mengirimkan Bentuk CSS. Dukungan mendatang untuk fitur ini di iOS 8 dan Safari 8 Apple. Vendor browser lain mungkin akan mempertimbangkannya pada masa mendatang. Sebelum itu, ada polyfill CSS Shapes untuk memberikan dukungan dasar.
Kesimpulan
Di web yang kontennya sebagian besar terjebak dalam kotak sederhana, CSS Shapes menyediakan cara untuk membuat tata letak yang ekspresif, menjembatani kesenjangan fidelitas antara desain web dan cetak. Tentu saja, bentuk dapat disalahgunakan dan mengalihkan perhatian. Namun, jika diterapkan dengan selera dan penilaian yang baik, bentuk dapat meningkatkan presentasi konten dan memfokuskan perhatian pengguna dengan cara yang unik bagi mereka.
Kami akan memberikan kumpulan karya orang lain, sebagian besar dari media cetak, yang menunjukkan penggunaan menarik untuk tata letak non-persegi panjang. Semoga ini menginspirasi Anda untuk mencoba CSS Shapes dan bereksperimen dengan ide desain baru.
Terima kasih banyak kepada Pearl Chen, Alan Stearns, dan Zoltan Horvath karena telah meninjau artikel ini dan memberikan insight yang berharga.