sergdenisov
sergdenisov

Reputation: 8572

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.

Upvotes: 2

Views: 376

Answers (2)

Sergii M
Sergii M

Reputation: 36

You can add transparent background to input and place icon absolutely below it (with less z-index).

    * {
        box-sizing: border-box;
    }
    label {
        position: relative;
        display: inline-block;
        background: white;
    }
    input {
        width: 100%;
        border: 1px solid #000;
        height: 30px;
        outline: none;
        position: relative;
        z-index: 2;
        background: transparent;
    }
    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;
        margin-top: -13px;
        position: absolute;
        top: 50%;
        right: 4px;
        z-index: 1;
    }

Here is a Fiddle

Upvotes: 1

dfsq
dfsq

Reputation: 193311

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/

Upvotes: 1

Related Questions