DTE :]

Sunday, July 7, 2019

Cara Memberlakukan Kode CSS Hanya pada Tampilan Tata Letak

Warna khusus pada tampilan blok widget di halaman Tata Letak.

Cara Lama

Cara pertama ini adalah cara yang paling tua, yaitu dengan membuat selektor CSS yang diinginkan menjadi khusus untuk anak-anak elemen pada induk <body id="layout"> saja. Kekurangan dari metode ini adalah, kode CSS khusus yang seharusnya hanya dimuat pada tampilan Tata Letak akan tampil juga pada kode sumber di halaman versi publik. Kode CSS juga akan diterapkan pada halaman versi publik apabila Anda menambahkan atribut id="layout" pada elemen <body> di dalam kode XML tema:

body#layout div.section {
  background: #ff0;
  border: 4px solid #f00;
}

Cara Baru

Cara yang paling baru untuk memberlakukan kode CSS hanya pada tampilan Tata Letak adalah dengan menuliskan kode CSS di dalam elemen <b:template-skin> seperti ini:

<b:template-skin>
<![CDATA[
div.section {
  background: #ff0;
  border: 4px solid #f00;
}
]]>
</b:template-skin>

Kita mungkin bisa menggunakan tag kondisional ini sebagai cara alternatif, hanya saja Saya belum sempat mengujinya jadi Saya tidak tahu apakah cara ini bisa bekerja atau tidak. Secara logika harusnya bisa:

<b:if cond='data:view.isLayoutMode'>
<style>
div.section {
  background: #ff0;
  border: 4px solid #f00;
}
</style>
</b:if>

Anda bisa menggunakan fitur ini untuk menandai beberapa widget yang Anda anggap khusus atau penting, misalnya dengan memberikan warna yang spesial pada widget-widget tertentu sehingga Anda sebagai pengembang tema akan lebih mudah untuk membimbing pengguna tema Anda dengan cara mengarahkan mereka untuk menyunting widget tertentu berdasarkan warna atau pola yang Anda berikan. Sebagai contoh, di sini Saya memberikan warna gradiasi biru pada widget pencarian dan gradiasi kuning pada widget iklan:

body#layout div.widget.BlogSearch div.widget-content {
  background: linear-gradient(#fff, #e8ffff);
}

body#layout div.widget.AdSense div.widget-content {
  background: linear-gradient(#fff, #ffffce);
}

Kode yang Saya beri tanda adalah nama kelas HTML yang akan diterapkan secara otomatis pada widget sesuai dengan jenisnya. Anda juga bisa membuatnya menjadi lebih spesifik lagi dengan memanfaatkan ID widget seperti ini:

body#layout div.widget#BlogSearch1 div.widget-content {
  background: linear-gradient(#fff, #e8ffff);
}

Labels: , , ,

Tuesday, July 5, 2016

Menerapkan Fitur Infinite Scroll Sederhana pada Blogger

Blogger Infinite Scroll

Fitur ini merupakan contoh nyata penerapan dari potongan kode ini yang kemudian diaplikasikan untuk membuat navigasi halaman AJAX tanpa jQuery seperti pada contoh sebelumnya.

Infinite scroll adalah teknik desain web yang mencegah bar gulir peramban menggulir ke bagian bawah halaman, membuat halaman tumbuh dengan konten tambahan sebagai gantinya.

Plugin ini mengharuskan Anda untuk menentukan empat elemen sebagai target JavaScript. Posting, wadah posting, wadah navigasi halaman dan tautan navigasi halaman berikutnya. Untuk Blogger, elemen target yang paling umum dapat digunakan adalah sebagai berikut:

  • .blog-posts
  • .date-outer
  • .blog-pager
  • .blog-pager-older-link

Anda dapat menyesuaikannya nanti berdasarkan markup HTML pada templat Anda.

Plugin ini pada awalnya merupakan plugin untuk CMS Mecha, tapi sebenarnya ini tetap dapat bekerja pada platform yang lain seperti Blogger, dengan sedikit penyesuaian tentunya.

Untuk menerapkannya pada Blogger, salin kode di bawah ini kemudian letakkan di atas </body>:

<b:if cond='data:blog.pageType in [&quot;index&quot;,&quot;archive&quot;]'>
<script src='//cdn.rawgit.com/tovic/infinite-scroll-plugin-for-mecha-cms/v1.1.0/infinite-scroll/assets/sword/infinite-scroll.min.js'></script>
<script>
//<![CDATA[
/*! Simple AJAX infinite scroll by Taufik Nurrohman */
var infinite_scroll = new InfiniteScroll({
    type: 2,
    target: {
        posts: '.blog-posts',
        post: '.date-outer',
        anchors: '.blog-pager',
        anchor: '.blog-pager-older-link'
    },
    text: {
        load: '<a class="js-load" href="javascript:;">Muat Lagi</a>',
        loading: '<span class="js-loading" style="cursor:wait;">Memuat\u2026</span>',
        loaded: '<span class="js-loaded">Dimuat.</span>',
        error: '<a class="js-error" href="javascript:;">Kesalahan.</a>'
    }
});
//]]>
</script>
</b:if>

Simpan perubahan.

Konfigurasi

Data Keterangan
type Opsi 0 berarti pengguna perlu mengeklik tombol Muat Lagi untuk memuat posting-posting sebelumnya. Opsi 1 berarti pengguna hanya perlu menggulung peramban sampai pada batas akhir halaman untuk memuat posting-posting sebelumnya. Opsi 2 berarti pengguna perlu mengeklik tombol Muat Lagi untuk memuat posting-posting sebelumnya, setelah itu pengguna hanya perlu menggulung peramban sampai pada batas akhir halaman untuk memuat posting-posting sebelumnya.

Labels: , ,

Thursday, August 21, 2014

Lettering PHP

Versi PHP untuk lettering.js

function lettering_PHP($text) {
    $results = '<span class="word-1 char-group">';
    $skip = false;
    $entity_open = false;
    $entity_close = false;
    $index_word = 2;
    $index_letter = 1;
    $letters = preg_split('#(?<!^)(?!$)#u', $text);
    foreach($letters as $letter) {
        $entity_open = $letter == '&';
        $entity_close = $letter == ';';
        if($letter == '<' || $entity_open) $skip = true;
        if($letter == '>' || $entity_close) $skip = false;
        if( ! $skip && $letter == ' ') {
            $results .= '</span> <span class="word-' . $index_word . ' char-group">';
            $index_word++;
        } else {
            if( ! $skip && $letter != '<' && $letter != '>' && $letter != '&' && $letter != ';' && $letter != ' ') {
                $results .= '<span class="char-' . $index_letter . '">' . $letter . '</span>';
                $index_letter++;
            } else {
                if($entity_open) {
                    $results .= '<span class="char-' . $index_letter . '">';
                }
                $results .= $letter;
                if($entity_close) {
                    $results .= '</span>';
                    $index_letter++;
                }
            }
        }
    }
    return '<span aria-label="' . str_replace(array('"', '\''), array('&quot;', '&#039;'), strip_tags($text)) . '"><span aria-hidden="true" class="word-group">' . $results . '</span></span></span>';
}

Penggunaan

<h2><?php echo lettering_PHP('Lorem Ipsum Dolor Sit Amet'); ?></h2>

Sebelum

<h2>Lorem Ipsum Dolor Sit Amet</h2>

Sesudah

<h2>
  <span aria-label="Lorem Ipsum Dolor Sit Amet">
    <span aria-hidden="true" class="word-group">
      <span class="word-1 char-group">
        <span class="char-1">L</span>
        <span class="char-2">o</span>
        <span class="char-3">r</span>
        <span class="char-4">e</span>
        <span class="char-5">m</span>
      </span> 
      <span class="word-2 char-group">
        <span class="char-6">I</span>
        <span class="char-7">p</span>
        <span class="char-8">s</span>
        <span class="char-9">u</span>
        <span class="char-10">m</span>
      </span> 
      <span class="word-3 char-group">
        <span class="char-11">D</span>
        <span class="char-12">o</span>
        <span class="char-13">l</span>
        <span class="char-14">o</span>
        <span class="char-15">r</span>
      </span> 
      <span class="word-4 char-group">
        <span class="char-16">S</span>
        <span class="char-17">i</span>
        <span class="char-18">t</span>
      </span> 
      <span class="word-5 char-group">
        <span class="char-19">A</span>
        <span class="char-20">m</span>
        <span class="char-21">e</span>
        <span class="char-22">t</span>
      </span>
    </span>
  </span>
</h2>

Sumber: https://github.com/tovic/lettering-plugin-for-mecha-cms/blob/master/lettering-php/launch.php

Labels: , ,

Saturday, June 21, 2014

Navigasi Halaman dengan Keyboard

Sisipkan kode ini di atas </head> atau di atas </body> pada editor templat Anda, lalu simpan perubahan:

<script>
//<![CDATA[
(function(win, doc) {

    var pager = false;

    // left = 37, right = 39
    doc.onkeydown = function(e) {
        switch (e.keyCode) {
            case 37: pager = doc.getElementById('blog-pager-newer-link'); break;
            case 39: pager = doc.getElementById('blog-pager-older-link'); break;
        }
        if (pager) {
            win.location.href = pager.children[0].href;
            return false;
        }
    };

})(window, document);
//]]>
</script>

Sekarang Anda akan bisa melakukan navigasi menggunakan tombol panah kanan atau kiri pada keyboard. Ini cuma berlaku untuk markup HTML navigasi halaman Blogger yang masih standar. Untuk navigasi halaman yang sudah mengalami perubahan mungkin akan memerlukan sedikit modifikasi, terutama pada bagian nilai variabel pager di dalam kondisional switch.

Menambahkan Efek Aktif (Seperti Tertekan)

Dengan cara menambahkan kelas active pada navigasi halaman ketika tombol panah kanan dan/atau kiri ditekan, maka kita bisa menciptakan efek aktif/tertekan palsu melalui kelas tersebut:

<script>
//<![CDATA[
(function(win, doc) {

    var pager = false;

    // left = 37, right = 39
    doc.onkeydown = function(e) {
        switch (e.keyCode) {
            case 37: pager = doc.getElementById('blog-pager-newer-link'); break;
            case 39: pager = doc.getElementById('blog-pager-older-link'); break;
        }
        if (pager) {
            pager.className = pager.className += ' active';
            win.location.href = pager.children[0].href;
            return false;
        }
    };

    doc.onkeyup = function(e) {
        switch (e.keyCode) {
            case 37: pager = doc.getElementById('blog-pager-newer-link'); break;
            case 39: pager = doc.getElementById('blog-pager-older-link'); break;
        }
        if (pager) {
            pager.className = pager.className.replace(/ active/g, "");
        }
    };

})(window, document);
//]]>
</script>
#blog-pager-older-link.active a,
#blog-pager-newer-link.active a,
#blog-pager-older-link a:active,
#blog-pager-newer-link a:active {
  background-color:red;
  color:white;
}

Demonstrasi bisa Anda lihat di sini. Pastikan Anda sudah berada dalam keadaan terfokus pada area ketika hendak menekan tombol panah kanan dan kiri:

Lihat Demo

Metode ini mungkin tidak cocok untuk diterapkan pada blog yang bersifat umum karena akan mengganggu fungsi tombol keyboard yang asli. Lebih baik terapkan pada blog-blog yang bersifat pribadi saja.

Labels: ,

Thursday, December 19, 2013

Panduan Mendesain Elemen-Elemen Formulir HTML dari Awal

HTML Form Elements
Elemen-elemen formulir.

Mendesain elemen UI itu bukan cuma soal menentukan efek gradiasi yang bagus, efek bayangan yang realistis dan juga pewarnaan yang cocok dengan lingkungan. Web tidak sama dengan sekedar mendesain grafis, yang artinya bahwa semuanya tidak akan bisa semudah itu dibuat menjadi tampak sama pada semua peramban. Setiap peramban memiliki spesifikasinya sendiri-sendiri, dan terkadang mereka juga memiliki spesifikasi yang sangat berbeda, yang menurut kita mungkin sangat mengganggu. Namun tentunya spesifikasi tersebut memiliki tujuan tersendiri yang sangat khusus untuk peramban terkait agar bisa bekerja dengan baik/lebih baik dibandingkan dengan peramban-peramban yang lain. Kita tidak bisa melakukan apa-apa.

Membuat desain tampilan menjadi tampak sama —atau setidaknya nyaris sama— itu tidak mudah untuk elemen-elemen formulir. Anda harus mengikuti beberapa tahapan pembentukan ulang… dan yang terpenting adalah mengenai prioritas dalam hal kestabilan tampilan dibandingkan dengan keindahan tampilan.

Memulai dengan Tahap Pembentukan Ulang

Langkah awal yang harus Anda lakukan adalah menentukan posisi, jarak, padding dan beberapa pengaturan warna serta tipe fon secara global sebisa mungkin ke semua elemen formulir yang ada:

button,
input,
select,
textarea {
  display:inline-block; /* alternatif yang lebih baik dibandingkan `display:inline` */
  vertical-align:middle; /* posisikan elemen ke tengah secara vertikal terhadap teks */
  width:170px; /* tentukan lebar elemen secara umum */
  margin:1px 0; /* tentukan `margin` elemen secara umum */
  padding:4px; /* tentukan `padding` elemen secara umum */
  font:normal normal 13px/normal Arial,Sans-Serif; /* tentukan tipe fon secara umum */
  color:#333; /* tentukan warna teks secara umum */
  line-height:normal; /* tentukan `line-height` secara umum (deklarasi `line-height` pada selektor `font` di atas biasanya tidak bekerja pada elemen `<button>`) */
  background-color:white; /* tentukan warna latar secara umum */
  border:1px solid #333; /* tentukan `border` secara umum */

  /* deklarasikan `box-sizing` yang seragam */
  -webkit-box-sizing:border-box;
  -moz-box-sizing:border-box;
  box-sizing:border-box;

  /* hapus outline jika mungkin */
  outline:none;
  outline-offset:-2px;
}

Pada kode di atas Saya juga menentukan ukuran lebar sebesar 170px secara global. Penentuan lebar elemen ini sebenarnya Saya tujukan hanya kepada elemen select dan elemen input yang berfungsi untuk menyisipkan teks (misalnya elemen formulir bertipe date, email, number, tel, text dan url). Namun karena Saya menerapkannya pada selektor CSS berupa input tanpa adanya penambahan atribut type secara spesifik, maka deklarasi lebar ini juga akan mempengaruhi semua elemen input yang tidak kita kehendaki, misalnya pada elemen input bertipe button dan checkbox. Oleh karena itulah setelah pendeklarasian tersebut dilakukan, kita juga harus mengembalikan ukuran lebar pada elemen-elemen formulir yang tidak kita kehendaki memiliki ukuran lebar tetap.

Kebetulan di sini Saya mengatur nilai lebar kembali menjadi auto pada elemen-elemen formulir berupa tombol, sehingga pada saat yang bersamaan Saya juga bisa menambahkan beberapa warna baru pada elemen-elemen ini untuk membedakan tampilannya dengan elemen-elemen formulir berupa masukan teks:

button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
  width:auto; /* mengembalikan ukuran lebar ke keadaan semula */
  background-color:#333; /* tentukan warna latar yang berbeda untuk elemen-elemen tombol */
  color:white; /* tentukan warna teks yang berbeda untuk elemen-elemen tombol */

  /* buat `padding` kiri dan kanan menjadi lebih lebar untuk membuatnya lebih gemuk */
  padding-right:8px;
  padding-left:8px;

  font-weight:bold; /* buat teks menjadi tebal */
  cursor:pointer; /* ubah kursor menjadi `pointer` untuk kenyamanan */
  border-color:transparent; /* opsional */
}

box-sizing

Sedikit catatan mengenai deklarasi box-sizing yang Saya tambahkan. Itu berfungsi untuk mengatasi masalah ukuran lebar yang tidak seragam terutama pada elemen formulir berupa masukan teks dan selectbox:

Text Input and Select Element without CSS `box-sizing`
Membandingkan ukuran elemen input dengan elemen select yang sudah dimodifikasi tanpa adanya deklarasi box-sizing yang seragam.

Dari gambar di atas terlihat bahwa meskipun keduanya sama-sama Saya beri ukuran lebar sebesar 170 piksel, padding sebesar 2 piksel dan border setebal 1 piksel (gambar perbandingan yang ke dua), pada kenyataannya elemen masukan teks akan menghasilkan lebar sebesar 173 piksel (border-left-width + padding-left + width + padding-right + border-right-width ), sedangkan elemen selectbox akan memiliki lebar sebesar 170 piksel (width ). Ini berarti bahwa elemen selectbox telah memiliki deklarasi box-sizing sebagai border-box secara normal, sedangkan elemen yang lain tidak —telah ditentukan oleh User Agent Stylesheet.

Anda bisa memilih untuk menentukan nilai properti ini menjadi border-box atau padding-box karena tujuan utama pendeklarasian properti ini memang hanya untuk menyamakan logika CSS Box-Model mereka saja. Tapi Saya sarankan untuk menggunakan border-box saja karena deklarasi ini memiliki satu keuntungan lain yaitu akan mempermudah Anda di dalam mengatasi masalah penentuan lebar elemen menuju ukuran 100% dengan hasil tampilan yang benar.

Kembalikan semua ukuran lebar elemen input bertipe checkbox dan radio serta image. Hilangkan juga deklarasi border, padding dan background yang kita deklarasikan sebelumnya:

/* hilangkan nilai `width`, `border`, `padding`, `background` yang telah dibuat sebelumnya pada elemen-elemen ini */
input[type="checkbox"],
input[type="image"],
input[type="radio"] {
  width:auto;
  padding:0;
  background:none;
  border:none;
  cursor:pointer;
}

Setelah itu atur posisi elemen label menjadi berada di tengah secara vertikal. Atur juga tipe kursor menjadi pointer untuk menambahkan kenyamanan bagi pengguna. Bisa juga digabungkan dengan select, input[type="color"] dan input[type="file"] untuk meringkas kode CSS (meskipun properti display dan vertical-align sebenarnya sudah ditentukan sebelumnya):

input[type="color"],
input[type="file"],
label,
select {
  display:inline-block;
  vertical-align:middle;
  cursor:pointer;
}

Atau pakai ini saja untuk CSS yang lebih panjang namun lebih logis:

input[type="color"],
input[type="file"],
select {cursor:pointer}

label {
  display:inline-block;
  vertical-align:middle;
  cursor:pointer;
}

Elemen Tombol Tampak Lebih Besar di Firefox

Mungkin Anda pernah mengalami ini. Masalahnya bukan karena kode CSS Anda yang salah, tetapi karena Firefox memiliki elemen DOM bayangan yang mengitari bagian sebelah dalam elemen button dan elemen input bertipe button, submit atau reset seperti ini, yang telah membuat ukuran tombol menjadi lebih gemuk di Firefox:

::-moz-focus-inner
::-moz-focus-inner pada peramban Firefox.

CSS ini bisa mengatasi masalah tersebut:

button::-moz-focus-inner,
input::-moz-focus-inner {
  margin:0;
  padding:0;
  border:none;
  outline:none;
}

Textarea di Internet Explorer

Internet Explorer secara normal memiliki tampilan elemen textarea yang akan tetap meninggalkan scrollbar vertikal meskipun isinya kosong. Gunakan deklarasi overflow:auto untuk menghilangkan scrollbar pada elemen ini agar tampilannya sama dengan apa yang terlihat di peramban lain:

textarea {overflow:auto}

Beberapa deklarasi lain yang umum untuk membuat elemen ini menjadi lebih stabil:

textarea {
  overflow:auto;
  display:block; /* set sebagai elemen blok */
  width:100%; /* buat lebarnya menjadi 100% */
  resize:vertical; /* agar `textarea` hanya bisa diubah ukurannya secara vertikal (lainnya: `both`, `horizontal`, `none`) */
}

Efek :focus, :hover dan :active

Tentukan efek fokus secara global. Target utamanya adalah elemen input bertipe date, email, number, tel, text dan url serta select dan textarea:

input:focus,
select:focus,
textarea:focus {background-color:#ffa}

Setelah itu buat efek :focus, :hover dan :active untuk elemen-elemen tombol:

/* focus */
button:focus,
input[type="button"]:focus,
input[type="reset"]:focus,
input[type="submit"]:focus {background-color:#00f}

/* hover */
button:hover,
input[type="button"]:hover,
input[type="reset"]:hover,
input[type="submit"]:hover {background-color:#444}

/* active */
button:active,
input[type="button"]:active,
input[type="reset"]:active,
input[type="submit"]:active {background-color:#111}

fieldset dan legend

CSS untuk mengatur tampilan fieldset dan legend:

fieldset {
  margin:0 0 1em;
  padding:1em;
  border:1px solid #333;
}

legend {
  margin:0;
  padding:0 10px;
  font-weight:bold;
}

Efek :disabled

Bisa menggunakan selektor pseudo kelas :disabled, tapi Saya sarankan untuk menggunakan selektor atribut saja yang memiliki dukungan peramban lebih bagus:

button[disabled],
input[disabled],
select[disabled],
textarea[disabled] {
  opacity:.7; /* buat warnanya menjadi kabur */
  cursor:default; /* fallback */
  cursor:not-allowed; /* CSS3 */
}

Efek :readonly

Hanya untuk elemen formulir masukan teks dan area teks:

input[type="date"][readonly],
input[type="email"][readonly],
input[type="number"][readonly],
input[type="tel"][readonly],
input[type="text"][readonly],
input[type="url"][readonly],
textarea[readonly],
input[type="date"][readonly]:focus,
input[type="email"][readonly]:focus,
input[type="number"][readonly]:focus,
input[type="tel"][readonly]:focus,
input[type="text"][readonly]:focus,
input[type="url"][readonly]:focus,
textarea[readonly]:focus {
  background-color:#eee;
  cursor:default;
}

Mengubah Warna Placeholder

Berikut ini beberapa selektor CSS elemen pseudo dengan prefiks khusus yang berbeda-beda pada setiap peramban. Untuk alasan yang tidak Saya tahu, semua selektor ini tidak bisa digabungkan dengan tanda koma:

::-webkit-input-placeholder {color:#999} /* WebKit */
:-ms-input-placeholder {color:#999} /* IE 9+ */
::-moz-placeholder {color:#999} /* Firefox 19+ */
:-moz-placeholder {color:#999} /* Firefox 18- */
:placeholder {color:#999} /* W3C */

:focus::-webkit-input-placeholder {color:#b9b989}
:focus:-ms-input-placeholder {color:#b9b989}
:focus::-moz-placeholder {color:#b9b989}
:focus:-moz-placeholder {color:#b9b989}
:focus:placeholder {color:#b9b989}

Yap!

Itu adalah garis besarnya. Beberapa yang lain di bawah ini mungkin bisa Anda tambahkan tapi ini spesifik untuk peramban WebKit:

/* mengubah tampilan simbol panah pada elemen `<select>` */
select {
  -webkit-appearance:none;
  background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB90MEg4aKjycyUMAAABJSURBVDjLYzQ0NPzPQCE4d+4cIzKfiYEGYNTQkWwoC450h1ODkZEReS7FpZEYA/F6H90AYg0kGKYwg0gxkKiIItXA0XQ6hAwFADv7Cz1+RA3TAAAAAElFTkSuQmCC');
  background-repeat:no-repeat;
  background-position:100% 50%;
}

select[multiple],
select[size] {background-image:none}

/* mengubah tampilan tombol pada elemen `<input type="file">` */
input[type="file"] {-webkit-appearance:none}
input[type="file"]::-webkit-file-upload-button {
  -webkit-appearance:none;
  display:inline-block;
  vertical-align:top;
  background-color:#333;
  color:white;
  font-size:11px;
  font-weight:bold;
  margin:0;
  padding:2px 5px;
  border:none;
  cursor:pointer;
}

/* `<input type="range">` */
input[type="range"] {
  -webkit-appearance:none;
  height:0;
  padding:1px 0;
  border:1px solid #333;
  background-color:white;
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance:none;
  margin:0;
  padding:0;
  border:none;
  background-color:#333;
  width:10px;
  height:18px;
  cursor:w-resize;
}

input[type="range"]::-webkit-slider-thumb:hover {background-color:#444}
input[type="range"]::-webkit-slider-thumb:active {background-color:#111}

Beberapa tautan yang Saya sarankan untuk mempelajari hal-hal terkait Shadow DOM:


Berikut ini adalah hasil akhir untuk semua hal yang telah Saya jelaskan di atas. Ini bisa dikatakan sebagai kerangka dasar, sehingga Anda bisa cukup salin-tempel kode ini saja dengan aman ke dalam berkas CSS pada setiap awal mendesain:

/* TAHAP PEMBENTUKAN ULANG */

button,
input,
select,
textarea {
  display:inline-block; /* alternatif yang lebih baik dibandingkan `display:inline` */
  vertical-align:middle; /* posisikan elemen ke tengah secara vertikal terhadap teks */
  width:170px; /* tentukan lebar elemen secara umum */
  margin:1px 0; /* tentukan `margin` elemen secara umum */
  padding:4px; /* tentukan `padding` elemen secara umum */
  font:normal normal 13px/normal Arial,Sans-Serif; /* tentukan tipe fon secara umum */
  color:#333; /* tentukan warna teks secara umum */
  line-height:normal; /* tentukan `line-height` secara umum (deklarasi `line-height` pada selektor `font` di atas biasanya tidak bekerja pada elemen `<button>`) */
  background-color:white; /* tentukan warna latar secara umum */
  border:1px solid #333; /* tentukan `border` secara umum */

  /* deklarasikan `box-sizing` yang seragam */
  -webkit-box-sizing:border-box;
  -moz-box-sizing:border-box;
  box-sizing:border-box;

  /* hapus outline jika mungkin */
  outline:none;
  outline-offset:-2px;
}


/* TOMBOL */

button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
  width:auto; /* mengembalikan ukuran lebar ke keadaan semula */
  background-color:#333; /* tentukan warna latar yang berbeda untuk elemen-elemen tombol */
  color:white; /* tentukan warna teks yang berbeda untuk elemen-elemen tombol */

  /* buat `padding` kiri dan kanan menjadi lebih lebar untuk membuatnya lebih gemuk */
  padding-right:8px;
  padding-left:8px;

  font-weight:bold; /* buat teks menjadi tebal */
  cursor:pointer; /* ubah kursor menjadi `pointer` untuk kenyamanan */
  border-color:transparent; /* opsional */
}


/* PERBAIKI DIMENSI BEBERAPA ELEMEN INI */

/* hilangkan nilai `width`, `border`, `padding`, `background` yang telah dibuat sebelumnya pada elemen-elemen ini */
input[type="checkbox"],
input[type="image"],
input[type="radio"] {
  width:auto;
  padding:0;
  background:none;
  border:none;
  cursor:pointer;
}

/*
Anda mungkin akan membutuhkan ini untuk memastikan agar
posisi checkbox dan radio bisa berada tepat di tengah secara vertikal.
Saya mengomentari deklarasi CSS ini dan tidak menjelaskannya
secara khusus di atas karena Saya pikir ini adalah
praktek Magic Number yang tidak disarankan. 

input[type="checkbox"],
input[type="radio"] {
  position:relative;
  top:-2px;
}

*/

/* set tipe kursor ke `pointer` untuk kenyamanan */
input[type="color"],
input[type="file"],
label,
select {
  display:inline-block;
  vertical-align:middle;
  cursor:pointer;
}

/* textarea */
textarea {
  overflow:auto;
  display:block; /* set sebagai elemen blok */
  width:100%; /* buat lebarnya menjadi 100% */
  resize:vertical; /* agar `textarea` hanya bisa diubah ukurannya secara vertikal (lainnya: `both`, `horizontal`, `none`) */
}


/* MENORMALKAN ::-moz-focus-inner PADA TOMBOL-TOMBOL DI FIREFOX */

button::-moz-focus-inner,
input::-moz-focus-inner {
  margin:0;
  padding:0;
  border:none;
  outline:none;
}


/* PSEUDO KELAS - :hover, :focus, :active */

/* focus */
input:focus,
select:focus,
textarea:focus {background-color:#ffa}

/* focus */
button:focus,
input[type="button"]:focus,
input[type="reset"]:focus,
input[type="submit"]:focus {background-color:#00f}

/* hover */
button:hover,
input[type="button"]:hover,
input[type="reset"]:hover,
input[type="submit"]:hover {background-color:#444}

/* active */
button:active,
input[type="button"]:active,
input[type="reset"]:active,
input[type="submit"]:active {background-color:#111}


/* FIELDSET & LEGEND */

fieldset {
  margin:0 0 1em;
  padding:1em;
  border:1px solid #333;
}

legend {
  margin:0;
  padding:0 10px;
  font-weight:bold;
}


/* DISABLED */

button[disabled],
input[disabled],
select[disabled],
textarea[disabled] {
  opacity:.7; /* buat warnanya menjadi kabur */
  cursor:default; /* fallback */
  cursor:not-allowed; /* CSS3 */
}


/* READONLY */

input[type="date"][readonly],
input[type="email"][readonly],
input[type="number"][readonly],
input[type="tel"][readonly],
input[type="text"][readonly],
input[type="url"][readonly],
textarea[readonly],
input[type="date"][readonly]:focus,
input[type="email"][readonly]:focus,
input[type="number"][readonly]:focus,
input[type="tel"][readonly]:focus,
input[type="text"][readonly]:focus,
input[type="url"][readonly]:focus,
textarea[readonly]:focus {
  background-color:#eee;
  cursor:default;
}


/* PLACEHOLDER */

::-webkit-input-placeholder {color:#999} /* WebKit */
:-ms-input-placeholder {color:#999} /* IE 9+ */
::-moz-placeholder {color:#999} /* Firefox 19+ */
:-moz-placeholder {color:#999} /* Firefox 18- */
:placeholder {color:#999} /* W3C */

:focus::-webkit-input-placeholder {color:#b9b989}
:focus:-ms-input-placeholder {color:#b9b989}
:focus::-moz-placeholder {color:#b9b989}
:focus:-moz-placeholder {color:#b9b989}
:focus:placeholder {color:#b9b989}

Lihat Demo

Setiap kali Anda mendesain elemen atom, selalu pastikan untuk menyelesaikan masalah-masalah di atas terlebih dahulu. Jika tidak, mungkin Anda akan mengalami berbagai kesulitan saat menangani masalah penampilan pada peramban-peramban tertentu.

Selain itu setidaknya Anda baru bisa/boleh mendesain tampilan elemen-elemen formulir setelah Anda menyelesaikan masalah tampilan elemen-elemen artikel. Setelah itu, Anda bisa memulai untuk menambahkan efek gradiasi, bayangan dan menyesuaikan warna-warna elemen-elemen formulir yang ada sesuai kehendak:

Lihat Demo

Labels: ,

Sunday, September 29, 2013

Memposisikan Judul dan Ringkasan Posting di Samping Thumbnail atau Thumbnail di atas Judul dan Ringkasan Posting

Bagaimana caranya memposisikan judul dan ringkasan posting di samping thumbnail, atau bagaimana cara memposisikan thumbnail di atas judul dan ringkasan posting (biasanya untuk membuat templat List & Masonry Grid)? Di sini Saya mencoba untuk membuat kode XML posting khusus yang Saya buat sefleksibel mungkin untuk keperluan modifikasi di masa datang. Kode ini sudah mencakup modifikasi ringkasan posting, sehingga jika Anda sudah mengimplementasikan modifikasi ini, maka Anda tidak perlu lagi repot-repot untuk mengimplementasikan tutorial pembuatan posting auto read-more.

Namun sebelum melakukan modifikasi ini, perlu dipertimbangkan bahwa nanti Anda akan mengubah struktur posting secara keseluruhan, sehingga beberapa kustomisasi lama Anda seperti penambahan widget artikel terkait, widget berbagi dan semuanya akan menghilang. Disarankan untuk menyimpan salinan templat Anda terlebih dahulu sebelum melakukan modifikasi ini.

Kode XML

Langkah pertama adalah mengedit XML templat. Kode XML ini cukup diterapkan sekali saja. Mengenai pengaturan posisi setiap elemen bisa kita lakukan dengan CSS yang sudah Saya tuliskan di bawah:

<b:includable id='post' var='post'>

  <article expr:class='&quot;_post _post-&quot; + data:blog.pageType' expr:id='&quot;post-&quot; + data:post.id'>

    <b:if cond='data:blog.pageType != &quot;item&quot;'>
      <b:if cond='data:blog.pageType != &quot;static_page&quot;'>
        <div class='_post-part _post-thumbnail-area'>
          <b:if cond='data:post.thumbnailUrl'>
            <img class='_post-thumbnail' expr:alt='data:post.title' expr:src='resizeImage(data:post.thumbnailUrl, 200, &quot;1:1&quot;)' height='200' width='200'/>
          </b:if>
        </div> <!-- ._post-thumbnail-area -->
      </b:if>
    </b:if>

    <div class='_post-part _post-body-area'>

      <h3 class='_post-title'>
        <b:if cond='data:post.title'>
          <b:if cond='data:post.link'>
            <a expr:href='data:post.link'><data:post.title/></a>
          <b:else/>
            <b:if cond='data:post.url'>
              <b:if cond='data:blog.url != data:post.url'>
                <a expr:href='data:post.url'><data:post.title/></a>
              <b:else/>
                <data:post.title/>
              </b:if>
            <b:else/>
              <data:post.title/>
            </b:if>
          </b:if>
        <b:else/>
          [Untitled]
        </b:if>
      </h3> <!-- ._post-title -->

      <div class='_post-body'>
        <b:if cond='data:blog.pageType == &quot;item&quot;'>
          <data:post.body/>
        <b:else/>
          <b:if cond='data:blog.pageType == &quot;static_page&quot;'>
            <data:post.body/>
          <b:else/>
            <b:if cond='data:post.snippet'>
              <data:post.snippet/>
            <b:else/>
              No content.
            </b:if>
          </b:if>
        </b:if>
      </div> <!-- ._post-body -->

      <footer class='_post-footer'>
        <div class='_post-footer-line _post-footer-line-1'>
          <span class='_post-author vcard'>
            <b:if cond='data:top.showAuthor'>
              <data:top.authorLabel/> <span class='fn'>
              <b:if cond='data:post.authorProfileUrl'>
                <a class='g-profile' expr:href='data:post.authorProfileUrl' rel='author' title='Author Profile'><data:post.author/></a>
              <b:else/>
                <span class='g-profile'><data:post.author/></span>
              </b:if>
              </span>
            </b:if>
          </span> <span class='_post-time'>
          <b:if cond='data:top.showTimestamp'>
            <data:top.timestampLabel/> <a class='_post-time-link' expr:href='data:post.url' rel='bookmark' title='Permanent Link'><time class='_post-published published' expr:datetime='data:post.timestampISO8601'><data:post.timestamp/></time></a>
          </b:if>
          </span> <span class='_post-comment-link'>
          <b:if cond='data:blog.pageType != &quot;item&quot;'>
            <b:if cond='data:blog.pageType != &quot;static_page&quot;'>
              <b:if cond='data:post.allowComments'>
                <a expr:href='data:post.url + &quot;#comments&quot;'><data:post.commentLabelFull/></a>
              </b:if>
            </b:if>
          </b:if>
          </span>
        </div> <!-- ._post-footer-line-1 -->
        <div class='_post-footer-line _post-footer-line-2'>
          <span class='_post-labels'>
            <b:if cond='data:post.labels'>
              <data:postLabelsLabel/> <b:loop values='data:post.labels' var='label'>
                <a expr:href='data:label.url' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != &quot;true&quot;'>, </b:if>
              </b:loop>
            </b:if>
            <!-- b:include data='post' name='postQuickEdit'/ -->
          </span>
        </div> <!-- ._post-footer-line-2 -->
      </footer> <!-- ._post-footer -->

    </div> <!-- ._post-body-area -->

  </article> <!-- ._post -->

</b:includable>

Salin semua kode di atas untuk menggantikan kode yang tampak seperti ini di dalam templat:

<b:includable id='post' var='post'> ... </b:includable>

Langkah berikutnya adalah menambahkan CSS khusus. Pilih salah satu saja.

Tata Letak 1: Thumbnail di Sebelah Kiri Judul dan Ringkasan Posting

Post Thumbnail on the Left
Thumbnail di sebelah kiri judul dan ringkasan posting.

Salin kode CSS ini lalu letakkan di atas ]]></b:skin> atau </style>:

/*!
Thumbnail width: 200
Thumbnail height: 200
*/

._post {
  background-color:white;
  height:200px; /* Thumbnail height */
  margin:0 0 10px;
  overflow:hidden;
  *zoom:1;
}

._post:after {
  content:" ";
  display:block;
  clear:both;
}

._post-title {
  font:normal bold 20px/1.2 Arial,Sans-Serif;
  margin:0 0 10px;
  padding:0;
}

._post-thumbnail-area {
  width:200px; /* Thumbnail width */
  height:200px; /* Thumbnail height */
  background-color:#2D3957;
  float:left;
  overflow:hidden;
}

._post-thumbnail {
  display:block;
  width:100%;
  height:100%;
  max-width:none;
  max-height:none;
  min-width:0;
  min-height:0;
  margin:0;
  padding:0;
  border:none;
  outline:none;
  position:static;
}

._post-body-area {
  padding:20px;
  margin-left:200px; /* Thumbnail width */
  font-size:11px;
}

._post-footer {
  margin:10px 0 0;
  padding:10px 0 0;
  border-top:1px dotted #ddd;
  font:normal bold 8px/1.5 Verdana,Tahoma,Arial,Sans-Serif;
  text-transform:uppercase;
  color:#999;
}

/* Item + Static Page */
._post-item,
._post-static_page {height:auto}

._post-item ._post-body-area,
._post-static_page ._post-body-area {
  margin:0;
  padding:20px;
  font-size:13px;
}

._post-item ._post-title,
._post-static_page ._post-title {font-size:40px}

Tata Letak 2: Thumbnail di Sebelah Atas Judul dan Ringkasan Posting

Thumbnail Before Post Title and Summary
Thumbnail di sebelah atas judul dan ringkasan posting.

Salin kode CSS ini lalu letakkan di atas ]]></b:skin> atau </style>:

/*!
Thumbnail width: 300
Thumbnail height: 300
*/

._post {
  background-color:white;
  width:300px; /* Thumbnail width */
  margin:0 10px 10px 0;
  overflow:hidden;
  *zoom:1;
  /* float:left; */
}

._post:after {
  content:" ";
  display:block;
  clear:both;
}

._post-title {
  font:normal bold 16px/1.2 Arial,Sans-Serif;
  margin:0 0 10px;
  padding:0;
}

._post-thumbnail-area {
  width:300px; /* Thumbnail width */
  height:300px; /* Thumbnail height */
  background-color:#2D3957;
  overflow:hidden;
}

._post-thumbnail {
  display:block;
  width:100%;
  height:100%;
  max-width:none;
  max-height:none;
  min-width:0;
  min-height:0;
  margin:0;
  padding:0;
  border:none;
  outline:none;
  position:static;
}

._post-body-area {
  padding:20px;
  margin:10px 0 0;
  font-size:11px;
}

._post-footer {
  margin:10px 0 0;
  padding:10px 0 0;
  border-top:1px dotted #ddd;
  font:normal bold 8px/1.5 Verdana,Tahoma,Arial,Sans-Serif;
  text-transform:uppercase;
  color:#999;
}

/* Item + Static Page */
._post-item,
._post-static_page {width:auto}

._post-item ._post-body-area,
._post-static_page ._post-body-area {
  margin:0;
  padding:20px;
  font-size:13px;
}

._post-item ._post-title,
._post-static_page ._post-title {font-size:40px}

Kode yang Saya beri tanda adalah resolusi gambar yang akan Anda terapkan. Ini tergantung dari ukuran standar masing-masing gambar posting di atas, yang sudah Saya sertakan dalam komentar CSS.

Simpan perubahan.


Struktur Posting yang Tercipta

Berikut ini adalah diagram markup HTML yang akan tercipta secara garis besar. Semoga bisa sedikit membantu untuk memberikan gambaran modifikasi lanjutan:

  • ._post
    • ._post-part._post-thumbnail-area
      • ._post-thumbnail
    • ._post-part._post-body-area
      • ._post-title
      • ._post-body
      • ._post-footer
        • ._post-footer-line._post-footer-line-1
          • ._post-author
          • ._post-time
          • ._post-comment-link
        • ._post-footer-line._post-footer-line-2
          • ._post-labels
._post {}
._post-part {}
._post-thumbnail-area {}
._post-body-area {}
._post-title {}
._post-body {}
._post-footer {}
._post-footer-line {}
._post-footer-line-1 {}
._post-footer-line-2 {}
._post-author {}
._post-time {}
._post-comment-link {}
._post-labels {}

Catatan Tambahan: Setelah ini lebih baik Anda hapus beberapa kode CSS yang memiliki selektor seperti ini. Markup posting sudah berubah secara total, sehingga CSS ini sudah tidak diperlukan lagi:

.post {}
.post-title {}
.post-body {}
.post-footer {}
.post-footer-line {}
.post-footer-line-1 {}
.post-footer-line-2 {}
.post-footer-line-3 {}
.post-header-line {}
.post-header-line-1 {}
.post-header-line-2 {}
.post-header-line-3 {}
.post-author {}
.post-timestamp {}
.post-comment-link {}
.post-labels {}

Labels: , ,

Saturday, June 1, 2013

Cross Browser Scroll to Top Animation (JavaScript)

/*! http://stackoverflow.com/questions/8917921/cross-browser-javascript-not-jquery-scroll-to-top-animation */
function scrollTo(element, to, duration) {

    // http://robertpenner.com/easing/
    // t = current time, b = start value, c = change in value, d = duration
    Math.easeInOutQuad = function(t, b, c, d) {
        t /= d / 2;
        if (t < 1) return c / 2 * t * t + b;
        t--;
        return -c / 2 * (t * (t - 2) - 1) + b;
    };

    var start = element.scrollTop,
        change = to - start,
        currentTime = 0,
        increment = 20,
        animateScroll = function() {
            currentTime += increment;
            var val = Math.easeInOutQuad(currentTime, start, change, duration);
            element.scrollTop = val;
            if (currentTime < duration) {
                setTimeout(animateScroll, increment);
            }
        };

    animateScroll();

}

Penggunaan

element digunakan untuk mewakili elemen yang ingin diberi efek animasi, to mewakili jarak arah gulungan ke atas, duration mewakili durasi animasi:

<button onclick="scrollTo(document.body, 0, 1000);">Scroll to Top</button>

Lihat Demo

Labels: , ,

Thursday, May 23, 2013

Framework CSS · Utamakan Konsistensi Tampilan Artikel Sebelum Layout

CSS Framework

Yang Saya maksudkan di sini adalah, jadikan tampilan artikel sebagai prioritas utama sebelum memulai pondasi desain/rancangan tema/template. Mengingat kebiasaan buruk yang sering terjadi adalah kita membentuk hasil jadinya terlebih dahulu kemudian baru merancang tampilan-tampilan paragraf, kuota dan blok kode. Padahal, dengan merancang elemen-elemen kecil dan umum tersebut terlebih dahulu, kita bisa memastikan bahwa tampilan akhir nantinya akan menjadi lebih konsisten.

Merancang penampilan secara keseluruhan dan melanjutkannya dengan merancang tampilan elemen artikel hanya akan menambah waktu kerja kita menjadi dua kali lipat lebih lama dan lebih rumit tanpa kita sadari. Sebagai contoh, saat kita merancang tampilan posting, saat itu kita juga akan menentukan tampilan judulnya. Setelah itu kita akan merancang tampilan sidebar dan footer, kemudian juga akan menentukan tampilan judulnya dan seterusnya:

Contoh Buruk

/* posting */
.post {
  font-family:Arial,Sans-Serif;
  font-size:12px;
  color:#333;
}

.post h2 {
  font-size:30px;
  font-weight:bold;
  margin-bottom:15px;
  color:#3399ff;
}

/* sidebar */
.sidebar {
  float:right;
  width:200px;
  overflow:hidden;
  word-wrap:break-word;
  font-family:Arial,Sans-Serif;
  color:#222;
}

.sidebar h2 {
  font-weight:normal;
  font-size:12px;
  text-transform:uppercase;
  margin-bottom:15px;
}

/* footer */
.footer {
  background-color:#2f2f2f;
  font-family:Georgia,Serif;
  font-size:13px;
  color:#666;
}

.footer h2 {
  font-weight:normal;
  font-size:20px;
  color:#f5f5f5;
}

Terlalu banyak pekerjaan hanya untuk membuat beberapa blok area saja. Seharusnya pekerjaan ini bisa menjadi lebih singkat apabila kita merancang framework elemen-elemen artikel terlebih dahulu secara global. Sudah ada beberapa framework yang tersedia untuk mengatasi kebiasaan buruk ini, misalnya Normalize dan HTML5 Boilerplate. Tapi di sini kita akan mencoba untuk membuatnya sendiri. Dimulai dengan CSS reset.

Merancang Framework CSS

CSS Reset

CSS ini akan menormalkan semua tampilan elemen HTML —kecuali elemen-elemen formulir— menjadi seragam/normal. Dimulai dari ukuran, warna, margin, padding, dimensi dan juga ketebalannya. Mengawali rancangan elemen artikel dengan CSS reset akan mempermudah kita dalam merancang tampilan elemen-elemen HTML setelah ini:

/* http://meyerweb.com/eric/tools/css/reset/
   v2.0 | 20110126
   License: none (public domain)
*/
html,body,div,span,
applet,object,iframe,
h1,h2,h3,h4,h5,h6,
p,blockquote,pre,
a,abbr,acronym,address,
big,cite,code,del,dfn,
em,img,ins,kbd,q,
s,samp,small,strike,strong,
sub,sup,tt,
var,b,u,i,center,
dl,dt,dd,
ol,ul,li,
fieldset,form,label,legend,
table,caption,tbody,tfoot,thead,tr,th,td,
article,aside,canvas,details,embed,
figure,figcaption,
footer,header,hgroup,menu,nav,
output,ruby,
section,summary,
time,mark,audio,video {
  margin:0;
  padding:0;
  border:0;
  font-size:100%;
  font:inherit;
  vertical-align:baseline;
}

/* HTML5 display-role reset for older browsers */
article,aside,details,
figcaption,figure,footer,
header,hgroup,menu,nav,section {
  display:block;
}

body {
  line-height:1;
}

ol,ul {
  list-style:none;
}

blockquote,q {
  quotes:none;
}

blockquote:before,
blockquote:after,
q:before,
q:after {
  content:'';
  content:none;
}

table {
  border-collapse:collapse;
  border-spacing:0;
}

Elemen <BODY>

Berikutnya kita atur ukuran huruf, tipe huruf, line-height dan warna huruf secara global pada elemen <body>:

body {
  /* `font-style:normal`,
     `font-weight:normal`,
     `font-size:13px`,
     `line-height:1.4em`,
     `font-family:Arial,Sans-Serif` */
  font:normal normal .8125em/1.4 Arial,Sans-Serif;
  background-color:white; /* warna latar secara global */
  color:#333; /* warna huruf secara global */
}

Huruf Tebal, Huruf Miring dan Elemen-Elemen Kecil Lainnya

Karena tampilan elemen HTML sudah diatur ulang oleh CSS reset, maka kita perlu mengatur beberapa tampilan elemen menjadi seperti semula:

/* huruf tebal */
strong,b {
  font-weight:bold;
}

/* citation & huruf miring (italic + emphasis) */
cite,em,i {
  font-style:italic;
}

/* tautan */
a {
  text-decoration:none;
}

a:hover {
  text-decoration:underline;
}

/* Internet Explorer akan menambahkan border pada gambar
   yang diliputi oleh tautan */
a img {
  border:none;
}

/* abbreviation & acronym */
abbr,
acronym {
  border-bottom:1px dotted;
  cursor:help;
}

/* superscript & subscript */
sup,
sub {
  vertical-align:baseline;
  position:relative;
  top:-.4em;
  font-size:86%;
}

sub {
  top:.4em;
}

/* huruf kecil */
small {
  font-size:86%;
}

/* tombol keyboard */
kbd {
  font-size:80%;
  border:1px solid #999;
  padding:2px 5px;
  border-bottom-width:2px;
  border-radius:3px;
}

/* penanda teks */
mark {
  background-color:#ffce00;
  color:black;
}

Margin Paragraf

Paragraf membutuhkan kerenggangan antara teks paragraf yang satu dengan yang lainnya. Begitu pula elemen-elemen lain yang biasa menyertainya seperti kuota, tabel, figur, formulir, daftar dan blok kode:

p,blockquote,pre,
table,figure,hr,form,
ol,ul,dl {
  margin:1.5em 0;
}

Elemen Heading

Atur elemen heading dengan line-height menjadi normal dan huruf menjadi tebal. Tentukan juga margin heading secara global sebelum kemudian kita melanjutkannya dengan menentukan ukuran elemen heading sesuai dengan level/tingkatannya:

h1,h2,h3,h4,h5,h6 {
  font-weight:bold;
  line-height:normal;
  margin:1.5em 0 0;
}

h1 {font-size:200%}
h2 {font-size:180%}
h3 {font-size:160%}
h4 {font-size:140%}
h5 {font-size:120%}
h6 {font-size:100%}

Elemen Daftar

Jangan biarkan elemen daftar menjadi terlalu sejajar dengan paragraf karena pada umumnya itu hanya akan membuat mata kita menjadi merasa tidak nyaman dan tertekan. Posisikan elemen daftar menjadi sedikit menjorok ke depan untuk menciptakan kesan istirahat/fokus:

/* ordered, unordered list & description list */
ol,ul,dl {margin-left:3em}

ol {list-style:decimal outside} /* atur ulang `list-style` pada elemen `<ol>` */
ul {list-style:disc outside} /* atur ulang `list-style` pada elemen `<ul>` */
li {margin:.5em 0} /* beri sedikit jarak atas dan bawah pada elemen `<li>` untuk item daftar dengan konten yang panjang */

dt {font-weight:bold}
dd {margin:0 0 .5em 2em}

Elemen Formulir

Biasanya ini tidak terlalu penting. Tetapi setidaknya samakanlah tipe dan ukuran huruf sesuai dengan huruf pada elemen induknya. Mengenai tampilan selanjutnya seperti warna latar dan efek :hover bisa ditentukan nanti setelah framework selesai dibuat:

input,
button,
select,
textarea {
  font:inherit;
  font-size:100%;
  line-height:normal;
  vertical-align:baseline;
}

/* mengeset `box-sizing` menjadi `border-box` pada `<textarea>` untuk mengatasi masalah
   pengguna yang sering kesulitan menentukan lebar akurat
   pada elemen ini menjadi `100%` ketika menggunakan logika box-model yang lama */
textarea {
  display:block;
  -webkit-box-sizing:border-box;
  -moz-box-sizing:border-box;
  box-sizing:border-box;
}

Blok Kode dan Kuota

<pre> dan <blockquote> biasanya mendapatkan perlakuan khusus mengingat elemen ini biasa kita gunakan untuk menyatakan hal-hal yang penting. Blok kode digunakan untuk menyatakan kode yang perlu dicatat/dipahami dan kuota digunakan untuk menyatakan teks yang perlu diingat atau direnungkan:

pre,
code {
  font-family:"Courier New",Courier,Monospace;
  color:inherit;
}

/* jika perlu tentukan juga warna latar dan huruf */
pre {
  white-space:pre;
  word-wrap:normal;
  overflow:auto;
}

blockquote {
  margin-left:2em;
  margin-right:2em;
  border-left:4px solid #ccc;
  padding-left:1em;
  font-style:italic;
}

Tabel

Seperti yang pernah Saya nyatakan pada tutorial pembuatan tabel dengan HTML, disarankan untuk menentukan border dan padding pada tabel yang memiliki atribut border=1 saja demi keamanan:

table[border="1"] th,
table[border="1"] td,
table[border="1"] caption {
  border:1px solid;
  padding:.5em 1em;
  text-align:left;
  vertical-align:top;
}

th {
  font-weight:bold;
}

table[border="1"] caption {
  border:none;
  font-style:italic;
}

Hasil Akhir

/* http://meyerweb.com/eric/tools/css/reset/
   v2.0 | 20110126
   License: none (public domain)
*/
html,body,div,span,
applet,object,iframe,
h1,h2,h3,h4,h5,h6,
p,blockquote,pre,
a,abbr,acronym,address,
big,cite,code,del,dfn,
em,img,ins,kbd,q,
s,samp,small,strike,strong,
sub,sup,tt,
var,b,u,i,center,
dl,dt,dd,
ol,ul,li,
fieldset,form,label,legend,
table,caption,tbody,tfoot,thead,tr,th,td,
article,aside,canvas,details,embed,
figure,figcaption,
footer,header,hgroup,menu,nav,
output,ruby,
section,summary,
time,mark,audio,video {
  margin:0;
  padding:0;
  border:0;
  font-size:100%;
  font:inherit;
  vertical-align:baseline;
}

/* HTML5 display-role reset for older browsers */
article,aside,details,
figcaption,figure,footer,
header,hgroup,menu,nav,section {
  display:block;
}

body {
  line-height:1;
}

ol,ul {
  list-style:none;
}

blockquote,q {
  quotes:none;
}

blockquote:before,
blockquote:after,
q:before,
q:after {
  content:'';
  content:none;
}

table {
  border-collapse:collapse;
  border-spacing:0;
}

/* ===============
   FRAMEWORK START
   =============== */
body {
  font:normal normal .8125em/1.4 Arial,Sans-Serif;
  background-color:white;
  color:#333;
}

strong,b {
  font-weight:bold;
}

cite,em,i {
  font-style:italic;
}

a {
  text-decoration:none;
}

a:hover {
  text-decoration:underline;
}

a img {
  border:none;
}

abbr,
acronym {
  border-bottom:1px dotted;
  cursor:help;
}

sup,
sub {
  vertical-align:baseline;
  position:relative;
  top:-.4em;
  font-size:86%;
}

sub {
  top:.4em;
}

small {
  font-size:86%;
}

kbd {
  font-size:80%;
  border:1px solid #999;
  padding:2px 5px;
  border-bottom-width:2px;
  border-radius:3px;
}

mark {
  background-color:#ffce00;
  color:black;
}

p,blockquote,pre,
table,figure,hr,form,
ol,ul,dl {
  margin:1.5em 0;
}

hr {
  height:1px;
  border:none;
  background-color:#666;
}

h1,h2,h3,h4,h5,h6 {
  font-weight:bold;
  line-height:normal;
  margin:1.5em 0 0;
}

h1 {font-size:200%}
h2 {font-size:180%}
h3 {font-size:160%}
h4 {font-size:140%}
h5 {font-size:120%}
h6 {font-size:100%}

ol,ul,dl {margin-left:3em}
ol {list-style:decimal outside}
ul {list-style:disc outside}
li {margin:.5em 0}

dt {font-weight:bold}
dd {margin:0 0 .5em 2em}

input,
button,
select,
textarea {
  font:inherit;
  font-size:100%;
  line-height:normal;
  vertical-align:baseline;
}

textarea {
  display:block;
  -webkit-box-sizing:border-box;
  -moz-box-sizing:border-box;
  box-sizing:border-box;
}

pre,
code {
  font-family:"Courier New",Courier,Monospace;
  color:inherit;
}

pre {
  white-space:pre;
  word-wrap:normal;
  overflow:auto;
}

blockquote {
  margin-left:2em;
  margin-right:2em;
  border-left:4px solid #ccc;
  padding-left:1em;
  font-style:italic;
}

table[border="1"] th,
table[border="1"] td,
table[border="1"] caption {
  border:1px solid;
  padding:.5em 1em;
  text-align:left;
  vertical-align:top;
}

th {
  font-weight:bold;
}

table[border="1"] caption {
  border:none;
  font-style:italic;
}

Sampai di sini Saya rasa sudah cukup untuk dijadikan sebagai dasar. Setelah ini Anda bisa melanjutkan untuk membuat kelas-kelas produktif seperti .hidden, .visually-hidden, .btn dan yang lainnya untuk keperluan rancangan tingkat lanjut:

.hidden,[hidden] {
  display:none;
}

.invisible {
  visibility:hidden;
}

.visually-hidden {
  position:absolute !important;
  overflow:hidden;
  clip:rect(0px 0px 0px 0px);
  clip:rect(0px,0px,0px,0px);
  height:1px;
  width:1px;
  margin:-1px 0 0;
  padding:0;
  border:0;
}

.clear {
  display:block;
  clear:both;
}

.clearfix:before,
.clearfix:after {
  content:"";
  display:table;
}

.clearfix:after {
  clear:both;
}

.clearfix {
  *zoom:1;
}

.pull-left {
  float:left;
}

.pull-right {
  float:right;
}

.centered {
  clear:both;
  display:block;
  text-align:center;
  margin-left:auto;
  margin-right:auto;
}

.text-center {
  text-align:center;
}

.text-left {
  text-align:left;
}

.text-right {
  text-align:right;
}

.text-justify {
  text-align:justify;
}

.btn {
  color:white;
  background-color:black;
  /* ... */
}

.btn:hover {
  /* ... */
}

.btn:active {
  /* ... */
}

Beberapa nama kelas di atas akan sangat mudah Anda temui pada framework HTML5 Boilerplate dan Twitter Bootstrap (Twitter Bootstrap juga memakai HTML5 Boilerplate). Anda akan mengetahui fungsi-fungsi kelas tersebut, mengapa kelas tersebut dibuat dan mengapa kelas-kelas tersebut menjadi semacam “standar” saat Anda mempelajarinya.

Beralih ke Framework Buatan Sendiri

Untuk mempercepat pekerjaan, yang terpenting sebenarnya adalah framework. Namun jika Anda tidak mengerti apa dan bagaimana framework itu dibuat dan digunakan, maka hasil akhirnya nanti akan sama saja. Memulai membuat framework sendiri Saya pikir jauh lebih baik dibandingkan hanya sekedar menyalin dan menempel kode dari framework lain yang sudah ada. Mengikuti dan mempelajari bagaimana mereka menciptakan framework seharusnya lebih diutamakan dibandingkan hanya sekedar memakainya. Karena dengan mempelajari bagaimana sebuah framework terbentuk, maka dari situ Anda bisa lebih cerdas di dalam mencontoh dan menyaring apa-apa saja yang sebenarnya diperlukan dan apa saja yang sebenarnya tidak diperlukan menurut kebutuhan Anda saat itu untuk keperluan yang lebih spesifik dan efisien tentunya:

Lihat Demo

Labels: , , ,

Wednesday, May 22, 2013

Jangan Mendeklarasikan `font-weight` dan `font-style` pada Font yang Tidak Memiliki Varian Tersebut

Membandingkan tampilan font Open Sans dengan varian regular saja dan font Open Sans dengan varian yang lengkap.

Ada satu hal yang mungkin tidak Anda sadari bahwa ketika Anda menyatakan font-family pada teks, maka peramban akan mencoba untuk menciptakan efek bold dan italic palsu ketika peramban tidak berhasil menemukan file font bold dan italic pada font terkait. Sebagai contoh, Tahoma hanya memiliki dua varian, yaitu regular dan bold, sehingga hasil tampilan teks pada peramban hanya akan terlihat bagus pada model teks biasa dan tebal:

Tahoma Fonts Preview
Tahoma

Karena sejak awal varian italic tidak pernah ada pada keluarga font Tahoma, maka peramban mencoba untuk merekayasa dimensi font tersebut menjadi italic. Akan tetapi tetap saja, efek italic yang Anda lihat bukanlah italic yang sesungguhnya. Perbedaan akan terlihat jelas pada jenis-jenis font yang memiliki lebih banyak varian. Misalnya Georgia:

Georgia Fonts
Georgia

Georgia memiliki empat varian, termasuk di dalamnya adalah regular, italic, bold bahkan bold-italic. Hal ini memungkinkan peramban untuk menampilkan dimensi font dalam “porsi” yang tepat pada varian font minimal. Yaitu regular, italic, bold dan bold-italic:

Georgia Fonts
Georgia

Hal Buruk yang Sering Saya Lihat

Hal buruk yang sering Saya lihat adalah bahwa seorang pengguna mencoba untuk menyatakan font-weight:bold atau font-style:italic pada keluarga font yang tidak memiliki varian tersebut atau pada keluarga font yang memiliki varian tersebut, akan tetapi varian selain regular tidak pernah disertakan di dalam deklarasi @font-face:

Bebas Neue with Fake Bold EffectBebas Neue with Regular Weight
Gambar 1: Mendeklarasikan ketebalan font heading pada situasi yang salah. Gambar 2: Dimensi font yang sesungguhnya.Keterangan: Bebas Neue pada judul dan Franklin Gothic Medium pada paragraf.

Pada keadaan normal, elemen heading akan memiliki efek tebal secara otomatis. Jadi, jangan lupa untuk mendeklarasikan font-weight dan font-style dengan nilai normal saat Anda sedang menerapkan font kustom yang tidak memiliki varian lengkap untuk elemen ini:

h1,h2,h3,h4,h5,h6 {
  font-family:"Bebas Neue",Sans-Serif;
  font-style:normal;
  font-weight:normal;
}

Mencari tutorial tentang cara menggunakan @font-face, baca di artikel Menggunakan @font-face

Labels: , ,

Monday, April 22, 2013

Membuat Navigasi Halaman AJAX pada Blogger

Prinsipnya sederhana. Di sini Saya menggunakan navigasi Posting Lebih Lama sebagai navigasi AJAX dan menggunakan jQuery $.get() untuk memanggil URL pada navigasi tersebut:

// Menyingkirkan navigasi posting lebih baru (Navigasi ini tidak diperlukan)
$('#blog-pager').find('#blog-pager-newer-link').remove();

// Dasar AJAX navigasi
$('#blog-pager').on("click", "#blog-pager-older-link a", function() {
    $.get(this.href, {}, function(data) {
        // Proses...
    }, "html");
    return false;
});

Kita akan menggunakan elemen .blog-posts untuk memuat posting-posting baru dari halaman selanjutnya.

Menerapkan AJAX pada Navigasi Halaman

Pastikan jQuery sudah terpasang pada template. Masuk ke editor HTML template, kemudian salin kode ini dan letakkan di atas </body>:

<b:if cond='data:blog.pageType != &quot;item&quot;'>
<b:if cond='data:blog.pageType != &quot;static_page&quot;'>
<script>
//<![CDATA[
(function($) {
    var $pager = $('#blog-pager'),
        $posts = $('.blog-posts');
    $pager.find('#blog-pager-newer-link').remove(); // Menyingkirkan navigasi posting lebih baru
    $pager.on("click", "#blog-pager-older-link a", function() {
        $.get(this.href, {}, function(data) {
            var source = $(data).find('.post').length ? $(data) : $('<div></div>');
            $posts.append(source.find('.blog-posts').html()); // Menyisipkan posting
            $pager.html(source.find('#blog-pager-older-link').clone()); // Memperbaharui navigasi
        }, "html");
        $(this).replaceWith('<span>Memuat...</span>'); // Ubah navigasi posting menjadi indikator memuat saat sedang memuat
        return false;
    });
})(jQuery);
//]]>
</script>
</b:if>
</b:if>

Klik Simpan Template.

Sekarang coba buka halaman blog Anda kemudian klik navigasi Posting Lama atau Older Post. Jika navigasi tersebut berubah menjadi teks bertuliskan “memuat...” seperti ini, maka itu artinya AJAX sedang bekerja:

Ini adalah gambar navigasi halaman yang sedang memuat halaman baru dengan AJAX
Indikator sedang memuat

Tunggu sampai posting-posting baru muncul di bawah posting-posting yang sedang terlihat saat ini.

Infinite Scroll (?)

Untuk menciptakan infinite scroll pada sistem navigasi halaman, cukup nyatakan event .scroll() pada $(window) dan cek apakah jarak gulungan layar telah mencapai batas akhir atau belum. Jika ya, picu event .click() pada navigasi AJAX yang telah kita buat sebelumnya.

Dalam kasus ini, Saya menentukan batas akhir gulungan layar bukan berdasarkan tinggi halaman, melainkan berdasarkan posisi navigasi terhadap bagian teratas dari layar:

(function($) {

    var $pager = $('#blog-pager'),
        $posts = $('.blog-posts'),
        loading = false;

    // AJAX
    $pager.find('#blog-pager-newer-link').remove(); // Menyingkirkan navigasi posting lebih baru
    $pager.on("click", "#blog-pager-older-link a", function() {
        $.get(this.href, {}, function(data) {
            var source = $(data).find('.post').length ? $(data) : $('<div></div>');
            $posts.append(source.find('.blog-posts').html());
            $pager.html(source.find('#blog-pager-older-link').clone());
            loading = false;
        }, "html");
        $(this).replaceWith('<span>Memuat...</span>'); // Ubah navigasi posting menjadi indikator memuat saat sedang memuat
        return false;
    });

    // INFINITE SCROLL
    $(window).on("scroll resize", function() {
        // Jika AJAX sedang tidak memuat dan jika jarak gulungan layar + tinggi layar telah mencapai
        // tinggi yang sama dengan/lebih besar dari offset navigasi halaman terhadap bagian teratas dari layar...
        if (!loading && ($(this).scrollTop() + $(this).height()) >= $pager.offset().top) {
            $pager.find('#blog-pager-older-link a').trigger("click"); // Picu event `.click()` pada navigasi AJAX posting
            loading = true; // Mulai antre pemuatan
        }
    });

})(jQuery);

Catatan: JavaScript Auto Read-More akan tereksekusi saat halaman dimuat dengan cara biasa, sehingga jangan kaget jika posting-posting baru yang dimuat oleh AJAX tidak akan terpotong menjadi ringkasan posting. Saya sarankan Anda untuk menggunakan konsep ringkasan posting tanpa JavaScript yang pernah Saya tuliskan sebelumnya di sini.

Labels: , , , ,

Sunday, April 14, 2013

Menggunakan @font-face

Yang dilakukan @font-face kepada file font pada dasarnya hanyalah memanggil file tersebut ke halaman web untuk diberi nama sesuai dengan nama yang ditentukan oleh pengguna agar bisa digunakan di dalam CSS font sebagai font-family:

@font-face {
  font-family:'Nama Font';
  src:url('files/my-font.woff') format('woff');
  font-style:normal;
  font-weight:normal;
}

Fungsi masing-masing kode di atas adalah:

  1. font-family berfungsi untuk menentukan nama font yang datang dari my-font.woff
  2. src digunakan untuk menyatakan di mana font tersebut disimpan
  3. format digunakan untuk menentukan format font
  4. font-style dan font-weight tidak wajib. Bisa dibuang jika memang tidak diperlukan. Dan akan menjadi wajib untuk alasan yang akan Saya jelaskan nanti.

@font-face lebih baik dinyatakan di bagian paling awal CSS untuk memastikan agar file font bisa diunduh sesegera mungkin. Setelah itu, nama font bisa dinyatakan ke elemen mana saja yang Anda inginkan dengan nama font yang telah dinyatakan pada font-family:

@font-face {
  font-family:'Nama Font';
  src:url('files/my-font.woff') format('woff');
  font-style:normal;
  font-weight:normal;
}

body {font-family:"Nama Font"}

Jangan lupa berikan beberapa font fallback dengan nama-nama font yang sudah biasa ada pada komputer Anda untuk berjaga-jaga agar jika font eksternal tersebut gagal dimuat atau terlalu lama dimuat atau belum berhasil dimuat, maka tampilannya tidak akan hanya jatuh ke font Serif. Pastikan tampilan font lokal tersebut mirip dengan font eksternal yang ingin ditampilkan. Inilah fungsi utama dari CSS Font Stack:

body {font-family:"Nama Font","Arial Narrow",Arial,Sans-Serif}

font-style dan font-weight

Bagi para pengguna yang baru pertama kali menggunakan @font-face mungkin akan merasa baik-baik saja dengan tampilan seperti ini. Namun tidak untuk para tipografer dan juga orang-orang yang sudah terbiasa melihat berbagai jenis font:

Font italic tampak terlalu miring, bahkan dan dalam beberapa browser, font bold akan tampak begitu tebal
Font italic tampak terlalu miring.

Font dengan model italic akan tampak terlalu miring. Bahkan dalam beberapa peramban, font dengan gaya bold juga akan tampak terlalu tebal. Ini adalah contoh font Ubuntu Regular yang Saya lihat melalui peramban Safari di Windows:

Font italic tampak terlalu miring, bahkan dan dalam beberapa browser, font bold akan tampak begitu tebal
Ubuntu, Safari Windows.

Menurut Saya tampilan masing-masing gaya font di atas kurang stabil dan tidak menarik. Itu disebabkan karena kita hanya memuat satu model font saja yaitu font regular. Ketika kita hanya memuat satu model font saja, maka model font yang lain seperti bold, italic dan bold-italic akan disesuaikan oleh peramban. Dan hasilnya tentu saja tidak akan sebagus model font asli dari keluarga tersebut. Para pembuat font yang baik setidaknya akan membuat minimal empat model font yaitu regular, italic, bold dan bold-italic. Itulah sebabnya mengapa kita harus menggunakan keempat-empatnya:

Daftar gaya font Ubutu yang umum.
Gaya font Ubuntu.

Satu Nama Font dengan Empat Gaya

Memanggil file font dengan jumlah gaya minimal empat buah tentu saja memiliki cara tersendiri. Setiap @font-face harus tetap diberi satu nama font yang sama namun harus tetap bisa menampilkan masing-masing font eksternal dengan benar berdasarkan gayanya. Dan sekarang adalah saatnya kita menggunakan font-style dan font-weight dalam @font-face untuk menangani setiap gaya font.

Pertama-tama, yang terpenting adalah pastikan setiap font disimpan dengan nama yang mudah dan jelas berdasarkan gayanya:

Contoh cara memberi nama file pada setiap font berdasarkan gayanya.
Contoh pemberian nama file pada setiap font berdasarkan gayanya.

Setelah semua file diberi nama dengan baik, maka tugas selanjutnya adalah memanggil font, kemudian memberi masing-masing @font-face dengan font-family yang sama. Perbedaan setiap gaya hanya ditentukan oleh font-style dan font-weight:

/* Regular */
@font-face {
  font-family:'Ubuntu';
  src:url('ubuntu-regular.woff') format('woff');
  font-style:normal;
  font-weight:normal;
}

/* Italic */
@font-face {
  font-family:'Ubuntu';
  src:url('ubuntu-italic.woff') format('woff');
  font-style:italic;
  font-weight:normal;
}

/* Bold */
@font-face {
  font-family:'Ubuntu';
  src:url('ubuntu-bold.woff') format('woff');
  font-style:normal;
  font-weight:bold;
}

/* Bold Italic */
@font-face {
  font-family:'Ubuntu';
  src:url('ubuntu-bolditalic.woff') format('woff');
  font-style:italic;
  font-weight:bold;
}

Dan ini adalah tampilan font setelah keempat gaya dimuat:

Font terlihat lebih ideal setelah kita memuat empat buah gaya font.
Tampilan masing-masing gaya font sudah tampak ideal sekarang.

Pengguna Google Fonts

Jika Anda adalah pengguna layanan Google Fonts, pada halaman Quick Use sudah terlihat dengan jelas beberapa pilihan gaya font. Ambil minimal empat gaya seperti ini untuk memastikan agar tampilan teks terlihat ideal satu sama lain:

Deret pilihan dalam bentuk kotak centang pada halaman Quick Use Google Fonts
Pilih gaya normal/regular, italic, bold dan bold-italic (jika ada).

Gunakan @font-face Seperlunya

Font ideal paling minimal setidaknya hanya terdiri dari dua buah tipe font dengan satu gaya pada font pertama untuk tampilan judul dan empat gaya pada font ke dua untuk tampilan teks utama (5 @font-face).

Sintaks Aman @font-face

Fontspring menyarankan kita untuk memuat beberapa font dengan tipe file tertentu secara bersamaan untuk memastikan agar @font-face bisa bekerja pada hampir semua peramban dan perangkat:

@font-face {
  font-family:'MyWebFont';
  src:url('files/my-font.eot'); /* IE9 Compat Modes */
  src:url('files/my-font.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
      url('files/my-font.woff') format('woff'), /* Modern Browsers */
      url('files/my-font.ttf') format('truetype'), /* Safari, Android, iOS */
      url('files/my-font.svg#svgFontName') format('svg'); /* Legacy iOS */
  font-style:normal;
  font-weight:normal;
}

Meski hasilnya akan lebih stabil, namun tentu saja itu akan membuat file yang dipanggil menjadi bertambah banyak. Jika target pembaca Anda hanya sebatas pada pemakai desktop, maka file font dengan format WOFF saja sudah cukup dan bisa lolos pada semua peramban modern.

Catatan Tambahan

Saat praktek, biasanya Anda akan menemui beberapa masalah seperti ini:

  1. CSS @font-face Not Working with Firefox
  2. CSS @font-face, Fungsi src:local('#')

Lisensi Font

Font merupakan karya seni dan itu bisa saja masuk ke dalam kategori komersial (seperti halnya komik), atau terlarang untuk ditampilkan ke dalam media berupa web, sehingga kita harus tetap berhati-hati dalam menampilkan font eksternal ke dalam halaman web. Untuk sumber font berlisensi gratis yang bisa digunakan dengan aman baik secara pribadi maupun komersial bisa dengan mudah Anda dapatkan di Google Fonts dan FontSquirrel. Beberapa ada juga yang dibuat di Deviant Art. Mungkin itu font buatan para hobiis.

Labels: , ,

Wednesday, March 20, 2013

Toggle Side Navigation

Image of toggle side navigation example. See the navicon symbol!

HTML

<div id="outer-wrapper">

    <section id="nav">
        <a href="#nav" id="toggle-nav-btn" title="Show Navigation">&equiv;</a>
        <div class="inner">
            <ul class="menu">
                <li><a href="#">Home</a></li>
                <li><a href="#">About</a></li>
                <li><a href="#">Archive</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
            ...
            ...
        </div>
    </section>

    <section id="main">
        Artikel di sini...
    </section>

</div>

CSS

/* Outer wrapper */
#outer-wrapper {
  background-color:black;
  overflow:hidden;
}

/* Left sidebar */
#nav {
  float:left;
  width:2.8em;
  color:#999;
  position:relative;
}

#nav .inner {
  padding:1em;
  display:none;
}

.menu,
.menu li {
  margin:0 0;
  padding:0 0;
  list-style:none;
}

.menu {margin:2em -1em 1em}

.menu a {
  display:block;
  font-weight:bold;
  color:white;
  text-decoration:none;
  height:2.4em;
  line-height:2.4em;
  padding:0 1em;
}

.menu a:hover {background-color:#222}

/* Right sidebar */
#main {
  background-color:white;
  margin-left:2.8em; /* Same with the `#nav` width */
  padding:1em 2em;
}

/* Toggle navigation button */
#toggle-nav-btn {
  text-decoration:none;
  font-size:200%;
  line-height:100%;
  color:#666;
  display:block;
  position:absolute;
  top:.2em;
  right:.4em;
}

#toggle-nav-btn:hover {color:#888}

/* When the `.menu-is-visible` class applied */
.menu-is-visible #nav {width:200px}
.menu-is-visible #nav .inner {display:block}
.menu-is-visible #main {margin-left:200px} /* Same with the `.menu-is-visible #nav` width */
.menu-is-visible #toggle-nav-btn {color:#aaa}

JavaScript

JavaScript ini digunakan untuk menambahkan dan melepaskan kelas .menu-is-visible pada elemen <body> secara bergantian:

(function() {

    var page = document.body,
        btn = document.getElementById('toggle-nav-btn');

    btn.onclick = function() {

        // Toggle the `.menu-is-visible` class to the <body> tag based on `#toggle-btn-nav` click event
        page.className = (/(^| )menu-is-visible( |$)/.test(page.className)) ?
            page.className.replace(/menu-is-visible/,"") :
                page.className + " menu-is-visible";

        // Toggle the toggle navigation title too...
        this.title = (this.title == "Show Navigation") ?
            "Hide Navigation" :
                "Show Navigation";

        return false;

    };

})();

Lihat Demo

Alternatif Lain

Kita juga bisa menggunakan plugin jQuery Toggle Sidebar untuk menampilkan dan menyembunyikan sidebar, dimana menu navigasi berada di dalam sidebar tersebut. Tapi dalam kasus ini Saya tidak menyarankannya, mengingat menggunakan JavaScript mentah saja masih bisa:

$('#nav').toggleSidebar({
    expand: "#main",
    defaultHidden: true
});

Labels: , , ,

Sunday, March 10, 2013

Kapan Harus Menggunakan px, % dan em?

Meskipun, kebanyakan dari kita masih bertahan dengan satuan piksel saat menentukan ukuran-ukuran elemen HTML, namun di sini Saya ingin mencoba untuk membuka mata Anda lebih lebar lagi agar Anda bisa mengerti betul mengapa satuan-satuan relatif seperti em dan % dalam banyak kasus lebih efisien dan logis dibandingkan dengan satuan piksel (px) yang selama ini paling sering dipakai karena ukuran mereka yang sangat akurat.

Ketika % Menjadi Lebih Baik

Persentase merupakan satuan yang tidak dihitung berdasarkan ukuran elemen itu sendiri, melainkan dihitung berdasarkan perbandingan ukuran elemen tersebut terhadap ukuran induknya.

Satuan % Dalam Sistem Grid

Dimulai dari kasus sistem grid, atau katakanlah kolom-kolom web Anda. Di sini kita memiliki tiga elemen HTML untuk merancang sebuah susunan/layout situs sederhana. Terdiri dari pembungkus utama dan dua buah kolom. Salah satu kolom merupakan area artikel, dan satunya lagi merupakan area sidebar:

<div class="col-group">
    <div class="left-col">Artikel...</div>
    <div class="right-col">Sidebar...</div>
</div>

Seseorang dengan sudut pandang piksel akan membuat layout dua kolom dengan pengukuran seperti ini:

.col-group {
  width:600px;
  overflow:hidden;
}

.left-col {
  width:400px;
  float:left;
}

.right-col {
  width:200px; /* 600 - 400 */
  float:right;
}

CSS di atas akan menghasilkan layout dua kolom dengan ukuran pembungkus utama selebar 600 piksel. Kolom kiri selebar 400 piksel dan kolom kanan selebar 200 piksel. Ukuran layout yang sangat tepat dan tidak mungkin bisa diragukan akurasinya. Tapi sayangnya, layout piksel seperti ini hanya akan menimbulkan kendala saat Anda mencoba untuk memodifikasi atau memperbaharui lebar layout tersebut di masa depan. Misalnya, suatu saat Anda ingin mengubah lebar layout menjadi 1000 piksel seperti ini:

.col-group {
  width:1000px;
  overflow:hidden;
}

Pada saat yang sama Anda tentu harus memperbaharui lebar kolom kiri dan kolom kanan:

.left-col {
  width:600px; /* 400 + ((1000 - 600) / 2) */
  float:left;
}

.right-col {
  width:400px; /* 1000 - 600 */
  float:right;
}

Tidak praktis, tidak hemat waktu dan membutuhkan perhitungan baru setiap kali ukuran layout diperbaharui. Jika susunan halaman hanya terdiri dari dua buah kolom sederhana seperti contoh di atas mungkin tidak begitu menjadi masalah, tapi bagaimana jika jumlah kolomnya banyak?

Bandingkan dengan saat Anda mengatur lebar kolom menggunakan satuan persentase:

.col-group {
  width:600px; /* lebar pembungkus utama */
  overflow:hidden;
}

.left-col {
  width:66.6%; /* (400/600) x 100 */
  float:left;
}

.right-col {
  width:33.4%; /* 100 - 66.6 */
  float:right;
}

Meskipun beberapa orang (termasuk Saya) masih merasa sedikit kesulitan ketika mencoba mengubah sudut pandang satuan piksel ke persen, tapi hasil akhirnya nanti Saya jamin akan lebih stabil dan lebih mudah diperbaiki/diperbaharui (maintainable) saat kita menggunakan satuan persen. Karena yang menjadi standar ukuran di sini hanya ada satu, yaitu pada elemen terluar saja. Sedangkan ukuran lebar anak-anak kolom di dalamnya yang menggunakan satuan persen akan secara otomatis mengikuti ukuran berdasarkan perbandingan lebar induknya, betapapun kita mengubah lebar pembungkus luar kolom-kolom tersebut.

Demonstrasi di halaman ini mungkin bisa sedikit menjelaskan bagaimana persen dan piksel bekerja pada sistem grid:

Lihat Demo

Satuan % Dalam Elemen Heading/Judul Artikel

Elemen-elemen heading h1, h2, h3, h4, h5 dan h6 akan lebih baik jika diatur menggunakan satuan persen. Walaupun beberapa ada juga yang menggunakan satuan em. Sebenarnya itu tidak masalah, karena baik em maupun % keduanya sama-sama merupakan satuan relatif. Yang penting cobalah untuk menghilangkan kebiasaan menggunakan satuan piksel dalam menentukan ukuran elemen heading. Ini berhubungan dengan pengaplikasian media queries yang lebih efisien dan juga kemudahan di dalam pengaturan ukuran judul berdasarkan ukuran teks utama. Sebuah contoh sederhana, di sini Anda mencoba menentukan ukuran elemen-elemen heading dengan satuan piksel:

body {
  font-size:13px;
  font-family:Arial,Sans-Serif;
}

h1 {font-size:28px}
h2 {font-size:25px}
h3 {font-size:22px}
h4 {font-size:19px}
h5 {font-size:16px}
h6 {font-size:13px}

Mengapa satuan piksel buruk dalam hal ini? Itu karena satuan piksel hanya akan membuat Anda melakukan ekstra perubahan ukuran teks dalam media queries perangkat seluler. Dimulai dari ukuran teks dasar yang dideklarasikan di dalam selektor body sampai ke ukuran teks pada elemen heading level 6:

@media (max-width:360px) {
  body {font-size:11px}
  h1 {font-size:26px}
  h2 {font-size:23px}
  h3 {font-size:20px}
  h4 {font-size:17px}
  h5 {font-size:14px}
  h6 {font-size:11px}
}

Pola penyusutan teks akan berbeda jika Anda menggunakan satuan persentase saat menentukan ukuran judul artikel. Saat menggunakan satuan persentase, maka ukuran judul-judul artikel akan menyesuaikan diri berdasarkan perbandingan ukuran teks dasar saat itu, yaitu 13px (Sebagai contoh: 200% dari 13 piksel adalah 26 piksel):

body {
  font-size:13px;
  font-family:Arial,Sans-Serif;
}

h1 {font-size:200%}
h2 {font-size:180%}
h3 {font-size:160%}
h4 {font-size:140%}
h5 {font-size:120%}
h6 {font-size:100%}

Karena Anda menggunakan satuan persentase pada semua judul artikel, maka saat Anda memperkecil ukuran teks pada perangkat seluler, yang perlu Anda lakukan hanya memperkecil ukuran teks dasarnya saja, yaitu pada elemen <body>. Ukuran teks pada semua judul artikel nantinya akan menyusut menyesuaikan diri berdasarkan persentase terhadap ukuran teks utama yang sudah mengecil:

@media (max-width:360px) {
  body {font-size:11px}
}

Menggunakan satuan persentase untuk elemen heading juga akan mempermudah Anda di dalam memperbaharui ukuran teks artikel. Anda tidak perlu memperbaharui semua ukuran judul artikel. Cukup perbaharui ukuran teks dasarnya saja. Selebihnya akan secara otomatis mengikuti skala yang diterapkan.

Ketika em Menjadi Lebih Baik

em adalah satuan yang dihitung berdasarkan ukuran teks di sekitarnya. Pada dasarnya 1em sama dengan 16 piksel. Itu jika Anda tidak menentukan ukuran teks pada elemen manapun. Tapi jika —misalnya— Anda menentukan ukuran teks sebesar 30 piksel pada <body>, maka 1em di area <body> akan setara dengan 30px (1em = Ukuran Teks di Sekitarnya).

Satuan em dalam line-height dan margin Paragraf

Satuan em sangat bermanfaat untuk menentukan ukuran dan jarak elemen yang terkait erat dengan ukuran teks. Misalnya margin paragraf dan jarak antar baris teks.

Contoh Kasus: Dua buah kolom dengan elemen paragraf di dalamnya mendapatkan ukuran teks sebesar 13 piksel yang diturunkan dari <body>. Paragraf di dalam kolom pertama menggunakan satuan piksel untuk mengatur margin dan line-height, sedangkan paragraf yang berada di dalam kolom ke dua akan menggunakan satuan em:

HTML

<div class="one">
    <p>Lorem ipsum dolor sit amet...</p>
    <p>Lorem ipsum dolor sit amet...</p>
</div>
<div class="two">
    <p>Lorem ipsum dolor sit amet...</p>
    <p>Lorem ipsum dolor sit amet...</p>
</div>

CSS

body {font-size:13px} /* 1em = 13px */

.one p {
  line-height:18px;
  margin:13px 0;
}

.two p {
  line-height:1.384615384615385em; /* 18 / 13 */
  margin:1em 0;
}

Hasil akhirnya, ukuran dan jarak antar baris paragraf akan tampak sama:

PX & EM
Sebelah kiri: Menggunakan piksel. Sebelah kanan: Menggunakan em.

Masalah akan muncul ketika Anda mencoba untuk memperbesar/memperkecil ukuran teks:

PX & EM
Sebelah kiri: Menggunakan piksel. Sebelah kanan: Menggunakan em.

Kolom sebelah kiri: Karena kita menggunakan satuan piksel, maka ketika ukuran teks berubah (dalam kasus ini: bertambah besar) jarak antar baris dan margin paragraf tetap sempit dan tidak berubah, bertahan pada ukuran 18px dan 13px. Membuat tulisan menjadi semakin sulit untuk dibaca.

Kolom sebelah kanan: Karena kita menggunakan satuan em, maka skala ukuran tinggi baris dan margin antarparagraf akan menyesuaikan diri berdasarkan ukuran teks.

Dalam Semua Elemen yang Terkait dengan Ukuran Teks

Pada intinya satuan em cocok untuk diterapkan pada semua hal yang berhubungan dengan ukuran teks. Semua hal yang membutuhkan ukuran dengan perbandingan yang tepat terhadap teks. Contoh paling sederhana ada pada desain tombol:

CSS3 Buttons
Desain tombol dengan satuan em pada padding dan border-radius akan menciptakan skala tombol yang lebih ideal dibandingkan px.

Ketika px Menjadi Lebih Baik

Satuan piksel dihitung berdasarkan ukuran lebar dan tinggi satu unit piksel pada layar. Oleh karena itu satuan piksel akan sesuai jika diterapkan pada elemen-elemen yang membutuhkan ukuran yang akurat dan tidak terpengaruh dengan ukuran elemen di sekitarnya. Misalnya lebar dan tinggi ikon, tebal border, blur bayangan, posisi latar dan ukuran teks utama. Ukuran teks utama biasanya dideklarasikan pada elemen <body> atau <html>.


Masalah Akurasi Ukuran pada Satuan Non-Piksel

Tidak bisa dipungkiri bahwa ukuran persentase dan relatif teks tidak akan bisa seakurat ukuran piksel. Tapi memangnya siapa yang peduli dengan itu? Kita, para penikmat desain dan tipografi pada dasarnya tidak pernah peduli mengenai seberapa besar tepatnya, ukuran huruf dan judul artikel yang sedang kita baca. Kita tidak peduli berapa piksel ukuran judul dan teks yang sedang kita baca. Karena yang kita pedulikan selama ini adalah proporsi yang ideal. Tipografi tidak begitu mementingkan akurasi, tipografi lebih mementingkan proporsi. Saya pikir kita tidak perlu khawatir untuk memulai beralih dari piksel dalam kasus-kasus tertentu menuju satuan-satuan relatif yang lebih mudah dipelihara dan responsif terhadap skala di sekitarnya.

Labels: , ,