Reputation: 1143
First, please do not mark this as duplicate, cause I want to ask a little modification from this QnA, here. I'm using this answer to achieve what I want, but it almost meets what I need. Here is his demo.
I am trying to achieve what he did, this is what I've made so far. But, when I click the image, because of the border, it makes the images a little get bigger. What I want is, when the image (checkbox) checked, there are checkboxes icon on the top left (its done) and the image surrounds with a border without making the image get bigger. Here is the code in my snippet:
here is the HTML:
<ul>
<li><input type="checkbox" id="cb1" />
<label for="cb1"><img src="http://lorempixel.com/103/103" /></label>
</li>
<li><input type="checkbox" id="cb2" />
<label for="cb2"><img src="http://lorempixel.com/102/102" /></label>
</li>
</ul>
this is the CSS:
ul {
list-style-type: none;
}
li {
display: inline-block;
}
input[type="checkbox"][id^="cb"] {
display: none;
}
label {
display: block;
position: relative;
cursor: pointer;
width: 100%;
height: 100%;
}
label:before {
background-color: red;
color: white;
display: block;
border: 1px solid red;
position: absolute;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
transition-duration: 0.4s;
-webkit-transition-duration: 0.4s;
-moz-transition-duration: 0.4s;
-ms-transition-duration: 0.4s;
}
label img {
height: 100%;
width: 100%;
}
:checked + label {
border-color: red;
}
:checked + label:before {
content: "✓";
background-color: red;
border: 1px solid red;
z-index: 99;
}
:checked + label img {
z-index: -1;
border: 1px solid red;
}
Thank you!
Upvotes: 0
Views: 3296
Reputation: 1710
You can use a "label" tag that contains an "img" tag inside.
Here's an example of using an image as a checkbox and radio.
* {
font-family: Lato;
margin: 0;
padding: 0;
--transition: 0.15s;
--border-radius: 0.5rem;
--background: #ffc107;
--box-shadow: #ffc107;
}
.cont-bg {
min-height: 100vh;
background-image: radial-gradient(
circle farthest-corner at 7.2% 13.6%,
rgba(37, 249, 245, 1) 0%,
rgba(8, 70, 218, 1) 90%
);
padding: 1rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.cont-title {
color: white;
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 1rem;
}
.cont-main {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
}
.cont-checkbox {
width: 150px;
height: 100px;
border-radius: var(--border-radius);
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
background: white;
transition: transform var(--transition);
}
.cont-checkbox:first-of-type {
margin-bottom: 0.75rem;
margin-right: 0.75rem;
}
.cont-checkbox:active {
transform: scale(0.9);
}
input {
display: none;
}
input:checked + label {
opacity: 1;
box-shadow: 0 0 0 3px var(--background);
}
input:checked + label img {
-webkit-filter: none; /* Safari 6.0 - 9.0 */
filter: none;
}
input:checked + label .cover-checkbox {
opacity: 1;
transform: scale(1);
}
input:checked + label .cover-checkbox svg {
stroke-dashoffset: 0;
}
label {
display: inline-block;
cursor: pointer;
border-radius: var(--border-radius);
overflow: hidden;
width: 100%;
height: 100%;
position: relative;
opacity: 0.6;
}
label img {
width: 100%;
height: 70%;
object-fit: cover;
clip-path: polygon(0% 0%, 100% 0, 100% 81%, 50% 100%, 0 81%);
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
label .cover-checkbox {
position: absolute;
right: 5px;
top: 3px;
z-index: 1;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--box-shadow);
border: 2px solid #fff;
transition: transform var(--transition),
opacity calc(var(--transition) * 1.2) linear;
opacity: 0;
transform: scale(0);
}
label .cover-checkbox svg {
width: 13px;
height: 11px;
display: inline-block;
vertical-align: top;
fill: none;
margin: 5px 0 0 3px;
stroke: #fff;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
stroke-dasharray: 16px;
transition: stroke-dashoffset 0.4s ease var(--transition);
stroke-dashoffset: 16px;
}
label .info {
text-align: center;
margin-top: 0.2rem;
font-weight: 600;
font-size: 0.8rem;
}
<div class="cont-bg">
<div class="cont-title">Checkbox</div>
<div class="cont-main">
<div class="cont-checkbox">
<input type="checkbox" id="myCheckbox-1" />
<label for="myCheckbox-1">
<img
src="https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-mazda-mx-5-miata-mmp-1-1593459650.jpg?crop=0.781xw:0.739xh;0.109xw,0.0968xh&resize=480:*"
/>
<span class="cover-checkbox">
<svg viewBox="0 0 12 10">
<polyline points="1.5 6 4.5 9 10.5 1"></polyline>
</svg>
</span>
<div class="info">Mazda MX-5 Miata</div>
</label>
</div>
<div class="cont-checkbox">
<input type="checkbox" id="myCheckbox-2" />
<label for="myCheckbox-2">
<img
src="https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2020-chevrolet-corvette-c8-102-1571146873.jpg?crop=0.548xw:0.411xh;0.255xw,0.321xh&resize=980:*"
/>
<span class="cover-checkbox">
<svg viewBox="0 0 12 10">
<polyline points="1.5 6 4.5 9 10.5 1"></polyline>
</svg>
</span>
<div class="info">Toyota Supra</div>
</label>
</div>
</div>
<div class="cont-title">Radio</div>
<div class="cont-main">
<div class="cont-checkbox">
<input type="radio" name="myRadio" id="myRadio-1" />
<label for="myRadio-1">
<img
src="https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-mazda-mx-5-miata-mmp-1-1593459650.jpg?crop=0.781xw:0.739xh;0.109xw,0.0968xh&resize=480:*"
/>
<span class="cover-checkbox">
<svg viewBox="0 0 12 10">
<polyline points="1.5 6 4.5 9 10.5 1"></polyline>
</svg>
</span>
<div class="info">Mazda MX-5 Miata</div>
</label>
</div>
<div class="cont-checkbox">
<input type="radio" name="myRadio" id="myRadio-2" />
<label for="myRadio-2">
<img
src="https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2020-chevrolet-corvette-c8-102-1571146873.jpg?crop=0.548xw:0.411xh;0.255xw,0.321xh&resize=980:*"
/>
<span class="cover-checkbox">
<svg viewBox="0 0 12 10">
<polyline points="1.5 6 4.5 9 10.5 1"></polyline>
</svg>
</span>
<div class="info">Toyota Supra</div>
</label>
</div>
</div>
</div>
Upvotes: 0
Reputation: 4170
So if requirement is when you click on image, you need to show ✓
on left top corner of image, and you also want to show some border around image, then what you have done is absolutely right.
If you are concerned about image moving by n
pixel, then keep in mind that border
occupy some space unlike outline
which doesnt need any space. Outline
takes n
pixel around object and apply border type effect.
So there are 2 solution -
transparent
so it will reserve the space for your border and actually you will not see any border around it, and on clicking (selecting image) just change the color of border.label img {
height: 100%;
width: 100%;
border: 1px solid transparent;
}
:checked + label img {
z-index: -1;
outline: 1px solid red;
}
details
that will be shown only when image selected and will be aligned in centre of the image.This below css rule to hide the details initially and making them in centre etc.
label img + .details
{
color:white;
position:absolute;
top:0px;
width:100%;
display:none;
margin-top:50%;
transform: translatey(-50%);
text-align:center;
}
Now, we will show the details
section if image selected.
:checked + label img + .details
{
display:block;
}
Upvotes: 0
Reputation: 3117
Try This:
ul {
list-style-type: none;
}
li {
display: inline-block;
}
input[type="checkbox"][id^="cb"] {
display: none;
}
label {
border: 1px solid #fff;
display: block;
position: relative;
cursor: pointer;
}
label:before {
background-color: red;
color: white;
content: "";
display: block;
border: 1px solid red;
position: absolute;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
transition-duration: 0.4s;
transform: scale(0);
}
label img {
height: 100%;
width: 100%;
transition-duration: 0.2s;
transform-origin: 50% 50%;
}
:checked + label {
border-color: red;
}
:checked + label:before {
content: "✓";
background-color: red;
z-index: 99;
transform: scale(1);
}
:checked + label img {
z-index: -1;
transform: scale(0.9);
}
<ul>
<li><input type="checkbox" id="cb1" />
<label for="cb1"><img src="http://lorempixel.com/103/103" /></label>
</li>
<li><input type="checkbox" id="cb2" />
<label for="cb2"><img src="http://lorempixel.com/102/102" /></label>
</li>
</ul>
Upvotes: 0
Reputation: 2758
I gave fixed height and width to li and when the checkbox is checked i am changing the height and width of an image and aligning it in the center. hope this is what you are looking for. thanks.
ul {
list-style-type: none;
}
li {
display: inline-block;
}
input[type="checkbox"][id^="cb"] {
display: none;
}
label {
display: block;
position: relative;
cursor: pointer;
height: 120px;
border: 1px solid;
width: 120px;
}
label:before {
background-color: red;
color: white;
display: block;
position: absolute;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
transition-duration: 0.4s;
}
label img {
height: 100%;
width: 100%;
}
:checked + label {
border-color: red;
}
:checked + label:before {
content: "✓";
background-color: red;
border: 1px solid red;
z-index: 99;
}
:checked + label img {
z-index: -1;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 100px;
width: 100px;
}
<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>
Upvotes: 0
Reputation: 14159
Add Border for img with transparent
label img {
height: 100%;
width: 100%;
border: 1px solid transparent;
}
https://codepen.io/anon/pen/PVRxRM
Upvotes: 1