Laying out input elements using display:table-cell - html

I'm trying to write a CSS class that allows me to sit form elements (mixed button and text inputs) in a line so that they abut. I'm using display:table on a parent, and wrapping each element in a container with display:table-cell, and it works fine except for one bug that I can't figure out a way around.
So for example, parent is control-group, the element wrappers are control-group-item, and the elements themselves are control-group-input.
.control-group
.control-group-item
.control-group-input{type: "text"}
.control-group-item
.control-group-input{type: "submit"}
CSS of this (I've normalized font size/line height/padding/browser weirdness and all form elements are inline-blocked etc.):
.control-group {
display: table;
.control-group-item {
display:table-cell;
}
gives this, which is OK:
However, I ideally need it to fill a grid column of undetermined size, rather than the browser deciding how big my elements should be. If apply width:100% on .control-group, this happens:
The orange is a background colour applied to the table cell control-group-item. The issue seems to be with the 'submit' input: the submit stays the size it should be but browsers universally add extra space next to it within the table cell. So if I apply width:100% to each .control-group-input, I get this:
Which is OK, but stretches the ‘submit’ button. I can live with that, but is there any way to get it like the second image (but without the random space) using my current approach, or should I sack that off & try something different?
Edit I do not know the sizes of the inputs in advance: I can't set a width on them, which effectively rules out most inline block/float methods. I ideally need IE 8/9 support, which is why display:table was tried.
Edit 2: here are versions on Codepen: http://codepen.io/DanielCouper/pen/knDmC
After rewriting the code there, I realise my question is: how is the width of the table cells being calculated? It's specifically the cell with the submit button that has the extra space. The extra space seems random.

Here's a working version in codepen: http://codepen.io/mkleene/pen/ldqDH
The summary is that you need to remove the width: 100% on the submit button and then give the second table cell element width: 100%. You also need to make the textbox take up its entire parent with a 100% width.
You also need to make sure that the table element is using an auto table layout.

nm, spoke too soon. Thought I had solved it, hadn't, was getting effects from some other CSS.

Related

Negative margin limit with images

See My Fiddle:
http://jsfiddle.net/5BEsZ/
I've discovered something very strange that I haven't seen documented anywhere else... Was wondering if you all had a solution.
You'll notice the negative margin hits a limit at around -212% for image elements. Is there a reason for this? Can you think of a work around?
Why I Need This (what I've tried):
I'm making a fluid layout and I want to display a rating system. I have a sprite sheet of stars (similar to the one in the fiddle) that I want to reuse at various sizes.
Because the size changes I can't use a background image. So I decided to use an image inside a container with a variable width and overflow:hidden. The sprite sheet adjusts to the width of the container and the container's viewable content is determined by a padding-top:20%. This is so it can be fluid with its width (since every star is a box, the total height is 20% the width).
Then I try and position the star image inside the container with margin-top. I tried using position:relative and a top:-X%, but because the container technically has no height this was causing issue on mobile phones (-100% of 0 is 0, etc).
So I assumed negative margin would work, but then discovered this strange issue!
NOTE: Because it affects only the last row I can make it work in my situation by using a padding-bottom instead of top (thereby bumping every star row up 1), but this isn't an adequate solution for me because it just ignores the problem. What if I wanted quarter stars?
I've updated your fiddle. img tags are "inline" elements by default, which impacts the way margin is calculated relative to the containing element. By forcing the image element to be rendered like a block (display: block), you're able to achieve the results you were expecting. A div element is a block by default.
As a side note, you'll want to avoid using inline styles (a different sort of "inline"!) wherever possible. Typically your styles would be included in a stylesheet instead of in a style attribute directly on the element. I included the fix (display: block) in the attribute to match the code style of your html.
I don't know why, but if you float the image the problem goes away.
<img src="http://www.whitepages.com/common/images/sprite_stars.gif?1343868502" id="stars" style="width:100%; float: left;" />
So, the answer to fix your problem: http://jsfiddle.net/5BEsZ/2/
If anyone could explain why this happens?

HTML forms that expand fill all the available space

I'm rendering a form in a table with the labels in tags (left) and text inputs in tags (right of labels).
For the sake of flexibility, I'd like to write as little css as possible and have everything magically fall into place, such that:
the cells expand to accomodate the width of the longest label
the fields on the right expand to fill the whole width of the cell
I've been trying various combinations of width:100% and width:auto on these various elements but to no avail. Is doing this possible, or should I just give up and specify hard widths like width:Npx?
Not sure what your code looks like (if you post, answers are so much better...).
Anyway: cells will expand naturally to the width of the longest element if no width is specified, BUT you can't have the element expand to the width of the cell at the same time! That would make the calculation of the width impossible. So I'd recommend fixing the inner content somehow. Input fields look great when they are all the same length...
You have two options as far as I'm concerned. Either you implement a solution with tables that allows you to have fluid lengths for your labels, or you set them as fixed widths and use table-less markup. I personally see no compelling reason to choose one solution over the other, although some web developers will do almost anything to avoid using <table> elements in their markup.
That being said, this solution is quite easy if you are using tables: http://jsfiddle.net/Wexcode/VcSXU/
td:first-child {
white-space: nowrap; /* don't allow text to wrap to the next line */
}

Liquid Pre inside Table Cell

Basically its a 2 column setup, with a dynamic width content column, and a static width menu column.
The content column is going to contain pre-tags (with code), and I need overflow:auto on the pre-tag inside the table to work.
So far I've had little luck. The nature of the pre tag forces a certain size on the table cell, which in turn refuses to be any smaller than the width of the pre tag.
Can anyone help out?
Ps. I've placed a second pre-tag on the page, which works as intended, but thats probably because it's not inside a table.
Add white-space: pre-wrap; to the element. max-width:100% may help too.
I found an acceptable solution.
The solution is a negative right margin for the pre (code) element.
Basically, a negative right margin will force the pre to shrink if it needs to.
I made margin-right -800px, and the width 97%.
I noticed that the width, paddings and borders need tweaking if to look good at all resolutions, but the solution works.
A simple solution that was hard to dream up.
[EDIT]
There was a link to an example, but it has been taken down.

How to make a html tag expand as much as possible to fit the parent width?

I want to make a textfield in my html page to expand as much as possible to fit the parent width. Here is an image shows what I want.
(source: ez2learn.com)
I try to use width: 100%, but the browser sets the width of elemnt as its parent's, which makes no room for other elements, they have to to be placed in second line. How can I let the element to expand as much as possible to fit all space in single line?
Thanks.
If you want to make the input ‘100% minus the widths of those other things’ you're into CSS layout stuff.
You could float: left the label, float: right a wrapper around the buttons, and set left and right margins on a wrapper around the input, then set the input to width: 100%.
(But personally, liquid-layout forms is one of the places I still typically resort to tables, as combining a series of fixed- and variable-width columns is something that easily stretches CSS layout beyond its limits.)
I agree with bobince. I would look into a table option. I would either decide on fixed:width that works for you within the table, or try to make the width:100% within the table.

How can I make a DIV behave like an IMG for use as a CSS sprite?

I have written code that automatically creates CSS sprites based on the IMG tags in a page and replaces them with DIV's with (what I thought was) appropriate CSS to position the sprite image as a background letting the appropriate part show through -- the problem is that I cannot get DIVs to behave as drop in replacements for IMGs.
If I leave the default 'display' value set to 'block' then if the original IMG was positioned at the end of some text, the replacement DIV will jump down to the next line after text (which of course is what I would expect something with display: block to do).
If I change the 'display' to inline, then the DIV stays on the same line as the text but it ignores the 'width' and 'height' I have set and collapses. I've tried putting 's inside the DIV but it then only takes up enough width to contain the nbsp.
I've tried experimenting with setting display to all possible values (including the "obscure" ones like 'table-row', 'run-in', 'compact', etc) but all with no luck. Is it even possible to create a DIV with the same layout behavior as an IMG?
I am open to having something more complicated than just a single DIV, however I've tried the obvious things there (one DIV inside another where the inner DIV is set to display: block with the outer set to display: inline) but I haven't found a combination there that works either.
There are always specific things I can do outside of the replaced IMG/DIV to get the layout I want, but my goal is to have a generic auto-CSS-sprite mechanism that works regardless of the rest of the HTML.
Did you try display: inline-block; ?
you may have to also use display: -moz-inline-block; for firefox2
Images have an equivalent of "display: inline-block". This was not originally included in CSS but was added in part to address the fact that images behave this way.
The issue is that all browsers are just now supporting it. If you want to support browsers from even a year ago, you are stuck.
Another, but not as great, solution is floating the div ("float: left").
inline-block : Introduced in CSS 2.1. This causes the element to generate a block element box that will be flowed with surrounding content as if it were an single inline box (behaving much like a replaced element [meaning an image] would.).
Source Mozilla Developer Center
Display: inline-block is supposed to work in this situation. Did you try it?