USWDS - How to align form labels to the left of inputs? - css

I'm using the
U.S. Web Design System (USWDS)
in a project I'm working on, and I'm struggling with something that seems superficially like it should be quite simple: How can I align form labels so they appear to the left of their corresponding inputs, instead of above them?
Some other CSS libraries call this a horizontal form but I've also seen it referred to as "inline" fields.
According to this answer it's possible to achieve the result I want using modern CSS Grid layout, but so far I haven't figured out how to make that play nicely with the USWDS styling, which does not use CSS Grid.
Can anyone help me to either:
Create a horizontal form using some combination of USWDS components and utility classes, or if that's impractical...
Produce a horizontal form by overriding the USWDS styling with custom CSS, but without causing too much conflict or breaking with the standard?
Below is a simplified snippet of my HTML:
<link href="https://cdn.jsdelivr.net/npm/uswds#2.8.0/dist/css/uswds.min.css" rel="stylesheet" />
<form class="usa-form">
<div class="usa-form-group">
<label class="usa-label" for="somefield1">Sample label</label>
<input class="usa-input" type="number" name="somefield1" value=0 />
</div>
<div class="usa-form-group">
<label class="usa-label" for="somefield2">Another label</label>
<input class="usa-input" type="number" name="somefield2" value=0 />
</div>
</form>

You can use flex on the usa-form-group to get them positioned next to each other as shown in this Code Sandbox, with some other minor touchups to the element margins https://codesandbox.io/s/nostalgic-moon-q7i7f?file=/styles.css

Related

Is it considered bad practice to put a '.col-*-*' class directly on an element in Bootstrap 3?

I'm working in a codebase that is using Bootstrap 3. According to their documentation this is how you create a basic grid structure:
<div class="row">
<div class="col-md-8">.col-md-8</div>
<div class="col-md-4">.col-md-4</div>
</div>
The code base I'm currently working in applies the grid structure in the following way.
<div class="form-group">
<label class="control-label col-sm-4"> Name<span class="text-danger">*</span> </label>
<div class="col-sm-8">
<input type="text" class="col-xs-10" value="Default" name="panel:expandedContentContainer" id="id9428">
</div>
</div>
I've never seen the grid applied in this way and I just want to make sure this won't cause problems down the road. I have two questions. Is it okay to use '.col-- without a row? And is it okay to put '.col--' directly on elements?
In Bootstrap 3, the .row class will apply a negative margin of ($grid-gutter-width / 2) to both the left and right.
The .col-* classes will apply a padding of ($grid-gutter-width / 2) to both the left and right.
Adding the .col-* class to the sub elements will not necessarily cause you problems, but unless you override the padding on .col-* through your own CSS you will find elements will be indented more that you were perhaps hoping for.
Yes, you can use '.col--' without a row. Then it just isn't vertical align. more information about that: http://www.helloerik.com/the-subtle-magic-behind-why-the-bootstrap-3-grid-works
And yes it is okay to put 'col--' directly on element. I don't have any bad experience with that.

Create a form using Bootstrap 4 that looks like the forms in Bootstrap 3

I would like to create a form using BootStrap 4 that looks like the forms that BootStrap 3 allowed one to create easily. i.e. I would like a bold label right-aligned within a specific size (e.g. col-sm-4), and next to it I would like an input field whose width is controlled by an enclosing div tag with a class like col-sm-4 (as an example). How can I do this? I have spent an hour or so now battling with .css and BS4 to create this, but have been unable to achieve the effect I desire. Any hints would be great.
The code below will produce the effect I wish for but will not allow me to have different sized inputs (they all default to the same size)
css:
div.form-inline label.col-sm-3 {
justify-content: flex-end;
font-weight:650;
}
html:
<div class="form-inline">
<label for="INcity" class="col-form-label col-12 col-sm-3">City</label>
<div class="col-sm-4"><input type="text" name="INcity" class="required form-control" id="INcity"></div>
</div>
If I instead use form-group, then I can alter the size of the input fields using the enclosing tags, but then the css (even when I change it to be .form-group instead of .form-inline) fails to align the label correctly and set it to bold. So I guess I'm looking for either the correct .css or an example of how to achieve the whole effect simply (as it was with BS3). I must be missing something obvious because I can not believe that the BS4 developers would make it so difficult to achieve the same look as BS3 allowed without any of the .css hacks etc that I am having to do. Though I do notice that every one of the examples given in the BS4 documentation has the label left-aligned, so perhaps they have decided to make that formatting decision for every BS4 user, but that seems a bit unlikely (and unfriendly).
In order for col-* to work they MUST be inside a .row or .form-row.
There's no need for any extra CSS:
https://codeply.com/go/0Vkxbmgb4c
<div class="form-row">
<label for="INcity" class="col-form-label col-12 col-sm-3 font-weight-bold text-right">City</label>
<div class="col-sm-4">
<input type="text" name="INcity" class="required form-control" id="INcity">
</div>
</div>
https://getbootstrap.com/docs/4.0/components/forms/#form-grid
If you have several of these that you are converting from BS3 to BS 4, then the way that ZimSystem has suggested as an answer will be extremely tiresome to implement - being as you will have to change every single instance of this. Just create some css (as it seemed you were actually asking for) with the following .css and use find and replace to replace every instance of control-label with col-form-label. This approach is much easier than the approach suggested above, and uses a more modular approach (in that you only have to write the css markup once - modularity should be every programmer's approach in my opinion). Ensure this css is loaded AFTER BS4 css has loaded.
.col-form-label
{
font-weight:600;
text-align:right;
}

Bootstrap margin / padding disapears on adding object via jquery

I've a little problem using bootstrap and adding dynamically element on my page.
I've a form where I lwant to dynamically add new inputs. All that work fine but the rendering is not that good because it seems that there is some missing margin padding between the label and the select.
I use bootstrap as main css.
Here is an exemple : http://jsfiddle.net/4Uf2U/1/
<div class="form-inline">
<label>Label</label>
<select><option>Option</option></select></div>
Does anyone have an idea why this happen and how to correct this ?
It is because of the select. The one that is not dynamic is formatted like so:
<div class="form-inline">
<label>Label</label>
<select><option>Option</option></select>
</div>
And the dynamic ones are one liners like so:
<div class="form-inline"><label>Label</label><select><option>Option</option></select></div>
So use one way and the style (appearance) will be the same.
Here is an updated jsFiddle: click

How to center input radio

I'm using jquery mobile for my project. It automatically converts all radio buttons in its inputs with its styles. The major problem is that in different situations i have different number of buttons (it depends on user) with its different width and i need it every time center.
<div data-role="fieldcontain" id="inline" >
<fieldset data-role="controlgroup" data-type="horizontal" data-mini="true">
{section name=i loop=$data['input'] start=0}
<input name="position" id="radio{$smarty.section.i.index}" value="{$data['input'][i]}" type="radio" />
<label for="radio{$smarty.section.i.index}">
{$data['input'][i]}
</label>
{/section}
</fieldset>
</div>
As you see each button has his size (for example Up and Zoom In are different). As i said before - i don't know what buttons will be for each users - it depends on their own settings, so i need somehow automatize process of centering it - is some ideas?
You could try it with <a> instead of <input> as done in the documentation, if at all possible in your situation.

Proper way to have a break between the form

Above is a Form. There are different methods to get the following form above, with the input and text seperated on different lines.
One is to use < br / > and another use fieldset, p-tag, etc.
But I am wondering what the proper way is to seperate the form different things in different lines?
The easiest way is simply:
label, input {
display: block;
}
Edited to add the content of a comment made below, from myself to the OP, since it seems pertinent to the answer:
The 'best' is a very subjective measure. The 'best' is simply the easiest way to achieve your end-result, ideally without mangling the semantics of the HTML. Using div elements in forms gives no meaning to the contained elements, or their relationship to each other.
Using a fieldset gives some idea of the relationship, but typically (possibly should, but I'm unsure) is used to group elements together, rather than simply style them. I'd argue my method is 'best' simply because it relies on no additional (meaningful or meaningless) HTML elements being added to the page.
There are no fast rules. HTML5 seems to favor using the p element, see its example on it. By old HTML specifications, p means a paragraph, but HTML5 defines a paragrapg as virtually any block of inline content.
In practice, it is best to select the markup according to the desired default rendering. If you prefer no vertical spacing, use br or div (in the latter, you would wrap each line in a div element, making it easier to style it if desired). If you prefer spacing (empty lines), use p. Using a table is one possibility but unnecessarily complicated in a simple case like this.
Using <br/> tags to control layout is not recommended. This tag should only use to break a line in a paragraph. Using it for layout purposes is lazy and bad practice.
The best way to create forms in general like the above is to use a <ul> list.
<form>
<ul>
<li>
<label for="firstname">Name</label>
<input name="firstname" type="text" />
</li>
<li>
<label for="surname">Surname</label>
<input name="surname" type="text" />
</li>
</ul>
</form>
This is considered by many the "proper" way of doing it.
Then you can style your list in whichever way you like, so depending on the css the label can be above or next to the input field (this is where the <br/> tag would spoil that).
The basic style you need to apply is:
form ul {
list-style-type:none;
}
This gets rid of the bullet points in the list. Then you can e.g. set the elements inside to block or make them float.
I would use <div> tags and position them manually with CSS. You can also use the clear:both within CSS. I have used <br /> before as well. You do not want to be using <p> tags though because it will confuse the Google Bot which crawls your website to place you on Google Search, from a SEO point of view <p> is bad unless you actually have content within the tags.
Tables may also look a good option but here is a good article on why you should not use tables for layout http://phrogz.net/css/WhyTablesAreBadForLayout.html
Ain't nothing wrong with using br's, though the cleanest way is to just make those items display:block.
http://jsfiddle.net/chad/MdbKE/
Quite semantic way to markup label/field pairs is to use DL list (for example, this is used by default in Zend_Form). For submit button, DIV can be used:
<dl>
<dt><label for="frm-login-username">Username</label></dt>
<dd><input type="text" name="username" id="frm-login-username" /></dd>
<dt><label for="frm-login-password">Username</label></dt>
<dd><input type="password" name="password" id="frm-login-password" /></dd>
</dl>
<div><input type="submit" value="Login" /></div>

Resources