2

I need to style a text input like this input

The requiremets are:

  1. fluid width (stretches to container width)
  2. border color changes on focus
  3. border color changes on error

Is there some simple way to do it with css?

What I've come up now is quite complex, requires js and it works not too smoothly -

<div class="inpt"><input type="text" /></div>

jQuery(".inpt").delegate("*", "focus blur", function() {
    var elem = jQuery(this);
    var elem2 = jQuery(this).parent();
    setTimeout(function() {
        elem2.toggleClass("focused", elem.is(":focus"));
    }, 0);
});

http://jsfiddle.net/4sKV9/

I had to wrap an input in a div and style that div using images on :before and :after
Obviously :active doesn't work for div in this case and thus I had to toggle some class with a script.

I feel like there must be some simple solution that I'm missing. Can someone suggest anything better?

2 Answers 2

2

This solution uses jQuery to detect focus on the <input> and add/remove .focused class on parent container.

Both left and right arrrows are made of CSS with 2 <span> elements and :before / :after.

The input is responsive and adapts to the width of it's container.

FIDDLE

HTML :

<div class="inpt"> 
    <span class="left arrow"></span>
    <input type="text" /> 
    <span class="right arrow"></span>
</div>

CSS :

.inpt {
    position:relative;
    margin:5%;
    width:50%;
}
.left, .right {
    position: absolute;
    top:14px;
}
.right {
    right:0;
}
.arrow:after, .arrow:before {
    top: 50%;
    border: solid transparent;
    content:" ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}
.arrow:after {
    border-color: rgba(255, 255, 255, 0);
    border-width: 12px;
    margin-top: -12px;
}
.arrow:before {
    border-color: rgba(220, 228, 228, 0);
    border-width: 15px;
    margin-top: -15px;
}
.left:after, .left:before {
    right: 100%;
}
.left:after {
    border-right-color: #fff;
}
.left:before {
    border-right-color: #dce4e4;
}
.right:after, .right:before {
    left: 100%;
}
.right:after {
    border-left-color: #fff;
}
.right:before {
    border-left-color: #dce4e4;
}
.focused input {
    border-color: #afddda;
}
.focused .right:before {
    border-left-color: #afddda;
}
.focused .left:before {
    border-right-color: #afddda;
}
input {
    border-top: 2px #dce4e4 solid;
    border-bottom: 2px #dce4e4 solid;
    border-left:none;
    border-right:none;
    padding:2px 10px 0px;
    height: 29px;
    display: block;
    outline: 0;
    width: 100%;
    margin: 6px 0;
    box-sizing:border-box;
}

jQuery

$('input').focus(function () {
    $(this).parent().addClass('focused');
});

$('input').blur(function () {
    $(this).parent().removeClass('focused');
});
Sign up to request clarification or add additional context in comments.

6 Comments

Can you change the angle of arrows?
@Andrey do you mean make them less wide?
I mean make them like on the image in my original question. I have to follow the design.
@Andrey sorry to be so long, I had other things to do here is the fiddle : jsfiddle.net/webtiki/N36WS
web-tiki Thanks for your input. This solution is not perfect, but I'll mark it as accepted because it seems that nothing better can be found. Just to mention the cons - 1. two additional spans; 2. the border looks a little distorted (especially when you zoom in your browser). Anyways thanks again!
|
0

Edit: You do need JS for this. :before and :after can't be applied to input fields. See web-tiki's answer.

You don't need Javascript in this case. :focus is a valid pseudo class in CSS. Have a look at this article about :focus.

input:focus {
    border-color: red;
}

With the help of the pseudo classes :before and :after you can create arrows in pure css, too.

3 Comments

You didn't understand what the problem is and you haven't looked into my fiddle. I already used :before and :after. But you have to know that :before and :after elements are not applicable to inputs. So I had to apply them to a wrapper div. But you can't apply :focus or :active on div, you apply it to input. But the styles are tied to a wrapper div, so you need some js to check if an input has focus then toggle class on wrapper div. This is what I did and it works, but I'm still looking for a more elegant solution.
The css arrows you suggested won't help because you can only make 45 degree with them.
You're right about :before and :after, my mistake. But you can make CSS arrows with less or more then 45 degrees.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.