Steve Price
Steve Price

Reputation: 600

Overlay image on radio button selection

Below is a code snippet from a page that shows attribute options. The code shown is for an item selected by hidden radio button, and the requirement was for the attribute image to be overlaid with a checkmark when selected. Whilst I have got the checkmark to show on selection, it is always behind the original image. I have tried using z-index, opacity, and also absolute and relative positioning. What is the way to achieve this? I've run out of ideas. I have already looked at multiple answers for similar questions, but none have worked for me.

<div class="attribImg">
<input type="radio" name="id[11]" value="61" checked="checked" id="attrib-11-61" />
<label class="attribsRadioButton four" for="attrib-11-61"><img src="images/attributes/18mg.png" alt="" width="50" height="50" />
</label>
<br />
</div>

Css used is:

input[type="radio"] {
visibility:hidden;
}
label {
cursor: pointer;
}

.attribImg {z-index:0;}

input[type="radio"]:checked+label{
background:url(../images/checkmark.png) no-repeat 7px -20px;
}    

Fiddle is http://jsfiddle.net/1jcz1xyn/

Upvotes: 0

Views: 3252

Answers (3)

teefars
teefars

Reputation: 612

i suggest you try to manipulate the icon/image with CSS background-image only, instead of having one case with img and another with CSS. If you do that, z-index won't fix cause it's a logical error.

If you are going to use images/icons (in some cases that's useful for transitions), its also better to add both with the same technique and change the state with css.

So, you can manipulate with CSS:

<div class="form-item">
    <label for="radio-1">
        <input type="radio" name="radios" id="radio-1"> <span>Sample 1</span>
    </label>
</div>

label > input[type="radio"]{
    display: none;
}
    input[type="radio"]:checked + span:after{
        font-family:"FontAwesome";
        content: "\f00c";
        margin-left:10px;
    }

And you can add both images in the same form-field, and manipulate them with some CSS (And FontAwesome):

<div class="form-item">
    <label for="radio-switch-2">
        <input type="radio" name="radios-2" id="radio-switch-2">
        <div class="radio-switch-state">
            <span class="icon-off"></span>
            <span class="icon-on"></span>
        </div>
    </label>
</div>


    input[type="radio"]{
        display: none;
    }
    .radio-switch-state{
        background-color:#aaa;
        display: inline-block;
        color:#fff;
        transition:all .5s ease;
        width:50px;
        height:50px;
        position: relative;
        overflow:hidden;
        vertical-align:middle;
    }
        .radio-switch-state .icon-on,
        .radio-switch-state .icon-off{
            display: inline-block;
            position: absolute;
            width:100%;
            top:0;
        }
        // If you are using font
        .radio-switch-state .icon-on:after,
        .radio-switch-state .icon-off:after{
            font-family:"FontAwesome";
            width:100%;
            display: block;
            line-height:50px;
            position: absolute;
            transition:all .5s ease;
        }
            .radio-switch-state .icon-on:after{
                content: "\f00c";
                margin-left:100;
                left:100%;
            }
            .radio-switch-state .icon-off:after{
                content: "\f056";
                left:0;
            }
                .radio-switch-state:hover{
                    background-color:#FFA374;
                    cursor:pointer;
                }
                input[type="radio"]:checked + .radio-switch-state{
                    background-color:#FA8144;
                }
            input[type="radio"]:checked + .radio-switch-state .icon-on:after{
                content: "\f00c";
                margin-left:100;
                left:0;
            }
            input[type="radio"]:checked + .radio-switch-state .icon-off:after{
                content: "\f056";
                left:-100%;
            }

I made a Pen with both samples.

Also, when using icons try to use an icon font library, like FontAwesome or Glyphicon.


Edit - Added a sample with images

Upvotes: 1

Max Chalov
Max Chalov

Reputation: 1

Maybe this variant will help you? It's without any changes to HTML. I've used ::after instead and here's the Fiddle: https://jsfiddle.net/mvchalov/1jcz1xyn/2/

input[type="radio"]:checked+label::after{
background:url(https://cdn1.iconfinder.com/data/icons/mimiGlyphs/16/check_mark.png) no-repeat center center;
    width:50px;
    height:50px;
    position: absolute;
    content:'';
    margin:0 0 0 -50px;
}

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 192382

The problem is caused by the <img> being inside the <label>. No matter the z-index you use on the label, the child (img), will always be above it's parent background, unless you set the child with z-index: -1 (updated fiddle - click the 2nd):

.attribImg {
    position: relative; /** this is the positioning context **/
    width: 50px;
    height: 50px;
}
input {
    visibility: hidden;
}

label {
    position: absolute;
    width: 100%;
    height: 100%;
    cursor: pointer;
}

img {
    position: relative;
    z-index: -1;
}

input[type="radio"]:checked+label {    background:url(https://cdn1.iconfinder.com/data/icons/mimiGlyphs/16/check_mark.png) no-repeat center center;
}

Upvotes: 1

Related Questions