dhblah
dhblah

Reputation: 10151

Cannot vertically align float element and surrounding elements

I have a couple of problems regarding floating element alignment, I'm trying to make table cell that has a couple of elements inside. Like text input and then dropdown, and only text input should be resized when user resize browser window. Here, how I do it:

<table style="width: 100%;">
    <tr style="vertical-align: bottom;">
        <td style="white-space: nowrap; width: 20%;">
            <div><span style="float: right; display: block;">
                <select style="display:show;width:60px">
                    <option selected="" value="1">1</option>
                    <option value="2">2</option>
                </select>
                </span> <span style="display: block; overflow: hidden; padding-right: 2px;">
                <input type="text" value="100.0" style="width:100%; text-align:right"/>
            </span></div>
        </td>
    </tr>
</table>

but floating element appears a bit upper that non-floating. enter image description here

Also I have another case when I have link, then input text field, then dropdown or another link, again, input field should be the only resizible element.

here is the code

<table style="width: 100%;">
    <tr style="vertical-align: bottom;">
        <td style="white-space:nowrap; width: 30%;">
          <span style="display: block; float: left; padding-top: 3px;">
            <a href="return false;"><img width="14" height="14" src=""/>
            </a>&nbsp;
          </span>
          <span style="float: right; display: block; padding-top: 5px;">
        <a href="return false;">&nbsp;?</a>
          </span>
          <span style="display: block; overflow: hidden; padding-right: 2px;">
        <input value=""style="width: 100%;">
          </span>
         </td>
    </tr>
</table>

what in this case, is that non-floating element is upper that the others:

enter image description here

Basically, I need to somehow vertically align floating element in the first sample, so it bottom will be the same as bottom of non-floating element and in the second sample i need to somehow align bottom of non-floating element, so it'll be the same as floating elements.

I'm trying to make it work in ie 7, 8, 9, 10.

Adding paddings will do the trick, but then it'll look ugly in firefox, chrome.

Edit:

Or at least tell me why this can't be done.

Edit2:

Or if the problem is with table tag? So I need use something different (divs). The whole structure is a table with only difference that there are some selects and such a like in cells, so it's very natural to use table here. But, well, if problem is with table, I'll try to recreate it with divs.

Edit3:

Even if I remove table, right floating element in sample 1 is a bit higher. I tried to replace float with padding and absolute positioning, but still it's higher.

Edit4:

For sample 1, if I set display: none for left element, then floating element vertical position becomes normal.

*** UPDATE: Sorry that was my mistake to put bounty on this question, i've already solved my problem.***

Upvotes: 3

Views: 3075

Answers (6)

Sandro Paganotti
Sandro Paganotti

Reputation: 2313

I've tried a different approach, supposing you can set a fixed with for the other elements that doesn't need to resize you can take advantage of calc() and avoid using float and table.

Here's the demo: http://jsfiddle.net/RcSfF/

HTML

<input/><select><option>a</option></select>

CSS

input,select{
    box-sizing: border-box;
}
input{ 
    width: calc(100% - 60px);
}
select{
    width: 60px;
}

You'll need a polyfill to emulate calc on old browsers.

Upvotes: 1

user2249123
user2249123

Reputation:

I dont get the need for aligning all the elements at the bottom, but since its been provided in CSS and you need it so what the heck.

I dont see anything wrong in your approach to use table instead of div. As a matter of fact It would help you to keep the width of the other elements fixed as your input box grows or shrinks in size.

I would suggest you to have more than one td tag, put your element in separate td tags and put the width on the table or tr instead of the td tag.Instead of using too many span elements to add inline-css(its not old school), add it to the td tag or your element tag. If its getting to tough to comprehend here is the jsfiddle

<table style="width: 100%;">
<tr style="width:20%;">
    <td style="white-space: nowrap;">
        <span style="display: block; overflow: hidden; padding-right: 2px;">
            <input type="text" value="100.0" style="width:100%;text-align:right"/>
        </span>
    </td>
    <td style="white-space: nowrap;width:60px;">
        <select style="width:60px">
            <option selected="" value="1">1</option>
            <option value="2">2</option>
        </select>
    </td>
</tr>
</table>


<hr>

<table style="width: 100%;">
<tr style="width: 30%;">
    <td style="white-space:nowrap;width:16px;height:auto; ">
        <a href="return false;"><img width="14" height="14" src=""/>
        </a>
    </td>
    <td>
      <input type="text" value="" style="width: 98%;margin:2px;">
    </td>
    <td style="width:14px;">
     <a href="return false;">&nbsp;?</a>
    </td>
</tr>
</table>

In the css section by un-commenting the border section, you would see how your elements stack up with each other in the table in each respective row.
Also by un-commenting the vertical-align property and changing it to the middle, you would see a much better layout though I am not sure if your particular case needs it the way you ask for.

Upvotes: 1

Wallace Sidhr&#233;e
Wallace Sidhr&#233;e

Reputation: 11597

I'm really not getting what you're trying to achieve with your markup/css, but maybe that's because you're using table + floating + vertically aligning something. Anyways, I cleaned the first problem up, thought of posting the code here:

<style type="text/css">
.container { vertical-align: bottom; }
.content { white-space: nowrap; width: 20%; }
.col1 { float: right; display: block; }
.col1 select { display: block; width: 60px }
.col2 { display: block; overflow: hidden; padding-right: 2px; }
.col2 input { width: 100%; text-align: right }
</style>

<div class="container">
    <div class="content">
        <div class="col1">
            <select>
                <option selected="" value="1">1</option>
                <option value="2">2</option>
            </select>
        </div>
        <div class="col2">
            <input type="text" value="100.0"/>
        </div>
    </div>
</div>

See it at work here: http://jsfiddle.net/dreamyguy/MKQ75/

Note that display: show is not valid CSS, so I changed it to display: block.

Another thing to be aware of, is that floated elements are as slippery as absolutely positioned elements. They fall out of the normal flow of the document and therefore should be handled with care. Don't float an element unless you must, and if you do, make changes to the styles of the parent & siblings - so that you get the results you'd expect.

Upvotes: 1

yunzen
yunzen

Reputation: 33439

You cannot use float and vertical-align parallel. floated elements are always vertical-align: top.

If you use display: inline-block instead, you can (With hack of *zoom: 1, *display:inline; for IE lt 9).

Unfortunanately with this method the whitespaces in the HTML code will show in the result. There are two workarounds for this.

  1. If you have full source control, remove the whitespace in your code
  2. Give the surrounding block a font-size of 0

See here some demonstration code: http://jsfiddle.net/HerrSerker/3yMcS/

Upvotes: 1

dhblah
dhblah

Reputation: 10151

At least I found solution for case 1. Misplaced floating element can be fixed by replacing float with position: absolute; right: 0; bottom: 0; bottom: 0 is important part. Not to forget, that padding right should be added to the input on the left and outer element position should be changed to relative.

Upvotes: 1

What have you tried
What have you tried

Reputation: 11138

Working example: http://jsfiddle.net/qARBL/1/

Before anything - Please, please, PLEASE, don't use inline styling - this is so old school! Use an external CSS stylesheet instead.

Add the following css to your HTML:

1.

<select style="display:show;width: 60px;margin: 0;">
    <option selected="" value="1">1</option>
    <option value="2">2</option>
</select>

2.

<input type="text" value="100.0" style="width:100%; text-align:right;margin: 0;padding: 0;">

Just adjusting the margin and the padding of the two elements above did the trick.

Upvotes: 5

Related Questions