Sekali lagi tentang visualisasi kotak centang jenis masukan dan radio. Bagi yang sudah lupa caranya

Topiknya sudah tua dan, ternyata, sudah dilupakan.



Baru-baru ini, saya mendapat pekerjaan singkat tentang pengembangan spesifikasi teknis untuk modernisasi proyek yang sudah lama ada. Dan, secara khusus, kasus tersebut berkaitan dengan gaya dari <input type = "checkbox"> yang terkenal kejam. Ternyata pemainnya, seorang programmer "dari semua perdagangan" bahkan tidak mengerti bahwa saya sedang menjelaskan kepadanya dengan kata-kata bagaimana melakukannya. Saya harus membuat contoh dan, sebagai hasilnya, teks ini muncul.



Izinkan saya mengingatkan Anda bahwa sekarang kotak centang dan kotak radio ditampilkan secara berbeda oleh situs yang berbeda. Kebetulan masukan yang tidak ditandai tidak dapat langsung dilihat - sangat "cantik secara desainer", dan di versi terbaru Chrome, kotak centang yang dipilih telah menjadi warna sian yang keji.



Jadi situasinya



Ada tiga perusahaan yang menggunakan produk perangkat lunak tertentu yang terkait dengan pesanan, akuntansi, gudang, dll. Bekerja dengan pelanggan, mitra, pelaksana, dll.



Pemasar dan pengiklan juga menggunakannya. Apa yang dilakukan sistem ini - tidak peduli apa yang dikatakannya - tidak masalah.



Dan penting bahwa situs produk ini memiliki banyak halaman dengan formulir yang berisi banyak kotak centang dan radio masukan.



Keluhan karyawan



Sutradara : Di layar lebar, "kryzhiki" sulit dilihat dan tidak terlihat.

Kepala akuntan : Di komputer saya, "kryzhiki" terlihat seperti ini, pada karyawan terlihat berbeda, di rumah juga berbeda, tetapi di tablet sama sekali berbeda.

Pemasar : Mungkinkah, sehingga beberapa posisi yang tidak dipilih menjadi merah, dan yang lain yang dipilih menjadi hijau?

Dll



Jadi tugasnya



  1. Perbaiki tampilan kotak centang dan kotak radio dengan biaya minimal dan sedikit perubahan.
  2. Buat kotak centang dan gaya kotak radio untuk pengguna yang berbeda. Penting: ini adalah situs tertutup, ada "milik kita sendiri", "keindahan" tidak diperlukan, tetapi efisiensi persepsi diperlukan.


Apa yang tidak diperbolehkan



1. Sisi server tidak boleh disentuh.

2. Anda tidak dapat menyentuh file javascript, Anda tidak dapat memasukkan javascript Anda sendiri.

3. File css tidak dapat disentuh.



Apa yang diperbolehkan



1. Edit template html.

2. Buat file gaya untuk semua pengguna.

4. Buat file gaya untuk pengguna atau grup pengguna tertentu.

Dan apa yang Anda lakukan, Anda dapat langsung melihat codepen.io , tetapi lebih baik untuk membaca lebih lanjut.



Studi pendahuluan menunjukkan



1. Hampir semua <input type = "checkbox"> memiliki kolom nama, dan yang tidak memiliki id.

2. Semua <input type = "radio"> memiliki kolom nama, beberapa memiliki id.

3. Karenanya, di css kotak centang dapat diakses baik oleh id maupun nama. Ke radio - baik dengan id, atau dengan nomor anak induknya.



Potongan kode sumber:



/*  1 */
<tag><input type="checkbox">  </tag>

/*  2 */
<tag><input type="checkbox">  <br>
<input type="checkbox">  </tag>

/*  3 */
...<label><input type="checkbox">  </label>...

/*  4 */
<td><input id="idxxx" type="checkbox"></td>
<td><label for="idxxx"> </label></td>


Mari perbaiki kodenya:



/*  1 */
<tag><label class="new-input"><input type="checkbox"><s></s><span> </span></label></tag>

/*  2 */
<tag><label class="new-input"><input type="checkbox"><s></s><span> </span></label><br>...</tag>

/*  3 */
...<label class="new-input"><input type="checkbox"><s></s><span> </span></label>...

/*  4 */
<td><label class="new-input new-input-one"><input id="idxxx" type="checkbox"><s></s></label></td>
<td><label for="idxxx"> </label></td>


Semuanya sama untuk <input type = "radio">, kelas LABEL sama.



Apa sebenarnya yang Anda lakukan?



  1. Setiap masukan (buritan opsi 3) telah dibungkus dengan tag LABEL dengan kelas kita. Opsi 3 baru saja menambahkan kelas.
  2. Segera setelah masukan, tag S kosong disisipkan. Karena masukan itu sendiri tidak akan terlihat, tag ini akan membuat masukan ini.
  3. Teks yang menyertainya dibungkus dengan tag SPAN (kecuali untuk opsi 4). Tag ini akan dibutuhkan saat kita memutuskan perataan input visual relatif terhadap teks ini.
  4. Opsi 4 ditambahkan kelas lain untuk menghindari perataan ini, karena teks yang menyertainya berada di sel lain dari tabel. Sebenarnya, itu perlu untuk melakukan yang sebaliknya - tambahkan kelas yang bertanggung jawab untuk penyelarasan ke opsi 1-3. Tapi, ada lebih banyak opsi 1-3 daripada yang ke-4, dan agar tidak memperbesar html, lakukan seperti ini.


Pertanyaan retoris dan jawaban retoris
1. S? , S – . , input.



2. S SPAN ? , html? , , «» .



  .new-input > S { }
  .new-input > .new-input-S {}


3. , , «» html . – mni mnio. :-))



Beberapa pertimbangan awal dan tweak css terkait dengan ukuran kotak: border-box, normalisasi LABEL, A + B, A ~ B dan [attr] selektor ,: diperiksa ,: dinonaktifkan dan :: before pseudo-class. Siapa pun yang tidak yakin apa yang dia ketahui atau ingin menyegarkan pengetahuannya terlihat di bawah luka.



Pertimbangan awal
1. , «» css (box-sizing:content-box) width height , padding border . box-sizing:border-box , padding border width height.



2. , , «» . «» LABEL , . LABEL.



LABEL {
    box-sizing:border-box; cursor:pointer; user-select:none;
}
LABEL *,
LABEL *::before,
LABEL *::after {
    box-sizing:inherit;
}


.., box-sizing:border-box LABEL, . ( ).



3. «A + B» , B, A, .. B. , «A ~ B» , B A, .. .

, «».



?



<label class="new-input"><input type="checkbox"><s></s><span> </span></label>
<label class="new-input"><input type="radio"><s></s><span> </span></label>


/* 1 */
.new-input > INPUT + S {}
.new-input > INPUT ~ SPAN {}

/* 2 */
.new-input > INPUT:not(:checked) + S {}
.new-input > INPUT:not(:checked) ~ SPAN {}

/* 3 */
.new-input > INPUT:checked + S {}
.new-input > INPUT:checked ~ SPAN {}

/* 4 */
.new-input > INPUT:disabled + S {}
.new-input > INPUT:disabled ~ SPAN {}

/* 5 */
.new-input > INPUT[type="radio"] + S {}


– S SPAN.

– INPUT .

– INPUT .

– INPUT .



, , – S , input radio.

, S SPAN input.



4. S input, input display:none, , LABEL , S . html hidden input? , hidden input «» , html .



Jadi, mari mulai memberikan masukan



Contoh N 1. Yang paling sederhana - kita menggunakan karakter alfabet.

Kode html-nya sama, dan cssnya akan seperti ini:



/* s1 */
.new-input > INPUT + S::before {
  content: "c";
}
/* s2 */
.new-input > INPUT:checked + S::before {
  content: "V";
}
/* s3 */
.new-input > INPUT[type="radio"] + S::before {
  content: "r";
}
/* s4 */
.new-input > INPUT[type="radio"]:checked + S::before {
  content: "X";
}
/* s5 */
.new-input > INPUT:disabled + S::before {
  opacity: 0.5;
}
/* s6 */
.new-input > S {
  text-decoration: none;
  margin-left: 3px;
  margin-right: 6px;
}
/* s7 */
.new-input > S::before {
  display: inline-block;
  width: 1.25em;
  text-align: center;
  color: #fafafa;
  background-color: #37474f;
}
/* s8 */
.new-input > INPUT[type="radio"] + S::before {
  border-radius: 50%;
}


Tag S akan memberikan masukan. Namun kami akan "membaginya" menurut fungsionalitas: tag S itu sendiri akan bertanggung jawab untuk penempatan di LABEL dan penyelarasan relatif terhadap SPAN berikutnya.



Dan pseudo-element S :: before akan ditempatkan di dalam tag S dan akan bertindak sebagai masukan.



Baris s1 mendefinisikan karakter apa yang akan ditempatkan di S :: sebelum ketika input tidak dipilih. Pada prinsipnya, akan perlu untuk menulis ".new-input> INPUT: not (: checked) + S :: before", tetapi beberapa browser (misalnya, IE) mungkin tidak menjalankan konstruksi seperti itu.

String s2 menentukan karakter saat input dipilih.

Garis s3 dan s4 melakukan hal yang sama untuk radio input.

String s5menjelaskan apa yang terjadi jika input diblokir - dalam hal ini, tag S akan setengah transparan.

Line s6 mendefinisikan alignment, dalam hal ini memberikan padding ke kiri dan kanan (hanya dalam contoh ini). Plus, ini menghilangkan coretan biasa.

Garis s7 membuat persegi, s8 mengubahnya menjadi lingkaran untuk radio input.



Contoh # 1 dapat dilihat di codepen.io . Ada masukan asli dan masukan baru. Yang pertama bisa dihilangkan.



Sedikit lebih banyak detail tentang tampilan: blok-sebaris, ukuran-font, tinggi-baris
font-size, line-height. line-height – font-size, line-height – , line-height – . line-height:1.25, S::before width:1.25em.



S::before display: inline-block – S::before «» ( , , .), «» . .





Pertanyaan:



Bisakah Anda menggunakan karakter khusus? Seperti ini:

□ ■ ▢ ▣ ○ ● ◎ ◉

Beri mereka ukuran yang tepat dan hanya itu. Tidak?



Jawaban:



Bisa. Tetapi Anda tidak perlu melakukannya. Untuk wasir besar akan ada dan tarian dengan rebana sesuai dengan ukuran yang diinginkan, pelurusan vertikal, pemangkasan dan sebagainya. Selain itu, browser yang berbeda bekerja secara berbeda dengan simbol-simbol ini.

Kami pergi ke arah lain. Meskipun contoh terakhir berisi implementasi dari ide ini.



Contoh N 2. Elemen masukan "Gambar" menggunakan



kode html css adalah sama, tetapi css akan menjadi seperti ini:



/* s1 */
.new-input > S::before {
  content: "";
  display: inline-block;
  width: 0.75em;
  height: 0.75em;
  border: 1px solid currentColor;
  padding: 2px;
  background-clip: content-box;
  border-radius: 20%;
}
/* s2 */
.new-input > INPUT[type="radio"] + S::before {
  border-radius: 50%;
}
/* s3 */
.new-input > INPUT:checked + S::before {
  background-color: currentColor;
}
/* s4 */
.new-input > INPUT:disabled + S::before {
  opacity: 0.5;
}
/* s5 */
.new-input > S {
  text-decoration: none;
  margin-left: 3px;
  margin-right: 6px;
}


Baris s1 mendefinisikan S :: before untuk memberikan masukan. Ini akan menjadi blok-sebaris yang lebar dan tingginya disetel ke 0,75em, yang kira-kira sama tingginya dengan huruf besar dan bergantung pada ukuran font induknya. Batas tipis diatur dengan warna saat ini, bantalan bagian dalam, pembulatan kecil sudut. Dan yang terpenting! - property background-clip: content-box diatur. Ini adalah properti yang sangat menarik - jika background-color disetel, itu hanya akan mewarnai bagian konten dan tidak akan mempengaruhi padding. Yang kami butuhkan.



Garis s2 untuk input radio membuat S :: sebelum putaran.

Garis s3 untuk input yang ditandai mengatur S :: before background-color ke warna saat ini. Artinya, itu "menggambar" persegi atau lingkaran di dalamnya.

Gariss4 membuka masukan, baris s5 memberi bantalan ke kiri dan kanan.



Keuntungan dari metode ini



  1. Semuanya sangat sederhana. Bekerja di semua browser. Bahkan IE10 (dalam persaingan ke-11).
  2. Anda bisa mewarnai sesuka Anda.
  3. Karena S :: before adalah inline-block, maka S :: before berada tepat di bawah baseline dan tidak keluar di mana pun. Jika tingginya lebih besar dari teks, itu hanya akan menambah tinggi garis dan tetap pada garis dasar.
  4. Karena visualisasi input ada di dalam tag S, itu dapat diposisikan dan disejajarkan dengan mudah.
  5. Dimensi S :: before in em memungkinkan untuk menyetel ukurannya relatif terhadap ukuran teks keterangan. Anda dapat, misalnya, menetapkan batas tinggi dan lebar.


Kekurangan dari metode ini



Terutama dalam ukuran em. Faktanya adalah bahwa situasi dapat muncul ketika lebar dan tinggi saat menghitung (dari em ke px) akan memiliki nilai pecahan. Pembulatan mungkin tidak berfungsi dengan benar pada komputer biasa dengan layar normal. Misalnya, dimensi 12.8px kali 12.8px di Mozila yang sama dapat menjadi 13px kali 12px. Maka Anda perlu mengatur ukuran tetap. Meskipun pada monitor modern dan kartu video, laptop, tablet, dan smartphone, hal ini tidak terjadi karena titik (piksel) browser terdiri dari beberapa piksel layar.



Contoh # 2 dapat dilihat di codepen.io . Ada masukan asli dan masukan baru. Yang pertama bisa dihilangkan.

Jadi, tugas pertama - memberikan masukan - selesai. Kami lolos ke "pewarnaan" yang dipilih.



Masukan mewarnai



html misalnya:



<label class="new-input"><input name="chb1" type="checkbox" ...><s></s><span> </span></label>
<label class="new-input"><input id="rb1" type="radio" ...><s></s><span> </span></label>


Kami akan merujuk ke masukan dari jenis kotak centang dengan nama, ke radio dengan id.



Kami mengecat semuanya dengan warna biru



/*  input */
.new-input > INPUT[name="chb1"] + S,
.new-input > INPUT#rb1 + S {
  color: #0091ea;
}
/*  text */
.new-input > INPUT[name="chb1"] ~ SPAN,
.new-input > INPUT#rb1 ~ SPAN {
  color: #0091ea;
}
/*   */
.new-input > INPUT[name="chb1"] ~ *,
.new-input > INPUT#rb1 ~ * {
  color: #0091ea;
}


Ingat kekhususan dalam css, gaya ini akan lebih spesifik daripada gaya dasar dan pasti akan berhasil. Apa perbedaannya dari yang dijelaskan di atas? Yang hanya berlaku untuk memilih input - yang memiliki nama dan nilai id yang ditentukan.



Semuanya baik-baik saja di sini kecuali input yang tidak dipilih tidak akan terlihat bagus - batas biru tipis hampir tidak terlihat.



Warnai dengan hijau saat input dipilih



/*  input */
.new-input > INPUT[name="chb1"]:checked + S,
.new-input > INPUT#rb1:checked + S {
  color: #00c853;
}
/*  text */
.new-input > INPUT[name="chb1"]:checked ~ SPAN,
.new-input > INPUT#rb1:checked ~ SPAN {
  color: #00c853;
}
/*   */
.new-input > INPUT[name="chb1"]:checked ~ *,
.new-input > INPUT#rb1:checked ~ * {
  color: #00c853;
}


Opsi pertama, menurut saya, tidak terlalu bagus - baik bingkai maupun bujur sangkar / lingkaran dalam akan berwarna hijau. Anda hanya bisa mewarnainya.



/*  input    */
.new-input > INPUT[name="chb1"]:checked + S::before,
.new-input > INPUT#rb1:checked + S::before {
  background-color: #00c853;
}


Warna merah jika input TIDAK dipilih



/*  input */
.new-input > INPUT[name="chb1"]:not(:checked) + S,
.new-input > INPUT#rb1:not(:checked) + S {
  color: #d50000;
}
/*  text */
.new-input > INPUT[name="chb1"]:not(:checked) ~ SPAN,
.new-input > INPUT#rb1:not(:checked) ~ SPAN {
  color: #d50000;
}
/*   */
.new-input > INPUT[name="chb1"]:not(:checked) ~ *,
.new-input > INPUT#rb1:not(:checked) ~ * {
  color: #d50000;
}


Apakah logikanya jelas? Anda dapat terus membuat desain yang lebih rumit.



Misalnya, jika masukan tidak dipilih, teks harus berwarna merah dan tebal, dan jika elemen masukan bagian dalam dan teks dipilih, ia harus berwarna hijau. Dasar!



/* ,    */
.new-input > INPUT[name="chb1"]:not(:checked) ~ SPAN,
.new-input > INPUT#rb1:not(:checked) ~ SPAN {
  color: #d50000;
  font-weight: bold;
}
/*   input,   */ 
.new-input > INPUT[name="chb1"]:checked + S::before,
.new-input > INPUT#rb1:checked + S::before {
  background-color: #00c853;
}
/* ,   */ 
.new-input > INPUT[name="chb1"]:checked ~ SPAN,
.new-input > INPUT#rb1:checked ~ SPAN {
  color: #00c853;
}


Dan, misalnya, Anda perlu memproses seluruh kelompok masukan (10-15 buah). Agar tidak menulis banyak baris, Anda dapat menemukan orang tua mereka yang sama (.parent_element) dan mempersingkat kondisinya.



.parent_element > .new-input > INPUT:not(:checked) ~ SPAN {
  color: #d50000;
  font-weight: bold;
}
.parent_element > .new-input > INPUT:checked + S::before {
  background-color: #00c853;
}
.parent_element > .new-input > INPUT:checked ~ SPAN {
  color: #00c853;
}


Anda dapat melihat semuanya dalam contoh terakhir di codepen.io



Di sini, tampaknya, dan hanya itu. Tetap hanya untuk "menggores tanda lahir" dari perfeksionis - masalah keselarasan.



Sejajarkan input visual dan teks yang menyertainya



Untuk memulainya, izinkan saya mengingatkan Anda tentang hal-hal terkenal tentang penempatan teks, pemformatan, dan banyak lagi. Semuanya di bawah pemotongan.



Hal-hal yang terkenal
, , css . .



1. font-size , . (baseline), «» . «» – g – «» . (cap height) – «» () . «» – – «» . , , . «» 75% . , font-size:16px, Arial 12px. , «» .



2. line-height . , font-size, , . , .



3. , S SPAN font-size line-height - . font-size:16px line-height:1.25. N1 S::before 1.25em, . N2 ( ) – S::before 0.75em, . font-size . , .



4. - «», , . . , , 50%. , , 150%. -, / – -! , -.



? , , input — , , , . !



Apa yang terjadi jika teks yang menyertai dalam SPAN ditampilkan dalam dua atau tiga baris? Jelas, itu akan "cocok" di bawah masukan. Tidak cantik, perlu diperbaiki.



Salah satu metode kuno adalah ini: tag S adalah float: left, dan tag SPAN adalah display: block and overflow: hidden.



Ini akan membuat kolom teks. Diasumsikan bahwa beberapa dari mereka akan memiliki margin yang sesuai, yang akan memberikan lompatan di antara mereka. Nah, ada juga yang ditambah wasir dengan penghentian float setelah SPAN. Kami akan mengambil rute modern - gunakan flexbox. Dia benar-benar tidak pada tempatnya di sini.



.new-input {
  display: flex;
  flex-direction: row;
  align-items: start;
}
.new-input > S {
  margin-right: 4px;
  flex: 0 0 auto;
}
.new-input > SPAN {
  flex: 0 1 auto;
}


Dalam hal ini tag LABEL (yaitu .new-input) akan fleksibel, S dan SPAN akan menjadi blok, ditempatkan di bagian atas LABEL. Teks dalam SPAN akan terdiri dari beberapa baris jika perlu. Karena itu, input visual dijelaskan di S :: before. Terlepas dari tingginya, SPAN S :: before akan disejajarkan dengan garis SPAN pertama. Alternatifnya, Anda dapat menetapkan align-items: center - lalu dengan satu baris SPAN, input visual akan berada di atas, dan dengan dua baris, di tengah, dan dengan tiga baris, baris kedua. Dalam contoh terakhir, Anda dapat mengganti lokasi input.



Itu saja



Saya berharap itu menarik dan bermanfaat bagi seseorang. Tolong jangan banyak memarahi saya - ini adalah pengalaman pertama saya di Habr.



Contoh # 1 hanyalah demonstrasi interaksi antara mengubah input dan elemen tetangga.



Contoh N 2 - visualisasi input menggunakan css, sebagai dasar solusi.



Contoh terakhir adalah semuanya dijelaskan bersama.



Tentang implementasi tertentu



Ada formulir ekstensif, di mana blok bidang yang dapat diedit oleh pengguna tertentu disorot dengan latar belakang yang samar, dan masukan lainnya memiliki properti yang dinonaktifkan dan hanya disajikan untuk informasi. Oleh karena itu, gaya ".new-input> INPUT: disabled + S :: before" tidak diterapkan.



UPD



Menanggapi komentar Contoh N 3 .

Ada kunci dan dukungan fokus untuk input tersembunyi di tempat kerja.



All Articles