Я хотел бы иметь альтернативу стандартным флажкам - в основном, я хотел бы использовать изображения и когда пользователь щелкает изображение, исчезает и накладывает галочку.
В сущности, я хочу сделать что-то вроде Recaptcha 2, когда вам нужно щелкнуть изображения, соответствующие определенным критериям. Вы можете увидеть демонстрацию Recaptcha здесь, но иногда это может помочь вам решить текстовые вопросы, в отличие от выбора изображения. Итак, вот скриншот:
Когда вы нажимаете одно из изображений (в этом случае, содержащее изображение стейка), изображение, которое вы нажимаете, уменьшается по размеру, и появляется синий галочка, указывающий, что вы отметили его.
Скажем, я хочу воспроизвести этот точный пример.
Я понимаю, что у меня может быть 9 скрытых флажков и прикрепить некоторый jQuery, чтобы при щелчке по изображению он выбирает/отменяет скрытый флажок. Но как насчет сокращения изображения/наложения галочки?
Это легко реализовать самостоятельно, без предварительного решения. Также он научит вас многому, поскольку вам не кажется слишком легким использование CSS.
У ваших флажков должны быть разные атрибуты id
. Это позволяет подключить к нему <label>
, используя метку for
-attribute.
Пример:
<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1"><img src="http://someurl" /></label>
Прикрепление метки к флажку приведет к поведению браузера: всякий раз, когда кто-то нажимает на метку (или изображение внутри нее), этот флажок будет переключен.
Затем вы скроете флажок, применив для него display: none;
.
Теперь все, что вам нужно сделать, это установить стиль, который вы хотите для своей метки: перед псевдоэлементом (элементы замены флажка):
label:before {
background-image: url(../path/to/unchecked.png);
}
В последнем сложном шаге вы используете селектор CSS :checked
, чтобы изменить изображение, когда установлен флажок:
:checked + label:before {
background-image: url(../path/to/checked.png);
}
+
(смежный селектор) позволяет вам только заменять метки, которые непосредственно следуют за скрытым флажком в разметке.
Вы можете оптимизировать это, поместив оба изображения в spritemap и применив только изменение background-position
вместо замены изображения.
Конечно, вам нужно правильно поместить метку и применить display: block;
и установить правильные width
и height
.
Пример codepen и фрагмент кода, который я создал после этих инструкций, используют ту же технику , но вместо использования изображений для флажков замены флажка выполняются исключительно с помощью CSS, создавая :before
на ярлыке, который после проверки имеет content: "✓";
. Добавьте округленные границы и сладкие переходы, и результат действительно приятный!
Вот рабочий код, который демонстрирует технику и не требует изображений для флажка:
Вот фрагмент кода:
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;
}
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="http://lorempixel.com/100/100" /></label>
</li>
<li><input type="checkbox" id="cb2" />
<label for="cb2"><img src="http://lorempixel.com/101/101" /></label>
</li>
<li><input type="checkbox" id="cb3" />
<label for="cb3"><img src="http://lorempixel.com/102/102" /></label>
</li>
<li><input type="checkbox" id="cb4" />
<label for="cb4"><img src="http://lorempixel.com/103/103" /></label>
</li>
</ul>
:hover
:)
Вызывается три аккуратных устройства:
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>
<input type="radio" name="myRadio" id="myRadio1" />
также меняет ваш css на скрыть маркер: input[type=radio]{display: none;}
Смотрите этот плагин jQuery: imgCheckbox (на npm и bower)
Отказ от ответственности: Для решения этой проблемы не требуется javascript. Напряженность связана с ремонтопригодностью и эффективностью кода. Хотя нет необходимости в плагине (или любом javascript), он уверен, что он быстрее работает, и часто его легче изменить.
С очень простым HTML (ни один из беспорядков с флажками и ярлыками и т.д.):
<img class="checkable" src="http://lorempixel.com/100/100" />
Вы можете использовать jQuery toggleClass, чтобы включить/выключить класс selected
или checked
в событии click
:
$("img.checkable").click(function () {
$(this).toggleClass("checked");
});
Проверяемые элементы выбираются с помощью
$(".checked")
Вы можете стилизовать изображения, основанные на этом, но большая проблема заключается в том, что без других элементов DOM вы даже не можете использовать ::before
и ::after
для добавления таких вещей, как отметки. Решение состоит в том, чтобы обернуть ваши изображения другим элементом (и имеет смысл прикрепить прослушиватель кликов к обернутому элементу).
$("img.checkable").wrap("<span class='fancychecks'>")
Это оставляет ваш html действительно чистым и ваш js невероятно удобочитаемым. Взгляните на фрагмент...
/* Note that this js actually responds
to a click event on the wrapped element!
(not the image) */
$("img.checkable").wrap("<span class='fancychecks'>")
.parent().click(function() {
$(this).toggleClass("checked");
});
/* style the images */
span.fancychecks img {
display: block;
margin: 0;
padding: 0;
transition-duration: 300ms;
transform: scale(1);
filter: none;
-webkit-filter: grayscale(0);
}
span.fancychecks.checked img {
transform: scale(0.8);
filter: gray;
filter: grayscale(1);
-webkit-filter: grayscale(1);
}
/* style the parent spans */
span.fancychecks {
padding: 0;
margin: 5px;
display: inline-block;
border: 1px solid transparent;
transition-duration: 300ms;
}
span.fancychecks.checked {
border-color: #ccc;
}
/* Using conexo fantastic CSS, make the checkmarks */
span.fancychecks::before {
background-color: rgba(50, 200, 50, 0.7);
color: white;
content: "✓";
font-weight: bold;
border-radius: 50%;
position: absolute;
margin: 2px;
top: 1;
left: 1;
z-index: 1;
width: 25px;
height: 25px;
text-align: center;
line-height: 28px;
transform: scale(0);
transition-duration: 300ms;
}
span.fancychecks.checked::before {
transform: scale(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<img class="checkable" src="http://lorempixel.com/100/100/city/1" />
<img class="checkable" src="http://lorempixel.com/100/100/city/2" />
<img class="checkable" src="http://lorempixel.com/100/100/city/3" />
Вдохновленный решением выше, я создал плагин, который можно использовать так же легко, как:
$("img").imgCheckbox();
Смотрите в действии (и см. источник)
Я бы добавил дополнительный div с position: relative;
и class="checked"
, который имеет ту же ширину/высоту, что и изображение, а не положение в left: 0; top: 0;
, содержащее значок. Он начинается с display: none;
.
Теперь вы можете слушать click
-event:
$( '.captcha_images' ).click( function() {
$(this + '.checked').css( 'display', 'block' );
$(this).animate( { width: '70%', height: '70%' } );
});
Таким образом вы можете получить значок, а также изменить размер изображения на меньший путь.
Примечание. Просто хотелось показать вам "логику" моих мыслей, этот пример может не работать или содержать некоторые ошибки.
Вот краткий пример выбора изображения, такого как флажок
Обновленный пример с помощью 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>
Чтобы расширить принятый ответ для тех, кто использует WordPress и GravityForms, чтобы сгенерировать их формы и пожелать автоматически заполнить поля флажка списком сообщений и их связанной Featured Thumbnail
// 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;
}
И 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;
}
Я заметил, что другие ответы либо не используют <label>
(почему бы и нет?), либо требуют сопоставления атрибутов for
и id
. Это означает, что если у вас есть конфликтующие идентификаторы, ваш код не будет работать, и вы должны помнить о том, чтобы каждый раз создавать уникальные идентификаторы.
Кроме того, если вы скроете input
с помощью display:none
или visibility:hidden
, браузер не будет фокусироваться на нем.
Флажок и его текст (или в этом случае, изображение) могут быть завернуты в метку:
.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>