Gunakan gambar seperti kotak centang

165

Saya ingin memiliki alternatif untuk kotak centang standar - pada dasarnya saya ingin menggunakan gambar dan ketika pengguna mengklik gambar, fade out dan overlay kotak centang.

Intinya, saya ingin melakukan sesuatu seperti yang dilakukan Recaptcha 2 ketika Anda mengklik gambar yang memenuhi kriteria tertentu. Anda dapat melihat demo Recaptcha di sini, tetapi kadang-kadang mungkin membuat Anda menyelesaikan pertanyaan teks, sebagai lawan dari pemilihan gambar. Jadi, inilah tangkapan layar:

Tangkapan layar Google Recaptcha

Ketika Anda mengklik salah satu gambar (dalam hal ini, berisi gambar steak), gambar yang Anda klik menyusut dalam ukuran dan centang biru muncul, menunjukkan bahwa Anda telah mencentangnya.

Katakanlah saya ingin mereproduksi contoh persis ini.

Saya menyadari bahwa saya dapat memiliki 9 kotak centang tersembunyi, dan melampirkan beberapa jQuery sehingga ketika saya mengklik gambar, itu memilih / membatalkan pilihan kotak centang tersembunyi. Tapi bagaimana dengan penyusutan gambar / overlay kutu?

bgs264
sumber
2
Anda dapat memiliki dua gambar yang identik: satu dengan tanda centang dan lainnya tanpa tanda centang. Dan ubah gambar saat klik
Alex
22
@ Alex Itu akan menjadi solusi yang sangat tidak fleksibel.
Siguza
2
Sudahkah Anda mencoba menambahkan / menghapus kelas CSS pada klik yang mengesampingkan ukuran gambar dan melakukan beberapa :beforekeajaiban untuk gambar centang?
Hexaholic
3
@Alex "Unflexible" dalam arti akan membutuhkan lebih banyak pekerjaan untuk mengubah apa pun, seperti menambahkan gambar baru ke koleksi atau mengubah ikon "ticked", ketika ini tidak akan menjadi masalah jika efeknya dibuat secara terprogram di runtime.
Siguza
2
@Christian Mengganti kotak centang dengan sesuatu yang khusus adalah keputusan desain yang populer (bahkan jika itu hanya kotak centang bergaya), dan menemukan cara-cara yang baik / sederhana untuk melakukannya jelas menarik bagi para dev yang harus berurusan dengannya. Dan pertanyaan ini (overlay pengganti kotak centang pada sesuatu yang lain) pasti membuatnya menjadi menarik. Secara khusus, perhatikan bagaimana jawaban yang diterima tidak menggunakan JS sama sekali, meskipun tugasnya terlihat sangat kompleks
Izkata

Jawaban:

308

Solusi HTML / CSS semantik murni

Ini mudah diimplementasikan sendiri, tidak perlu solusi pra-dibuat. Juga akan banyak mengajari Anda karena Anda tampaknya tidak terlalu mudah dengan CSS.

Ini adalah hal yang perlu kamu lakukan:

Kotak centang Anda harus memiliki idatribut yang berbeda . Ini memungkinkan Anda untuk menghubungkannya <label>, menggunakan label for-atribut.

Contoh:

<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1"><img src="http://someurl" /></label>

Melampirkan label ke kotak centang akan memicu perilaku browser: Setiap kali seseorang mengklik label (atau gambar di dalamnya), kotak centang akan diaktifkan.

Selanjutnya, Anda menyembunyikan kotak centang dengan menerapkan misalnya display: none;untuk itu.

Sekarang yang perlu dilakukan hanyalah mengatur gaya yang Anda inginkan untuk label::beforeelemen semu Anda (yang akan digunakan sebagai elemen penggantian kotak centang visual):

label::before {
    background-image: url(../path/to/unchecked.png);
}

Pada langkah rumit terakhir, Anda menggunakan :checkedpemilih palsu CSS untuk mengubah gambar ketika kotak centang dicentang:

:checked + label::before {
    background-image: url(../path/to/checked.png);
}

The +( berdekatan saudara pemilih ) memastikan Anda hanya mengubah label yang langsung mengikuti centang tersembunyi di markup.

Anda dapat mengoptimalkannya dengan meletakkan kedua gambar dalam spritemap dan hanya menerapkan perubahan background-positionalih-alih menukar gambar.

Tentu saja Anda perlu memposisikan label dengan benar dan menerapkan display: block;serta mengatur yang benar widthdan height.

Edit:

Contoh kode dan cuplikan, yang saya buat setelah instruksi ini, menggunakan teknik yang sama, tetapi alih-alih menggunakan gambar untuk kotak centang, penggantian kotak centang dilakukan murni dengan CSS , membuat ::beforelabel yang telah, setelah diperiksa, memiliki content: "✓";. Tambahkan beberapa batas bulat dan transisi manis dan hasilnya benar-benar disukai!

Berikut adalah codepen yang berfungsi yang menampilkan teknik dan tidak memerlukan gambar untuk kotak centang:

http://codepen.io/anon/pen/wadwpx

Berikut ini kode yang sama dalam cuplikan:

ul {
  list-style-type: none;
}

li {
  display: inline-block;
}

input[type="checkbox"][id^="cb"] {
  display: none;
}

label {
  border: 1px solid #fff;
  padding: 10px;
  display: block;
  position: relative;
  margin: 10px;
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

label::before {
  background-color: white;
  color: white;
  content: " ";
  display: block;
  border-radius: 50%;
  border: 1px solid grey;
  position: absolute;
  top: -5px;
  left: -5px;
  width: 25px;
  height: 25px;
  text-align: center;
  line-height: 28px;
  transition-duration: 0.4s;
  transform: scale(0);
}

label img {
  height: 100px;
  width: 100px;
  transition-duration: 0.2s;
  transform-origin: 50% 50%;
}

:checked+label {
  border-color: #ddd;
}

:checked+label::before {
  content: "✓";
  background-color: grey;
  transform: scale(1);
}

:checked+label img {
  transform: scale(0.9);
  box-shadow: 0 0 5px #333;
  z-index: -1;
}
<ul>
  <li><input type="checkbox" id="cb1" />
    <label for="cb1"><img src="https://picsum.photos/seed/1/100" /></label>
  </li>
  <li><input type="checkbox" id="cb2" />
    <label for="cb2"><img src="https://picsum.photos/seed/2/100" /></label>
  </li>
  <li><input type="checkbox" id="cb3" />
    <label for="cb3"><img src="https://picsum.photos/seed/3/100" /></label>
  </li>
  <li><input type="checkbox" id="cb4" />
    <label for="cb4"><img src="https://picsum.photos/seed/4/100" /></label>
  </li>
</ul>

connexo
sumber
32
Senang kamu menyukainya! Mulai mengutak-atik CSS lebih banyak, itu menyenangkan dan CSS dapat melakukan jauh lebih banyak daripada yang mungkin Anda harapkan (kecuali pemusatan vertikal, itu terlalu sulit;)).
connexo
1
Ya, dan memahami cara kerjanya akan membuat Anda berpikir di masa depan, setiap kali Anda ingin beberapa tindakan DOM di klik. Dan Anda pikir Anda hanya bisa bereaksi terhadap :hover:)
connexo
Itu akan menjadi hal berikutnya yang saya tonton di Pluralsight - beberapa hal CSS :)
bgs264
6
Ini sangat bagus! Saya perhatikan masalah kecil ketika Anda mengklik label yang sama dua kali, itu memilih gambar. Ini memperbaikinya: codepen.io/anon/pen/jPmNjg
Ayesh K
1
Centang akan terlihat lebih baik sebagai SVG. Konten CSS menempatkan Anda pada belas kasihan beberapa font sistem yang mengerikan.
Adria
31

Solusi CSS murni

Ada tiga perangkat rapi yang dipanggil:

  1. The :checkedpemilih
  2. The ::beforepseudo-selector
  3. contentProperti css .

label:before {
  content: url("https://cdn1.iconfinder.com/data/icons/windows8_icons_iconpharm/26/unchecked_checkbox.png");
  position: absolute;
  z-index: 100;
}
:checked+label:before {
  content: url("https://cdn1.iconfinder.com/data/icons/windows8_icons_iconpharm/26/checked_checkbox.png");
}
input[type=checkbox] {
  display: none;
}
/*pure cosmetics:*/
img {
  width: 150px;
  height: 150px;
}
label {
  margin: 10px;
}
<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1">
  <img src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcR0LkgDZRDTgnDrzhnXGDFRSItAzGCBEWEnkLMdnA_zkIH5Zg6oag">
</label>
<input type="checkbox" id="myCheckbox2" />
<label for="myCheckbox2">
  <img src="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRhJjGB3mQxjhI5lfS9SwXou06-2qT_0MjNAr0atu75trXIaR2d">
</label>
<input type="checkbox" id="myCheckbox3" />
<label for="myCheckbox3">
  <img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQuwWbUXC-lgzQHp-j1iw56PIgl_2eALrEENUP-ld72gq3s8cVo">
</label>

jcuenod
sumber
Bagaimana mungkin menambahkan perilaku tombol radio ke kotak centang ini? Maksud saya ketika Anda mengklik gambar, gambar yang sudah dipilih menjadi tidak terpilih.
Libertad
Siapa pun yang bertanya pada dirinya sendiri pertanyaan yang sama dengan @Libertad hanya mengubah jenis input ke radio dan memberi mereka semua nama yang sama "atribut" <input type="radio" name="myRadio" id="myRadio1" />juga mengubah css Anda untuk menyembunyikan peluru:input[type=radio]{display: none;}
Lou
8

Melihat plugin jQuery ini: imgCheckbox (pada NPM dan bower )

Penafian: Tidak diperlukan javascript untuk menyelesaikan masalah ini. Ketegangan adalah antara rawatan dan efisiensi kode. Meskipun tidak perlu untuk plugin (atau javascript), itu tentu membuatnya lebih cepat untuk membangun dan sering lebih mudah untuk berubah.

Solusi Barebones:

Dengan HTML yang sangat sederhana (tidak ada kekacauan dengan kotak centang dan label dll.):

<img class="checkable" src="http://lorempixel.com/100/100" />

Anda dapat menggunakan jQuery toggleClass untuk mengaktifkan / menonaktifkan selectedatau checkedkelas pada clickacara:

$("img.checkable").click(function () {
    $(this).toggleClass("checked");
});

Barang yang diperiksa diambil dengan

$(".checked")

Ditambah kesejukan:

Anda dapat mendesain gambar berdasarkan ini tetapi masalah besar adalah bahwa tanpa elemen DOM lainnya Anda bahkan tidak dapat menggunakan ::beforedan ::aftermenambahkan hal-hal seperti tanda centang. Solusinya adalah membungkus gambar Anda dengan elemen lain (dan masuk akal juga untuk melampirkan pendengar klik ke elemen yang dibungkus).

$("img.checkable").wrap("<span class='fancychecks'>")

Ini membuat html Anda benar-benar bersih dan js Anda sangat mudah dibaca. Lihatlah cuplikan ...

Menggunakan Plugin jQuery imgCheckbox :

Terinspirasi oleh solusi di atas, saya telah membangun sebuah plugin yang dapat digunakan semudah:

$("img").imgCheckbox();
  • Suntikkan data untuk gambar yang diperiksa ke dalam formulir Anda
  • Mendukung tanda centang khusus
  • Mendukung CSS yang disesuaikan
  • Mendukung elemen yang dipilih sebelumnya
  • Mendukung grup radio alih-alih beralih-pindah gambar
  • Memiliki callback acara
  • Default yang masuk akal
  • Ringan dan super mudah digunakan

Lihat dalam aksi (dan lihat sumbernya )

jcuenod
sumber
Saya suka pendekatan ini juga, tetapi memiliki sejumlah kelemahan yang patut disebutkan, yang terbesar adalah ini: Dengan asumsi pengguna dimaksudkan untuk memilih gambar, informasi yang diberikan oleh pengguna dengan cara ini pasti dimaksudkan untuk diproses entah bagaimana, menjadi itu melalui panggilan AJAX atau melalui formulir kirim. Untuk pruposis pemrosesan lebih lanjut dari informasi yang diberikan oleh pengguna, memiliki kotak centang di mana sejumlah pilihan harus direfleksikan dan diproses adalah cara alami dan semantik untuk melakukannya.
connexo
Ini benar, ada di daftar todo saya untuk plugin - untuk membajak pengiriman formulir dan menyuntikkan data ke dalam formulir. Tapi Anda benar, kotak centang adalah semantik untuk formulir
jcuenod
Saya mencoba menggunakan plugin Anda, tetapi jika saya menambahkan lebih banyak gambar setelah inisialisasi sepertinya tidak ada cara untuk menghancurkan contoh sebelumnya sehingga gambar baru dapat dimasukkan
Ian Kim
@IanKim kasus penggunaan yang menarik, dapatkah Anda menjelaskan lebih lanjut tentang apa yang Anda coba lakukan dalam masalah di github? github.com/jcuenod/imgCheckbox
jcuenod
Ini adalah plugin yang luar biasa! tolong publikasikan Webjar =)
naXa
6

Saya akan menambahkan div tambahan dengan position: relative;dan class="checked"yang memiliki lebar / tinggi yang sama dengan gambar memiliki dan dari posisi dalam left: 0; top: 0;mengandung ikon. Dimulai dengan display: none;.

Sekarang Anda dapat mendengarkan clickacara-:

$( '.captcha_images' ).click( function() {
    $(this + '.checked').css( 'display', 'block' );
    $(this).animate( { width: '70%', height: '70%' } );
});

Dengan cara ini Anda bisa mendapatkan ikon dan juga mengubah ukuran gambar ke cara yang lebih kecil.

Perhatikan: Hanya ingin menunjukkan "logika" di balik pikiran saya, contoh ini mungkin tidak berfungsi atau memiliki beberapa bug di dalamnya.

Cagatay Ulubay
sumber
Teknik yang saya tunjukkan sangat sederhana dan kuat, bahkan sering diterapkan dalam situasi di mana Anda tidak memiliki kotak centang secara semantik, seperti mengubah tampilan elemen lain dan sejenisnya. Ini adalah usecase di mana ia bukan hanya solusi termudah, paling fleksibel, tetapi juga yang terbaik secara semantik.
connexo
2
Ya kau benar. Pada awalnya saya ingin menunjukkan jawaban pertama Anda dan memperbaikinya (sebelum mengedit), karena saya suka No-JS dan cara Semantic yang bagus, tetapi daripada saya membaca bahwa OP menginginkan sesuatu di jQuery jadi saya mengubah jawaban saya. Saya ingat di mana saya mendapat downvote, karena OP tidak menginginkan solusi "lebih baik" atau "jalan yang benar", tetapi cara persisnya ia menulis. Mungkin ada sesuatu yang saya baca atau tidak mengerti atau tergantung pada OP?
Cagatay Ulubay
2

Saya perhatikan jawaban lain yang tidak digunakan <label>(mengapa tidak?), Atau memerlukan kecocokan fordan idatribut. Ini berarti jika Anda memiliki ID bentrok, kode Anda tidak akan berfungsi, dan Anda harus ingat untuk membuat ID unik setiap kali.

Juga, jika Anda menyembunyikan inputdengan display:noneatau visibility:hidden, browser tidak akan fokus padanya.

Kotak centang dan teksnya (atau dalam hal ini, gambar) dapat dibungkus dengan label:

.fancy-checkbox-label > input[type=checkbox] {
  position: absolute;
  opacity: 0;
  cursor: inherit;
}
.fancy-checkbox-label {
  font-weight: normal;
  cursor: pointer;
}
.fancy-checkbox:before {
  font-family: FontAwesome;
  content: "\f00c";
  background: #fff;
  color: transparent;
  border: 3px solid #ddd;
  border-radius: 3px;
  z-index: 1;
}
.fancy-checkbox-label:hover > .fancy-checkbox:before,
input:focus + .fancy-checkbox:before {
  border-color: #bdbdff;
}
.fancy-checkbox-label:hover > input:not(:checked) + .fancy-checkbox:before {
  color: #eee;
}
input:checked + .fancy-checkbox:before {
  color: #fff;
  background: #bdbdff;
  border-color: #bdbdff;
}
.fancy-checkbox-img:before {
  position: absolute;
  margin: 3px;
  line-height: normal;
}
input:checked + .fancy-checkbox-img + img {
  transform: scale(0.9);
  box-shadow: 0 0 5px #bdbdff;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
<p>
  <label class="fancy-checkbox-label">
    <input type="checkbox">
    <span class="fancy-checkbox"></span>
    A normal checkbox
  </label>
</p>
<p>
  <label class="fancy-checkbox-label">
    <input type="checkbox">
    <span class="fancy-checkbox fancy-checkbox-img"></span>
    <img src="http://placehold.it/150x150">
  </label>
</p>

rybo111
sumber
1

Di sini contoh cepat memilih gambar seperti kotak centang

Contoh yang Diperbarui menggunakan Knockout.js:

var imageModel = function() {
    this.chk = ko.observableArray();
};
ko.applyBindings(new imageModel());
    input[type=checkbox] {
        display:none;
      }
 
  input[type=checkbox] + label
   {
       display:inline-block;
        width:150px;
        height:150px;
        background:#FBDFDA;
        border:none;
   }
   
   input[type=checkbox]:checked + label
    {
        background:#CFCFCF;
        border:none;
        position:relative;
        width:100px;
        height:100px;
        padding: 20px;
    }

   input[type=checkbox]:checked + label:after
    {
        content: '\2713';
        position:absolute;
        top:-10px;
        right:-10px;
        border-radius: 10px;
        width: 25px;
        height: 25px;
        border-color: white;
        background-color: blue;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<input type='checkbox' name='image1' value='image1' id="image1" data-bind="checked: chk"/><label for="image1"></label><label for="image1"><img class='testbtn'/></label>

<div data-bind="html: chk"></div>

YaBCK
sumber
1
Meskipun saya menyukai pendekatan Anda, akan sangat membantu bagi kebanyakan orang untuk menyatakan bahwa Anda menggunakan Knockout.js dalam contoh Anda.
connexo
@connexo Cheers, baru saja diperbarui untuk mengatakan contoh menggunakan Knockout.js
YaBCK
0

Untuk memperluas jawaban yang diterima bagi siapa saja yang menggunakan WordPress & GravityForms untuk menghasilkan formulir mereka dan ingin secara otomatis mengisi bidang kotak centang dengan daftar posting dan Thumbnail Unggulan mereka yang terkait

// Change '2' to your form ID
add_filter( 'gform_pre_render_2', 'populate_checkbox' );
add_filter( 'gform_pre_validation_2', 'populate_checkbox' );
add_filter( 'gform_pre_submission_filter_2', 'populate_checkbox' );
add_filter( 'gform_admin_pre_render_2', 'populate_checkbox' );

function populate_checkbox( $form ) {

    foreach( $form['fields'] as &$field )  {

        // Change '41' to your checkbox field ID
        $field_id = 41;
        if ( $field->id != $field_id ) {
            continue;
        }

        // Adjust $args for your post type
        $args = array(
                'post_type' => 'pet',
                'post_status' => 'publish',
                'posts_per_page' => -1,
                'tax_query' => array(
                        array(
                                'taxonomy' => 'pet_category',
                                'field' => 'slug',
                                'terms' => 'cat'
                        )
                )
        );

        $posts = get_posts( $args );

        $input_id = 1;

        foreach( $posts as $post ) {

            $feat_image_url = wp_get_attachment_image( get_post_thumbnail_id( $post->ID ), 'thumbnail' );
            $feat_image_url .= '<br />' . $post->post_title;

            if ( $input_id % 10 == 0 ) {
                $input_id++;
            }

            $choices[] = array( 'text' => $feat_image_url, 'value' => $post->post_title );
            $inputs[] = array( 'label' => $post->post_title, 'id' => "{$field_id}.{$input_id}" );

            $input_id++;
        }

        $field->choices = $choices;
        $field->inputs = $inputs;

    }

    return $form;
}

Dan CSS:

.gform_wrapper .gfield_checkbox li[class^="gchoice_2_41_"] {
    display: inline-block;
}

.gform_wrapper .gfield_checkbox li input[type="checkbox"][id^="choice_2_41_"] {
    display: none;
}


.gform_wrapper .gfield_checkbox li label[id^="label_2_41_"] {
    border: 1px solid #fff;
    padding: 10px;
    display: block;
    position: relative;
    margin: 10px;
    cursor: pointer;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

label[id^="label_2_41_"]:before {
    font-family: "font-icons";
    font-size: 32px;
    color: #1abc9c;
    content: " ";
    display: block;
    background-color: transparent;
    position: absolute;
    top: -5px;
    left: -5px;
    width: 25px;
    height: 25px;
    text-align: center;
    line-height: 28px;
    transition-duration: 0.4s;
    transform: scale(0);
}

label[id^="label_2_41_"] img {
    transition-duration: 0.2s;
    transform-origin: 50% 50%;
}

:checked + label[id^="label_2_41_"] {
    border-color: #ddd;
}

/* FontAwesome tick */
:checked + label[id^="label_2_41_"]:before {
    content: "\e6c8";
    background-color: transparent;
    transform: scale(1);
}

:checked + label[id^="label_2_41_"] img {
    transform: scale(0.9);
    box-shadow: 0 0 5px #333;
    z-index: 0;
}
essexboyracer
sumber