I am trying to create an input mechanism using the flex box model. I know it's not supported by all browsers, but that doesn't matter in this case. It really only needs to work on web-kit browsers.
I am trying to build a nice two column layout without needing to use specific widths. I have the flex property set to one on both the label and the input. However, as you can see, when the label element gets long, it messes up the width of the input that is next to it.
I want both label and input to be the same width down the column, but I want them to grow and shrink as the size of the window/device changes.
Is there a way to do this without having to set a width on either of the elements?
Update
I can set a max-width on the label elements to 5% and I basically get the desired effect. However, I'm still wondering if there is a way to do this without setting any width and using purely the flex box?
Here is a working jsFiddle.
The example you provided doesn't have columns at all, just the appearance that there are columns. Without actual columns you will have to set widths to make these 3 unreleated blocks look they are joined in some way.
You should be using the new CSS3 Flexible Box syntax, which is now 'flex' rather than 'box'. See the spec: http://www.w3.org/TR/css3-flexbox/ With this you can set the elements to have a <grow> <shrink> <default width> of 1 1 50%, so they will grow and shrink at the same rate and will each take up 50% of available width (you can adjust this or make it 60/40 or whatever).
Example JSFiddle: http://jsfiddle.net/XTa98/4/
Otherwise, if you want actual columns so that you don't have to set widths, you need to wrap all of the labels in their own "column" div and all of the inputs in their own "column" div.
JSFiddle: http://jsfiddle.net/XTa98/5/
This has actual columns and no widths set, but it does not degrade gracefully anymore since the elements are not in their own rows. To alleviate this you could always provide text-overflow: ellipses to truncate the text.
In any case, you have a trade-off. If you want the appearance of columns without actually using columns, you will need to set some type of width. Otherwise, you can use real columns but the elements are no longer joined as rows and you will need to account for the overflow when shrinking the browser width.
You don't have to wrap the elements in column divs to avoid setting widths. Just set each label and input to flex:1, and you'll get them dividing up the width equally. However, this is effectively just the same as setting each to be 50% wide, in this case, so I'm not sure what advantage it really has.
Related
Demo
I'm trying to make a table that contains a horizontal scrollbar where the width of any individual row can be set to whatever I want. I've tried two different approaches to achieve this and they each give me problems:
If I assign a width to my table that is larger than its containing div and apply overflow-x: scroll, the table exceeds the width of its container. However, I have no control over the width of my cells. Setting td{width:'x'px;} doesn't do anything.
If instead I apply table-layout:fixed to the table, I can now adjust the width of individual rows but cannot exceed the width of the table container.
How do I get the best of both worlds? I need the table to exceed the width of the container in order to get the scrollbar, while also being able to set the width of different rows to any value.
HTML table and table cells work this way by design - cells will always be confined to within the width of the table. If you want to size them like you do to normal inline-block elements, you can either:
Use <div class="table"> and <div class="cell"> to markup and style tables.
OR
Change the display mode in CSS. {display: block} for tables, {display: inline-block} for cells. You'd probably also need to fiddle with the display modes of other elements like <tr>, <th>, <thead>, <tbody>...
A little note: just in case you are using tables as a means to layout your page content, please stop and strongly reconsider changing your approach. Tables are a nasty crutch for layout, and should really ONLY be used to display actual tabular data.
Set the position: absolute; for the element that you want to exceed it's container width. But also set position: relative; to its parent, so you can adjust the position.
I have a bunch of data input screens and they all use a basic table filled with asp.net textboxes. Some of the textboxes (the smallest ones) are set to 250px in width. The others have been set a width in px depending on what makes them align best at 100% zoom.
The issue is when you zoom in and out, it's clear that the boxes don't really line up on the far right.
Can anyone suggest a way to properly align these last columns. It's worth noting that for some reason when using 100% in the last column that it busts outside of the actual table a certain way for unknown reasons.
The columns with the larger textboxes are defined using colspan of 2 or 3.
The boxes at 100%
The boxes at 75%
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 */
}
I have 4 elements inside a container element. The container element will have its height set to 100% of the browser window. The 4 inner elements will appear vertically stacked on each other (as normal). The first two elements and the last element should have a "natural" height (ie: enough to fit their contents). The 3rd element should expand to fill the space available in the container, after the other 3 eat all they need to.
So, it would look something like this:
I cannot set explicit heights for Element-1, Element-2, or Element-4, nor do I know the height of the Container. I don't know the natural height of Element-3 either; I plan on using overflow-scroll if it gets larger then what's available. I've added spacing between the elements for illustration, but there will be spacing (margins/padding) between the real elements too.
How do you achieve this using HTML/CSS? If compromises have to be made to get a decent layout, I'll consider them. Bonus points if the technique also applies horizontally (which I've needed on occasion).
First off, great visual.
Secondly.. would a javascript solution be out of the question?
Update
This was just intended to be a sample, but I have updated the code to appease some of the more picky people out there.
http://jsfiddle.net/tsZAV/9/
There are a number of things that make this impossible in pure css.
The browser window could be shorter than the dynamic height of the first 3 elements.
There is no way to force an element to take up the rest of the container's height.
CSS is a document styling language, not a programming language. Think of writing CSS as a set of guidelines that the page should try to follow, rather than a way of explicitly setting sizes (although you can explicitly set sizes).
This is relatively simple to do with JavaScript resizing the fourth element. You'll have to listen for a resize event so that the fourth element gets sized accordingly. Also, you'll want to set a min-height value for element-4, in case there isn't enough space for the fourth element.
How can you enforce the minimum width for a TD that can optionally contain an image? I ask this because I'm using a Javascript chess widget but when there are no pieces in any of the squares of a particular column, regardless of the width style of the td's being set to 36px, this column renders much narrower than those that have at least one row that contains the image of a chess piece.
Note that all the style is being set directly on each td cell. I read somewhere that a possible solution would be to instead create a div inside the td and set the width on that. Am hoping to avoid that as it might require significant modification to the underlying Javascript library. I've tried specifying !important along with the width but it had no effect.
Using firebug I can modify the width attribute but it seems the numbers are incorrect. For instance I can decrease the width all the way to 0 and it still appears the same. Or I can set the width to more than 36 and it appears to grow by width-36, but if for instance I set both the height and width of one of these narrow cells to the same number, lets say 60px, the height of what gets displayed is greater than the width and it appears as a rectangle not a square.
Furthermore not only can the td optionally contain an image, but each square specifies a background image too. So I am at a loss :( Thanks in advance
When I alter the CSS in your file using Firebug or the JS inspector in Chrome, setting the min-width property instead of the width property does the trick. Might want to try that? Not sure how IE will like that, though.
BTW: Why not use classes to do the CSS? It's kinda horrible to debug, this way.
By default tables will auto-size their columns.
If you set the table style to include:
table-layout: fixed;
then you'll have much better control of it via css and attributes.
You can use the td tags width attribute or you could use css and set the width.