I need to layout a page, but I can't figure out how to do it without tables. I know it must be possible, but I can't think of a solution that isn't table-based that isn't incredibly rigid with fixed widths for everything.
Mockup: http://i.imgur.com/jSSDhIh.png
No matter what I do, it looks like I'm going to have commit a major sin. For example, the top set - it looks like I'm going to have either to:
Create a table (the root of all evil, apparently)
Hardcode widths and heights specifically for these elements. (either #id or style= or single-use classes, all three are also considered evil)
Is that the case? Is there a realistic way I can avoid those scenarios? Googling for answers just gets me a bunch of useless "TABLES ARE EVIL SO ARE CSS TABLES ALSO DON'T USE ID SELECTORS OR STYLE ATTRIBUTES EVERYTHING MUST BE A REUSABLE CLASS" with no actual useful information.
EDIT: I've already done this with CSS tables (display: table) and had it thrown back as unacceptable. I think it's fine because it works and it still looks good, but it's not my call.
Tables aren't evil. This stackexchange page alone has many tables on it. Some people want to use divs to create rows and spans using a grid. I suggest using tables where they seem appropriate. If you're really bent on avoiding it, consider grabbing something like bootstrap for twitter.
http://twitter.github.com/bootstrap/scaffolding.html#gridSystem
There you can use their scaffolding to arrange items the way you want without tables.
heres a link on HTML Tables – when and how to use tables in HTML
this might help you understand when to use tables.
on your mock theres no reason not to use tables. like wordpress backend uses tables for forms but in tabular form.
but if you really want to layout this on divs i rather suggest using css grid frameworks.
I personally use zurb foundation. heres the link
I'd recommend using Bootstrap, it gives you plenty of options for styling forms. (However it may interfere with the rest of your CSS.)
Here's how a two column form would work:
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<div class="row">
<!-- right column -->
<div class="span6">
<label>Subject <input type="text"></label>
<label>Category <select></select></label>
<label><input type="radio"> Permanent Change</label>
<label><input type="radio"> Temporary Change</label>
</div>
<!-- right column -->
<div class="span6">
<label>Requested Approval Date <input type="text"></label>
Effective Dates <input type="text"> to <input type="text">
</div>
</div>
Obviously the styling leaves a lot to be desired, but check out http://twitter.github.com/bootstrap/base-css.html#forms to see how much you can do. You'll want to look into <form class="form-horizontal">. Be forewarned that the CSS is picky, you'll need a lot of <div class="control-group">'s.
Related
Context:
We have some cards that are radio buttons in a radio group, that we want to display in a different order for small and large breakpoints. I want to know if there is a way to do this nicely that doesn't involve duplicating the html for the different breakpoints, and doesn't break accessibility.
Desired large breakpoint:
|Large|Medium|Small|
Desired small breakpoint:
|Small|
|Medium|
|Large|
Desired accessibility behaviour:
With a radio group, you'd normally expect to hit tab to get to the first option in the radio group, and then use the arrow keys to select different options.
What I've tried:
I've tried using display:flex and changing flex-direction to either row or column-reverse depending on the breakpoint. And then because flex is visual only, I have also put tabindex onto the radio inputs. Although it fixes the tab behaviour, the arrow keys are the reverse of what you'd expect.
Super cut down example:
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<p>Standard view:</p>
<div style="display:flex;">
<div>
<input type="radio" id="featured" name="tier2" value="featured" tabindex="1">
<label for="featured">Featured</label><br>
</div>
<div>
<input type="radio" id="standard" name="tier2" value="standard" tabindex="2">
<label for="standard">Standard</label><br>
</div>
<div>
<input type="radio" id="basic" name="tier2" value="basic" tabindex="3">
<label for="basic">Basic</label>
</div>
</div>
<p>Mobile view:</p>
<div style="display:flex; flex-direction:column-reverse">
<div>
<input type="radio" id="featured" name="tier" value="featured" tabindex="3">
<label for="featured">Featured</label><br>
</div>
<div>
<input type="radio" id="standard" name="tier" value="standard" tabindex="2">
<label for="standard">Standard</label><br>
</div>
<div>
<input type="radio" id="basic" name="tier" value="basic" tabindex="1">
<label for="basic">Basic</label>
</div>
</div>
</body>
</html>
Questions:
Is there another attribute like tabindex that you can use to define the order the arrow keys work?
Is there any other way of doing this that doesn't involve duplicating html?
Thanks!
Short Answer
Don't use tabindex, flex etc.
Instead serve the mobile version of the HTML and reorder the DOM order of your component using JavaScript on page load for larger screens.
Longer Answer
Is there another attribute like tabindex that you can use to define the order the arrow keys work?
No, sadly there isn't.
Also using tabindex is a terrible idea as you will break logical tab order for the rest of your application. Avoid it at (nearly) all costs!
Is there any other way of doing this that doesn't involve duplicating html?
There is no clean way to do it without duplicating the HTML (that will work with all screen reader and browser combinations).
You do have a few options though
Reorder the HTML on the server - You could load the component via AJAX after querying the screen width. Decide which version to send based on the screen size (send the screen size to the server with the AJAX request).
Reorder the HTML on page load - I would start with your mobile layout as the base HTML (to minimise JS work on mobiles as they are less powerful). Then if the screen size is over your break point rearrange the items using JS on page load for larger screens.
The key to both is that DOM order is correct. It will save you a lot of headaches if you can somehow get your DOM order as you want it rather than trying to change it with CSS, tabindex etc.
Both options do the same thing but both have pros and cons:-
Option 1 - Reorder the HTML on the server
Pro - the page will load faster and lazy loading the item in has performance benefits.
Pro - your HTML is clean and exactly what is required, it even gives the option for different lists entirely if you desire.
Pro - probably easier to maintain as you just have a raw HTML file to edit on the server (albeit 2 files, one for each view) and don't need to do mental gymnastics to work out reordering if the list grows longer.
Con - when you JavaScript fails the item will not load in at all
Con - an extra network call may actually end up slower, you would have to test. Yes this conflicts with the first "Pro" so you would have to test it!
Option 2 - Reorder the HTML on page load
Pro - By going mobile first it will not add anything other than maybe a KB of JavaScript to the page needed to reorder on desktop.
Pro - when your JavaScript fails the item will still render, it just might not be in the order you desire.
Con - As your list grows it may be harder to maintain the reordering.
Con - Despite the earlier "Pro" about JavaScript size, it is also a "con", you are still sending extra info down the wire and have to do a screen size check. Minor points but if performance is important something to consider.
What would I do?
If I had to do this I would probably go for option 2.
The main reason being that the tiny amount of JS is nothing compared to a full AJAX call and performance is key.
This is assuming the form is not "above the fold", in which case I would go for option 1 to avoid Cumulative Layout Shift, as that would annoy users seeing the list reorder while the page loads.
I am struggling with how to write the correct CSS for positioning some data entry forms. I'm not sure what the "proper" way to do it is.
An example of what I am trying to create a layout for:
Last Name Middle Initial First Name DOB
||||||||||||| |||||| |||||||||||||||| ||||||||||
City State Zip
|||||||| |||| |||||||||
Basically I have my labels and the ||| are representing my form elements (text boxes, dropdowns etc). I don't know the proper way to create classes for these elements without just creating one time use classes that specify a specific width that is only for these elements.
Also, how do I get all of these elements aligned properly and multiple items per line? Do I need to float each element?
Would I do something like:
<div class="last-name">
<div class="label">
<label>Last Name</label>
</div>
<div class="field">
<input type="text" />
</div>
</div>
<div class="middle-initial">
<div class="label">
<label>Middle INitial</label>
</div>
<div class="field">
<input type="text" />
</div>
</div>
...
<div class="clear"></div>
last-name and middle-initial etc would all be classes that would be used once and floated to the left. I'm not sure if this is a good way to go about it or not? Is there a better way to do this kind of positioning with CSS so I can avoid using tables?
I would choose to mark up this particular layout using fieldsets:
<form>
<fieldset class="personal">
<label>
<span>Last Name</span>
<input type="text" ... />
</label>
<label>
<span>Middle Initial</span>
<input type="text" ... />
</label>
...
</fieldset>
<fieldset class="address">
<label>
<span>City</span>
<input type="text" ... />
</label>
</fieldset>
</form>
I'd float all the labels, make the spans or inputs use display:block, and most everything should fall into place.
IMO, this is tabular data.
I don't think it's necessarily a shame to use a <table> for this.
Related discussion: Proper definition for "tabular data" in HTML
It's not a bad thing to use table layout when the data you're laying out is a table! That's what you have here, imo: a table. So save yourself some grief and treat it that way. We've been so beat up by CSS purists and semantic-web lunatics that I suggest the pendulum has swung too far: now we tie ourselves in knots over-CSSifying our layouts. Or at least I do. I spend way too much time trying to avoid table layout.
The outcome is that a lot of my pages have to do browser checking. And the extra time (hey! the 80-20 rule again!) to deal with browser quirks is way more than it should be. I'd have saved a lot of time, and had more robust pages, if I'd just thought a little bit instead of going for the never-any-tables, always-pure-CSS solution every time. Table handling is solid like a rock in every browser with no problems and no frustrations.
Just my experience.
Here is my version without tables: http://jsfiddle.net/dy4bv/5/ (increase a little HTML part to fit all fields)
Maybe it will be helpful.
You could always use display:table and display:table-cell.
So using your example code above, you would do something like this
div.last-name, div.middle-initial{
display:table-cell;
padding:1em;
}
Example: http://jsfiddle.net/5LBgp/
EDIT
A bit more context to add to the answers from #Pekka and #Pete Wilson:
I foresee two big problems with styling this as a table
if you ever want to change the styling, you will need to hack away at the HTML, probably even redo it completely. Your code will be more future friendly if you use divs.
screen readers and such will likely make a mess of it, not understanding that the table is not really a table.
I am not a web developer, but i've had a crack.
http://jsfiddle.net/dy4bv/28/
This is based on #Samich's design, but instead of using a pile of divs with magic clearing divs interspersed, i've split the rows up into items in a ul. I use labels for the warm fuzzy semantic feeling. The styling is done by making the label-and-field divs inline-block, so they flow from left to right, but the labels and fields themselves block, so they stack vertically (this is a very crude idea, i know). As #zzzzBov pointed out, you can then use the field IDs to hang widths off.
No, that is not tabular data. Here's a test if you're ever wondering if something is tabular data: What are the table headers?
As for the layout, whenever I get something that I have trouble laying out, I back up and ask if the design is the problem and in this case I think the answer to that question is: yes.
Is that a user friendly design? no. It's difficult to scan and will be slow for users to identify errors if there are submit errors.
Luke Wroblewski has some great information on his blog and in his book Web Form Design: Filling in the Blanks about how to design human friendly forms.
Just to unload these 2 pennies...
The first column is "PropertyDescription" and the second column is "PropertyValue", while each row is a "Property" items -- voilà, a table!
Still prefer CSS, but this can certainly be classified as tabular data.
I have always struggled designing css forms, I can never get the input and label side by side. Do you have any words of wisdom that may help me.
I usually use a 10px margin on the bottom but cannot get them aligned
My Common form:
Name:
Email:
Phone:
Message:
text area
I know I'm going to get backlash for this from people who think that the only possible way to do things is with pure CSS, divs, spans, etc. However, your form is tabular. You have a column of titles, and a column of input fields. In this case, because of the tabular layout, a valid solution could be tables.....GASP!
Tables are not valid for page layout...let me repeat that again, tables are not valid for layout. However, you've got an element of a page, you're not doing a full page layout. You can easily use <th> elements to style the labels for the inputs, which is quick and simple. Overall, the table (tabular) solution would be less verbose than many of the CSS layouts given, which from a pure HTML standpoint is a win. It will continue to work and layout properly even when the server gets backed up and can't load the external CSS document. To all those who believe that tables are never ok, let me remind you that this solution will validate with W3 100% of the time provided your table is properly structured. And it's far more cross browser compatible, with no box-model issues in the "crabby" legacy browers. Certainly continue to progressively enhance with CSS as is best practice.
Theory and practice, especially in the web world, are two entirely different things. In theory, all of us should be producing 100% HTML5/CSS3/Semantic/SEO Optimized...blah blah blah. In practice, theory only goes as far as the first customer complaint. Progressive enhancement is key to survival. When a webform breaks in a big corporate setting, money is lost and people get fired. For that reason, the International Bank I recently did work for had requirements that demanded all its webforms were tabular (assembled with tables) It's hard to argue with a portfolio of sites whose users generate the company hundreds of millions of $$$ annually.
<style>
ul.anyclassname{
padding:0;
}
ul.anyclassname li{
list-style-type:none;
clear:left;
}
ul.anyclassname li label{
width:300px;
float:left;
}
.inputs{
float:left;
}
</style>
<form>
<ul class="anyclassname">
<li>
<label>Name:</label>
<div div class="inputs"><input type="text"></div>
</li>
<li>
<label>Email:</label>
<div div class="inputs"><input type="text"></div>
</li>
<li>
<label>Phone:</label>
<div div class="inputs"><input type="text"></div>
</li>
</ul>
</form>
I usually do this:
<div>
<label for="txtname">Name:</label>
<input type="text" id="txtname" name="txtname"/>
</div>
<div>
<label for="txtEmail">Email:</label>
<input type="text" id="txtEmail" name="txtEmail"/>
</div>
<div>
<label for="txtPhone">Phone:</label>
<input type="text" id="txtPhone" name="txtPhone"/>
</div>
etc...
Then with my CSS:
label { width: 100px; display: inline-block; }
Something along those lines. Nothing fancy, but they are side-by-side and with the surrounding div you get a block level element to give you a line return after each pair.
I wrote a complete form in this answer: how can we make forms like this with css & html? . It has the html markups and the css classes you need to start.
The code is also in a fiddle here: http://jsfiddle.net/vSqR3/64/ (Now with the nice addition of the for attribute, thanks Kyle!)
You will find in that link not only how to put one markup next to the other, but how to set sizes and borders for each.
I strongly suggest you to play on the jsfiddle.net website. You'll be able to modify and test immediately all your changes.
One part of web development (from a front-end perspective) is laying out forms. There is never a standard set, and I've seen people continuing to use <tables> to keep styling consistent. Say you were to lay out this form:
At first glance it seems that a table would make laying out this form easy. Another options is to use <fieldset>'s, with perhaps a list inside them. Float the fieldsets to the left, give them equal widths.
My question is what is the most standard way of laying out forms? There seem to be several techniques, but many of them don't work cross browser.
How would you do it? And why?
I must say, the most common way to do this would be to use tables. Unfortunately, there are problems with table based form layouts (big surprise). One big thing is that tables will bleed over their containers (if overflow is not hidden) and they don't squash their contents like CSS can do. On top of that, rendering tables is more expensive (takes up more CPU cycles). Overall, I think that, compared to pure CSS solutions, table based form layouts are rigid and inflexible, and as a designer, I cringe (and you should, too!) at using tables for layout purposes to begin with.
A method that I am beginning to like (and that is growing more popular) is a pure, CSS2 method for laying out forms. I will not credit myself for coming up with the idea, but it is really straight forward. All you have to do is this:
THE HTML:
<form action="process.php" method="post">
<label for="username">Username:</label>
<input type="text" name="username" id="username" />
<br />
<label for="password">Password:</label>
<input type="password" name="password" id="password" />
</form>
THE CSS:
label, input {
width:200px;
display:block;
float:left;
margin-bottom:10px;
}
label {
width:125px;
text-align:right;
padding-right:10px;
margin-top:2px;
}
br {
clear:left;
}
As you can see, the CSS code is really minimal and the results are really awesome. The pros of this method is that it uses less code (faster to download), it is cleaner without all the messy table tags littering your HTML document (maintainability), and I believe web browsers will render the CSS method faster.
Update 1: I also found a CSS method using unordered lists.
Update 2: #musicinmyhead reminded me about using fieldset and legend tags in CSS form layouts. I coded us a quick and dirty little demo here.
Note: I originally learned of this pure CSS form layout from: http://www.cssdrive.com/index.php/examples/exampleitem/tableless_forms/
Research shows that labels above fields and fields all in one column are the easiest to fill out. Lukew has a lot of form's data/research/info:
http://www.lukew.com/ff/entry.asp?504
As a bonus, that's usually the easiest way to build the presentation layer as well. Plus, it's usually much more mobile-friendly out-of-the-box.
All that said, tables can be valid. In many ways, a form is a partially filled out spreadsheet (if you want to think in terms of tabular data).
I typically wrap the LABEL/FIELD pair in a div and position the label and field as needed depending on the layout desired.
The practice of using tables as layout made sense prior to CSS, but tables are actually intended to present data and nothing else. The simplest way to layout a form is label above field in a single column, but it is possible to create the same grid-like layout that tables provide using the <div> element and some CSS.
For that, the CSS might look like this:
.layout-grid{
display: table;
}
.layout-row{
display: table-row;
}
.layout-cell{
display: table-cell;
}
and the HTML might look like this:
<form action="foo.php" method="post">
<div class="layout-grid">
<div class="layout-row">
<div class="layout-cell">
<label for="foo">Foo:</label>
</div>
<div class="layout-cell">
<input id="foo" name="foo" />
</div>
</div>
<div class="layout-row">
<div class="layout-cell">
<label for="foo">Foo:</label>
</div>
<div class="layout-cell">
<input id="foo" name="foo" />
</div>
</div>
<div class="layout-row">
<div class="layout-cell">
</div>
<div class="layout-cell">
<button type="submit">Go!</button>
</div>
</div>
</div>
</form>
Personally? A table. At work? CSS. I go with whatever is required. There's the whole debate about the fact that a form is not in and of itself tabular data (like that of a form), which is true, and there is CSS that can create a cell-like structure.
If you're short on time and comfortable with only tables? Tables. Next up is the CSS/cell structure, but most will (probably rightly) say CSS all the way. It's not too difficult, and if you want to mix and match the whole thing, say adding an extra, fourth question at the bottom at the first three, it will make the change just a tad quicker. Not much, but a tad.
I have been looking at a couple html/css form frameworks like Uni-Form and Formy. They provide easier management of html forms. I was wondering if anyone knows similar ones. I am not looking for css grid frameworks nor Yahoo's YUI.
blueprintCSS has a form plugin (I don't know if it can be used alone, I haven't tried to do that). http://www.blueprintcss.org/
http://www.blueprintcss.org/tests/parts/forms.html
Baseline CSS also has a form system. I haven't personally used it.
just tried formy and uniform..
i want something styled a bit simpler, just to look clean so i can do the rest..
Formalize is another one, quite simple, worth a look.. looked at uniform and jformer and they're both too comprehensive, if that could be used as a reason to ignore them
Formalize
Uniform (different from Uni-Form)
There is also Tacit.
It's a "class-less" CSS framework were you only need a single <link> statement in your HTML and the web page will have a complete look. In particular, for forms, you get a more finished appearance out of the box, just by including the CSS file, and you don't need to attribute specific classes to your form elements. It also guarantees your form will work visually fine both in Desktop and in Mobile.
You can get an overall idea from the demo page.
Here are also a few examples of pages that use Tacit, and the only work put into was including the CSS file: http://filfreire.com/, http://www.jare.io/, https://socatar.com/,
I think uniform is the best solution for forms.
Html is good and understandable, it has a bunch of tricky form examples solved very nicely ad it pays attention to usability much more than other frameworks.
Other seem to insist more on a vertical typographic rythm than common sense and usability. :)
There is also: Formy http://code.google.com/p/formy-css-framework/
I have developer a single class CSS framework just for forms. The class "form" can be added to any form input to style it properly. You can see the examples on the documentation: https://form.js.org
Here an example of mailing list form:
form {
margin: 1rem;
}
<link href="https://cdn.jsdelivr.net/npm/#codolog/form#1.0.0/dist/form.min.css" rel="stylesheet"/>
<form>
<div>
<div>
<input type="email" class="form" placeholder="Enter your email">
</div>
<div>
<button type="button" class="form full">Subscribe</button>
</div>
</div>
<form>