103

Using HTML and CSS, how do I visually place a button inside an input element as shown below?

password input

The user should be able to interact with the input as normal. The text shouldn't go behind the button, even when it's long. Focus should work correctly. The form should be accessible and work correctly in screen readers. The whole component should be styleable with CSS, and should be able to easily resize to fit the space available.

How do I accomplish this with modern CSS?

Tim
  • 12,318
  • 7
  • 50
  • 72
Vlad Otrocol
  • 2,952
  • 7
  • 33
  • 55

6 Answers6

127

Use a Flexbox, and put the border on the form.

The best way to do this now (2022) is with a flexbox.

  • Put the border on the containing element (in this case I've used the form, but you could use a div).
  • Use a flexbox layout to arrange the input and the button side by side. Allow the input to stretch to take up all available space.
  • Now hide the input by removing its border.

Run the snippet below to see what you get.

form {
  /* This bit sets up the horizontal layout */
  display:flex;
  flex-direction:row;
  
  /* This bit draws the box around it */
  border:1px solid grey;

  /* I've used padding so you can see the edges of the elements. */
  padding:1px;
}

input {
  /* Tell the input to use all the available space */
  flex-grow:2;
  /* And hide the input's outline, so the form looks like the outline */
  border:none;
}

/* remove the input focus blue box, it will be in the wrong place. */
input:focus {
  outline: none;
}

/* Add the focus effect to the form so it contains the button */
form:focus-within { 
  outline: 1px solid blue 
}

button {
  /* Just a little styling to make it pretty */
  border:1px solid blue;
  background:blue;
  color:white;
}
<form>
  <input />
  <button>Go</button>
</form>

Why this is good

  • It will stretch to any width.
  • The button will always be just as big as it needs to be. It won't stretch if the screen is wide, or shrink if the screen is narrow.
  • The input text will not go behind the button.

Caveats and Browser Support

There's limited Flexbox support in IE9, so the button will not be on the right of the form. IE9 has not been supported by Microsoft for some years now, so I'm personally quite comfortable with this.

I've used minimal styling here. I've left in the padding to show the edges of things. You can obviously make this look however you want it to look with rounded corners, drop shadows, etc..

superluminary
  • 47,086
  • 25
  • 151
  • 148
121

The button isn't inside the input. Here:

input[type="text"] {
    width: 200px;
    height: 20px;
    padding-right: 50px;
}

input[type="submit"] {
    margin-left: -50px;
    height: 20px;
    width: 50px;
}

Example: http://jsfiddle.net/s5GVh/

Alfo
  • 4,801
  • 9
  • 38
  • 51
  • 6
    This is how I do it however I can't figure out how to prevent the text overlapping the submit button. – user1078385 Oct 11 '13 at 10:16
  • 6
    It shouldn't happen if you use the same width for `padding-right` and `margin-left` – SuN Sep 12 '14 at 14:44
  • 1
    +1 for right-padding on the input. Solves any issues with standard browser (IE10, iOS etc) input clear buttons overlapping with the search button. – Liam Gray Sep 11 '15 at 13:25
  • breaks w/ responsive view. ;( –  Aug 29 '16 at 03:20
  • 1
    This does not answer the question. The question is how to put it inside the input. I came here looking for a way to have it inside and toggling the visibility of the button based on the value changing. – Johan Tidén Oct 20 '16 at 08:19
  • 6
    @JohanTidén It does answer the question. To a user, the button is inside the field. Of course because we're coders, we can tell that it's not really inside... but that's besides the point. The point is to present a user with a pleasant experience. – Sami Fouad Feb 05 '17 at 13:20
  • you can prevent the text overlapping the submit button by setting the maxlenght attribute on the input, like – DeZeA Jul 25 '22 at 05:10
36

.flexContainer {
    display: flex;
}

.inputField {
    flex: 1;
}
<div class="flexContainer">
    <input type="password" class="inputField">
    <button type="submit"><img src="arrow.png" alt="Arrow Icon"></button>
</div>
Lars-Lasse
  • 554
  • 5
  • 9
22

I found a great code for you:

HTML

<form class="form-wrapper cf">
    <input type="text" placeholder="Search here..." required>
    <button type="submit">Search</button>
</form>

CSS

/*Clearing Floats*/
.cf:before, .cf:after {
    content:"";
    display:table;
}

.cf:after {
    clear:both;
}

.cf {
    zoom:1;
}    
/* Form wrapper styling */
.form-wrapper {
    width: 450px;
    padding: 15px;
    margin: 150px auto 50px auto;
    background: #444;
    background: rgba(0,0,0,.2);
    border-radius: 10px;
    box-shadow: 0 1px 1px rgba(0,0,0,.4) inset, 0 1px 0 rgba(255,255,255,.2);
}

/* Form text input */

.form-wrapper input {
    width: 330px;
    height: 20px;
    padding: 10px 5px;
    float: left;   
    font: bold 15px 'lucida sans', 'trebuchet MS', 'Tahoma';
    border: 0;
    background: #eee;
    border-radius: 3px 0 0 3px;     
}

.form-wrapper input:focus {
    outline: 0;
    background: #fff;
    box-shadow: 0 0 2px rgba(0,0,0,.8) inset;
}

.form-wrapper input::-webkit-input-placeholder {
   color: #999;
   font-weight: normal;
   font-style: italic;
}

.form-wrapper input:-moz-placeholder {
    color: #999;
    font-weight: normal;
    font-style: italic;
}

.form-wrapper input:-ms-input-placeholder {
    color: #999;
    font-weight: normal;
    font-style: italic;
}   

/* Form submit button */
.form-wrapper button {
    overflow: visible;
    position: relative;
    float: right;
    border: 0;
    padding: 0;
    cursor: pointer;
    height: 40px;
    width: 110px;
    font: bold 15px/40px 'lucida sans', 'trebuchet MS', 'Tahoma';
    color: #fff;
    text-transform: uppercase;
    background: #d83c3c;
    border-radius: 0 3px 3px 0;     
    text-shadow: 0 -1px 0 rgba(0, 0 ,0, .3);
}  

.form-wrapper button:hover {    
    background: #e54040;
}  

.form-wrapper button:active,
.form-wrapper button:focus {  
    background: #c42f2f;
    outline: 0;  
}

.form-wrapper button:before { /* left arrow */
    content: '';
    position: absolute;
    border-width: 8px 8px 8px 0;
    border-style: solid solid solid none;
    border-color: transparent #d83c3c transparent;
    top: 12px;
    left: -6px;
}

.form-wrapper button:hover:before {
    border-right-color: #e54040;
}

.form-wrapper button:focus:before,
.form-wrapper button:active:before {
        border-right-color: #c42f2f;
}     

.form-wrapper button::-moz-focus-inner { /* remove extra button spacing for Mozilla Firefox */
    border: 0;
    padding: 0;
}    

Demo: On fiddle Source: Speckyboy

Sahil Popli
  • 1,967
  • 14
  • 21
  • 5
    Fun fact: -9999px is the furthest you can go (afaicr) – Alfo Mar 09 '13 at 18:43
  • 2
    Alfo, the text overlaps the button in IE when you get a lot of text in the input. That's why this is the accepted answer. – Aaronius Feb 28 '14 at 22:39
  • If you have a different font-size declared (bigger one), the text will not be visible. – MEM Apr 24 '14 at 11:54
  • 8
    The whole load of code, and no explanation at all... What is the main idea of solution? Why it ever works? What is a re-usable piece? – C-F Feb 19 '17 at 23:46
3

This is the cleanest way to do in bootstrap v3.

<div class="form-group">
    <div class="input-group">
        <input type="text" name="search" class="form-control" placeholder="Search">
        <span><button type="submit" class="btn btn-primary"><i class="fa fa-search"></i></button></span>
     </div>
</div>
Ebrahim Karimi
  • 732
  • 8
  • 24
Brennan James
  • 332
  • 2
  • 7
0

This can be achieved using inline-block JS fiddle here

<html>
<body class="body">
    <div class="form">
        <form class="email-form">
            <input type="text" class="input">
            <a href="#" class="button">Button</a>
        </form>
    </div>
</body>
</html>


<style>
* {
    box-sizing: border-box;
}

.body {
    font-family: Arial, sans-serif;
    font-size: 14px;
    line-height: 20px;
    color: #333;
}

.form {
    display: block;
    margin: 0 0 15px;
}

.email-form {
    display: block;
    margin-top: 20px;
    margin-left: 20px;
}

.button {
    height: 40px;
    display: inline-block;
    padding: 9px 15px;
    background-color: grey;
    color: white;
    border: 0;
    line-height: inherit;
    text-decoration: none;
    cursor: pointer;
}

.input {
    display: inline-block;
    width: 200px;
    height: 40px;
    margin-bottom: 0px;
    padding: 9px 12px;
    color: #333333;
    vertical-align: middle;
    background-color: #ffffff;
    border: 1px solid #cccccc;
    margin: 0;
    line-height: 1.42857143;
}
</style>
van
  • 550
  • 4
  • 15