Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

CSS

fixed width button and a fluid form field to fill the rest of the parents width.

I am a little bit out of ideas how to accomplish. I have the following rough markup.

<div class="formwrap">
    <h2>Newsletter</h2>
   <form>
      <input></input>
      <button></button>
   </form>
</div>

form has text-align: centeras only property. input and button are inline-block elements so properly aligned horizontally. but problem if i define the width of the input and button larger than the width of the parent form then the two are aligened center after another vertically. if their cumulated width is smaller than the parent width i have margins left and right. but i wanted to fit them exactly into their parent container.

to work around with float to get each element stick to the left and right also doesnt help since the input is aligned to the middle while the button to the top line.

so is there a way to say the button element should have a fixed width and padding or margin to the left while the input element fills up the remaining width?

best regards ralf

4 Answers

If I understand correctly, you have a fluid width form and you want a fixed width button with an input field that takes up the rest of the space? I'll base my answer on this but I can update it if I've misunderstood.

I didn't see how text-align: center fits into this so I didn't use it.

Ideally we would like to do something like this: width: 100% - 120px. This would mean "take up the full width but then subtract 120 px to make room for a fixed width button of say, 100px" In this example if your button was 100px wide then it would give you 20px of space between them.

css has a calc() function that lets us do this.

input {
width: calc(100% - 120px);
}

Unfortunately, it only has about 75% browser support and is not ready for production use yet in my opinion. See here: http://caniuse.com/calc

I did a codepen demo for you to show you the calc() example and then a second one that you could use for the time being. To see the calc() example you'll have to make sure you're using a browser that supports it.

In the second example, I increased the right padding on the form so that the input could be set to 100% and it would extend all the way to the padding. Then I gave the button absolute positioning and placed it inside the padding. This should work in most, if not all, browsers.

http://codepen.io/anon/pen/IJjuz/

I think there must be some other ways to do this but that's all I could think up at the moment.

If you're going to do this, I would recommend that you set a min and max-width on the form. If you view the demo on a desktop browser you can see that the input is way too long

Raúl Barrera C.
Raúl Barrera C.
18,943 Points

When you use display: inline-block, appears a margin between the elements, I don't know exactly the value, around 4px. Then input+button width should be equal or less than form's width - 4px.

wow nice one. and you understand my goals exactly right. thank you! a few comments. text-align center is a rudiment of a smaller viewport i forgot to comment out. sorry. and yeah the calc property i am aware of but as you said i would be reluctant to use at the moment like you said ( the reason i never took it in consideration and even tried an solution with it - but nice application of it). and your second solution is working perfectly. was a bit of fiddling to get the right em value for my button length and whitespaces but works now. pretty nice. and yep this solution is only needed for a limited viewport width from 850 to 1074px. before and after the input and button are positioned otherwise. i needed this solution only for the width from 850 to 1074 to get the two elements align inline and let the input fill as much as space as necessary. perfect. thanks a lot again!

p.s. another solution i got suggested using an extra span. the only downside on this one is that it exchanges the position of button and input in the markup. otherwise this one is quite nice too: http://codepen.io/rpkoller/pen/IGsfe

You're welcome. Glad it helped.

Are you saying that you set the width of the button in em's and not px's? If so, it's not really a fixed width anymore but dependent on font-size. Did you also use em's for the padding-right value? If not, you have the potential for the button to overflow the padding which would cause it to overlap the input if the user increases their font size. If they're both set in em's then they will both get bigger, or smaller, together.

Using em's would be better than using pixels like I did in the demo.

Thanks for posting another solution. I know that some people don't like to use extra markup for styling purposes so that could be another downside. I think that every solution probably has pro's and con's until we're able to use the calc() function.

yep i know it isn't basically "fixed" anymore if you are using ems. But i basically i wanted the button just to remain in place - maybe not described in the best way. ;) and yep i've used em for the button as well as for the padding, i normally try to avoid px. but in combination it's exactly what i was looking for.

Yep, normally i don't have a problem with the extra markup, but the switching of places of button and input in this particular case was my show stopper for that method.

And yep you just need an appropriate stack of solutions to solve problems and then choose the right one. ;) and the calc method looks more than promising but i guess it will need a few more month or even years if it is save to use in most of the browsers.