3

I have a fixed-size navbar (using Bootstrap) that contains four divs. These divs contain a logo, some links/dropdowns and a search box:

┌────────────────────────────navbar (fixed-size)──────────────────────────────┐
│┌───logo───┐┌───dropdown───┐┌───────────links──────────┐┌────search box─────┐│
││fixed-size││  fixed-size  ││      variable width      ││  fill remaining   ││
│└──────────┘└──────────────┘└──────────────────────────┘└───────────────────┘│
└─────────────────────────────────────────────────────────────────────────────┘

I want the search box (the box on the far right) to fill the remaining space in the container. The search box comprises an input and a button:

┌─────────────────────────────────┐
│┌─────────────────────┐┌────────┐│
││        <input>      ││<button>││
│└─────────────────────┘└────────┘│
└─────────────────────────────────┘

The button has a fixed size but I want the input to scale horizontally, stretching the search box to fill its parent (the nav-bar).

Edit: To clarify, I want the search box to take up the (horizontal) space left over from when it's siblings (logo, dropdown and links) have taken up their space. Since the search box is made out of an input and a button and the button will have a fixed width, I want the input to expand and push the search box's boundaries until the search box fills the space it's siblings left in the navbar

jbb
  • 346
  • 3
  • 9

3 Answers3

1

This is how I would do it: http://jsfiddle.net/vU52q/

You have your wrapper and child elements:

<div class="search">
    <input type="text" />
    <button type="submit">Go</button>
</div>

And you set the container to position: relative; and your submit button to position: absolute; and give the container enough padding for the button.

.search {
    box-sizing: border-box;
    background: #0f0;
    padding: 5px 100px 5px 5px;
    position: relative;
    width: 300px;
}
.search input {
    width: 100%;
}
.search button {
    position: absolute;
    top: 5px;
    right: 5px;
    width: 85px;
}

That way, the input is always the width of the parent element minus the width of the fixed width button.

You could also play with inline alignment and css calc, but this is my preferred way.

If you want to play with calc, you can check this out, and it might provide more of an option to add additional fixed size elements: http://jsfiddle.net/ug7a9/

This takes into account each section and explicitly adds it to the width calculation.

<div class="search">
    <button type="submit">Go</button><!--
    --><button type="submit">Go</button><!--
    --><input type="text" /><!--
    --><button type="submit">Go</button>
</div>

The comments are in there to prevent space in between elements (you can also do a font-size: 0) on the .search element.

* {
    box-sizing: border-box;
}
.search {
    background: #0f0;
    position: relative;
    width: 300px;
}
.search input {
    display: inline-block;
    width: calc(100% - 50px - 50px - 50px);
}
.search button {
    display: inline-block;
    width: 50px;
}

You'd want to be a bit more explicit with your selectors (i.e. don't do *), but for quick demo purposes I put this in.

Chad
  • 5,308
  • 4
  • 24
  • 36
  • I'm sorry maybe my question wasn't clear enough. You are setting the width of .search to 300px. I want the width of .search (and thus the input) to be the space left over when .search's siblings (logo, dropdown and links) have taken up the (horizontal) space they need. – jbb Apr 07 '14 at 18:33
  • So you want them all dynamic? Did you take a look at this: http://stackoverflow.com/questions/6938900/css-input-take-remaining-space? – Chad Apr 07 '14 at 18:41
0

you can use the calc function but not is cross-browser

calc(100% - element size);

http://jsfiddle.net/8CQHP/

You can see the support in caniuse.com

Jose Vega
  • 27
  • 8
0

I ended up changing my code and using the idea from the solution Chad provided in the comment to his answer. I also used his absolute-positioned button trick. This is what I did:

I used a span for the search box and moved the button out of the search box straight into the nav:

<nav>
    ...

    <span>
        <input type="text" placeholder="Search...">
    </span>
    <button class="searchBtn" type="button"></button>
</nav>

Using this css:

span {
    display: block;         /*This is the trick from*/
    overflow: hidden;       /*the solution Chad provided*/
}

input {
    width: 100%;
    padding-right: 65px;    /*This is to make room*/
}                           /*for the button*/

button {
    position: absolute;
    right: 0px;
    top: 0px;
}

overflow: hidden on the span makes it all possible. Read about it here: http://colinaarts.com/articles/the-magic-of-overflow-hidden/#making-room-for-floats

jbb
  • 346
  • 3
  • 9