Search code examples
htmlcsscss-selectorshoverpseudo-class

Input label hover issue with absolute positioning


I have <input type="text"/> and styles on :hover, for example:

input:hover {
    border-color: red;
}

I want to add search icon to my input. Input :hover styles apply well when I hover on the icon, try it:

JSFiddle

input, span {
    display: inline-block;
    vertical-align: middle;
    height: 30px;
}

input:hover {
    border-color: red;
}

span {
    background: url(https://cdn1.iconfinder.com/data/icons/hawcons/32/698627-icon-111-search-128.png) 50% 50%/100% 100% no-repeat;
    width: 25px;
    height: 25px;
}
<label>
    <input type="text"/>
    <span></span>
</label>

But if I put the search icon visually on the input, the input :hover styles don't apply when I hover the icon:

JSFiddle

label {
    position: relative;
}

input, span {
    display: inline-block;
    vertical-align: middle;
    height: 30px;
}

input:hover {
    border-color: red;
}

span {
    background: url(https://cdn1.iconfinder.com/data/icons/hawcons/32/698627-icon-111-search-128.png) 50% 50%/100% 100% no-repeat;
    width: 25px;
    height: 25px;
    position: absolute;
    top: -4px;
    right: 4px;
}
<label>
    <input type="text"/>
    <span></span>
</label>

Question: can I fix this behavior? I want to apply input :hover styles when I hover the input at any point.

P.S. I know I could set :hover styles on <label> or set it with Javascript/jQuery, but I don't want to do it because I have many cases of using <input> and in other cases I have no <label> and an icon, only <input>. I'd want the solution without it.


Solution

  • One solution is to add poiter-events rule:

    span {
        background: url(https://cdn1.iconfinder.com/data/icons/hawcons/32/698627-icon-111-search-128.png) 50% 50%/100% 100% no-repeat;
        width: 25px;
        height: 25px;
        position: absolute;
        top: -4px;
        right: 4px;
        pointer-events: none; <!-- this line -->
    }
    

    Demo: http://jsfiddle.net/kfgggd1b/4/

    But it's not very well supported: http://caniuse.com/#search=pointer

    Another approach is to reorganize HTML a little by putting span before input and then

    span:hover + input, 
    input:hover {
        border-color: red;
    }
    span {
        background: url(https://cdn1.iconfinder.com/data/icons/hawcons/32/698627-icon-111-search-128.png) 50% 50%/100% 100% no-repeat;
        width: 25px;
        height: 25px;
        position: absolute;
        top: -4px;
        right: 4px;
    }
    

    Demo: http://jsfiddle.net/kfgggd1b/5/