<div class="form-group">
<label for="Description">"Description"</label>
<input type="text" id="Description" class="form-control"
[(ngModel)]="description" name="Description"
required />
</div>
Is there anyway to add a star (*) after label( label::after) without changing anything in the code by just adding CSS selector? AFAIK there is no support for previous css selector (has) so I cannot use something like:
label:has(+ input:required)::after {
content:" *";
}
No.
Via CSS-only there is no way to achieve the result without changing markup or javascript in the code unless
1) label and input are in the same line, side by side and
2) the background is a solid color
as in the example below, so you could cheat by always adding the star, but if the sibling input is not [required] then cover the star using a box-shadow.
input { border: 1px #ccc solid }
label::after {
content: "*";
width: 1.5em;
margin-right: 1.5em;
}
label + input:not([required]) {
box-shadow: -3.2em 0 0 #fff;
}
<label>Username</label>
<input name='username' required />
<br /><br />
<label>Username</label>
<input name='username' />
But I'd suggest to at least revert the order of the elements in the markup (and showing them in the right order with display:flex and flex-direction: row-reverse)
If you are fine with adding a div around your every label and input group, then below approach can help you.
input {
border: 1px #ccc solid
}
input[required]+label::after {
content: "*";
color: red;
width: 1.5em;
margin-right: 1.5em;
}
.form-group {
display: flex;
}
.form-group label {
order: -1;
width: 100px;
}
<div class="form-group">
<input name='username' required />
<label>Username</label>
</div>
<br /><br />
<div class="form-group">
<input name='username' />
<label>Username</label>
</div>
The correct selector would be
.form-group:has(:required) label
But, alas, as the :has pseudo class is CSS Selectors Level 4 and has no browser support at all.
You can use it with jQuery though:
jQuery($ => {
$('.form-group:has(:required) label').each((i,el) => {console.log(el); el.classList.add('required')})
})
label.required:after {
content: ' *';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
<label for="Description"><span>Description</span></label>
<input type="text" id="Description" class="form-control"
name="Description"
required />
</div>
Since you seem to use angular, this might get a little tricky. I don't know, if there is something like this in Angular.
I'm creating a layout using column-count and -webkit-column-count but I found an issue that appears multiple times.
As you can see from this image, Chrome 45 (not happening in FF) breaks elements' border, which is very strange and quite annoying. This is a bit the code where the break happens (but I don't know why it is not happening here, only difference are fonts, and absence of Mayers css reset):
body {
line-height: 1.5;
}
form {
-webkit-column-count: 2;
column-count: 2;
}
label {
display: block;
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
margin-top: 0.625em;
}
input {
border: 1px solid green;
border-radius: 4px;
padding: 0.25em 0.5em;
}
label>span:first-child {
width: 5em;
display: inline-block;
}
<h2>CONFIG:</h2>
<form id="pop_values" action="" class="ng-pristine ng-valid">
<label>
<input type="checkbox">
<span>Mobile</span>
</label>
<label>
<input type="checkbox">
<span>Animate</span>
</label>
<label>
<span>Frecuency:</span>
<input type="number">
</label>
<label>
<span>Exclusions:</span>
<input type="text">
</label>
</form>
But it didn't work. Could you give any enlightenment?
Although it is not very clear (without markup) in your question, it seems your form elements (labels and inputs) are not wrapped in their respective containers and are on their own.
You are preventing break on labels only, and hence the inputs are not bound by that rule. This is the reason you are facing that problem.
Best solution would be to wrap your label-input sets in their own containing divs and apply break-inside: avoid on those divs.
Example:
* { box-sizing: border-box; }
form { -webkit-column-count: 2; -moz-column-count: 2; column-count: 2; }
form > div { -webkit-column-break-inside: avoid; page-break-inside: avoid; break-inside: avoid-column; }
form label, form input { display: inline-block; margin: 4px 0px; }
form input[type=text] { width: 50%; }
<form>
<div>
<input id="chk1" type="checkbox" /><label for="chk1">Mobile</label>
</div>
<div>
<input id="chk2" type="checkbox" /><label for="chk2">Animated</label>
</div>
<div>
<label for="txt1">Input 1:</label><input id="txt1" type="text" />
</div>
<div>
<label for="txt2">Input 2:</label><input id="txt2" type="text" />
</div>
<div>
<label for="txt3">Input 3:</label><input id="txt3" type="text" />
</div>
<div>
<label for="txt4">Input 4:</label><input id="txt4" type="text" />
</div>
<div>
<label for="txt5">Input 5:</label><input id="txt5" type="text" />
</div>
<div>
<label for="txt6">Input 6:</label><input id="txt6" type="text" />
</div>
</form>
Fiddle to see the effect of resizing: http://jsfiddle.net/abhitalks/jd7v0n8e/
Note: Last style rule in the above example is to prevent overflow of the inputs when the the available space is less than their default width.
Edit:
(after Op's comment)
Now that you have provided your markup, this arrangement should also work. As long as you are sure that all inputs are properly wrapped inside those labels.
See this snippet:
* { box-sizing: border-box; }
form{
-webkit-column-count: 2;
column-count: 2;
}
label {
display: block; margin: 2px;
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid-column;
}
input {
border: 1px solid green;
width: 50%;
}
<form>
<label>This: <input type="text" /></label>
<label>This is long: <input type="text" /></label>
<label>This: <input type="text" /></label>
<label>This: <input type="text" /></label>
<label>This is much longer than before: <input type="text" /></label>
<label>This: <input type="text" /></label>
<label>This: <input type="text" /></label>
<label>This: <input type="text" /></label>
</form>
And also this fiddle: http://jsfiddle.net/abhitalks/38wjpu28/3/
It seems that there must be something else going on in your markup besides what you have shown in your question.
Note 2: I would recommend going with a wrapping div and keeping the label and input separate. This would allow you greater control in case you need to change the layouts later on. (e.g. when you need to put label on top of input instead of side by side)
I have rows consisting of two elements that I'd like to align by the second element (they're input boxes, and it's nice to have them all line up vertically). The solution I behaves exactly how I want when the elements fit onto one line, I don't want to be using the width of the first element to set the horizontal position. This starts to act weird in small windows or on mobile (when the width of the label is more than 45% of the screen it starts wrapping again).
What would be the proper way to achieve the same result?
FIDDLE
HTML:
<label>Test</label>
<input type="number" value="0">
<br />
<label>Test longer</label>
<input type="number" value="0">
<br />
<label>Test longest text</label>
<input type="number" value="0">
<br />
CSS:
label {
display: inline-block;
float: left;
width: 45%;
text-align: right;
padding: 2px;
margin: 2px;
}
input {
display: inline-block;
float: left;
width: 200px;
padding: 2px;
margin: 2px;
}
You can use flex properties to display rows and columns and remove float
<div class="flex">
<label>Test</label>
<input type="number" value="0">
</div>
<div class="flex">
<label>Test longer</label>
<input type="number" value="0">
</div>
<div class="flex">
<label>Test longest text</label>
<input type="number" value="0">
</div>
in css
.flex {
display:flex;
}
label {
width: 45%;
text-align: right;
padding: 2px;
margin: 2px;
}
input {
width: 200px;
padding: 2px;
margin: 2px;
}
#media(max-width:200px){
.flex{
display:block;
}
}
and use media queries for screen below 200px(or your preference) to make the text and input appear vertically
I have a form where I gave the textfields a padding so it will be a bit bigger and nicer. Underneath the form I have a submit button.
The button and the textfields have a width of 100%, but the problem is, is that the button isn't fully 100% by that it isn't equally even in the width with the textfields. What am I doing wrong? Can't seem to "find" the issue
I have put it here http://jsfiddle.net/zrhB6/3/
The Css
input[type=text],input[type=password]{
display: block;
height: 3em;
width: 100%;
}
.btn {
background-color:#c1d82f;
border:3px solid #97a34b;
display:inline-block;
color:#26328c;
font-family:Verdana;
font-size:20px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;
cursor: pointer;
width: 100%;
}
HTML
<div class="grid-container">
<div class="grid-50 login">
<h3>Login</h3>
<form class="grid-100">
<input type="text" name="loginEmail" placeholder="Email"/>
<input type="password" name="loginPassword" placeholder="pass"/>
<input type="submit" name="loginSubmit" class="btn"/>
</div>
<div class="grid-50 login">
<h3>Register</h3>
<form">
<input type="text" name="registerName" placeholder="Name"/>
<input type="text" name="registerEmail" placeholder="Email"/>
<input type="password" name="registerPassword" placeholder="pass"/>
<input type="submit" name="registerSubmit" class="btn"/>
</div>
</div>
I'm using unSemantic grid, but that shouldn't be a issue I think
To both CSS selectors, add:
box-sizing:border-box;
The reason is the default box sizing doesn't include padding and margins in the width, so you're getting 100% + padding + border + margin for the total width.
How to position a complex form with multiple fields in line across the screen?
Why are people so hell-bent on avoiding tables?
Tables are not deprecated and should be used when displaying content which logically belongs in a table.
If your form is logically grouped such that a table would be intuitive, please use a table.
Always be thinking: "What's the cleanest, simplest, most maintainable way to achieve this result."
If you want a fluid form with a variable number columns, then disregard this.
I prefer the slightly-more-semantic way, using a definition list:
<dl class="form">
<dt><label for="input1">One:</label></dt>
<dd><input type="text" name="input1" id="input1"></dd>
<dt><label for="input2">Two:</label></dt>
<dd><input type="text" name="input2" id="input2"></dd>
</dl>
Then your CSS:
dl.form {
width:100%;
float:left;
clear:both;
}
dl.form dt {
width:50%;
float:left;
clear:left;
text-align:right;
}
dl.form dd {
width:50%;
float:left;
clear:right;
text-align:left;
}
This should produce a form centered in the page, with the labels in the left column and the inputs in the right
There are many different ways to do this. It's all a matter of preference. What I typically do is have a wrapper div that contains all of the rows, and then a div block per row that contains the label, input, and validator. You can use the line-height CSS property to help you with vertical alignment. Example:
<div class="formWrapper">
<form>
<div class="formItem">
<label for="firstName">First Name:</label>
<input name="firstName" id="firstName" class="required" type="text" />
<span class="validator" style="display: none;">*</>
</div>
... <!-- Rinse repeat -->
</form>
</div>
<style type="text/css">
.formWrapper { width: 400px }
.formWrapper .formItem { line-height: 35px; height: 35px; }
.formWrapper label { width: 50px; }
.formWrapper input { width: 100px; border: 1px solid #000; }
.formWrapper .validator { padding-left: 10px; color: #FF0000; }
</style>
Hope that helps.
After looking at many many different solutions, I found the examples on this page (particularly the one from 'Fatal'?) some of the most helpful. But the extensive and tags did bother me a bit. So here is a little bit of a modification that some may like. Also, you find some sort of 'wrapper' or 'fieldset' style very necessary to keep the float from affecting other HTML. Refer to examples above.
<style>
.formcol{
float: left;
padding: 2px;
}
.formcol label {
font-weight: bold;
display:block;}
</style>
<div class="formcol">
<label for="org">organization</label>
<input type="text" id="org" size="24" name="org" />
</div>
<div class="formcol">
<label for="fax">fax</label>
<input type="text" id="fax" name="fax" size="2" />
</div>
<div class="formcol">
<label for="3">three</label>
<input type="text" id="3" name="3" />
<label for="4">four</label>
<input type="text" id="4" name="4" />
<label for="5">five</label>
<input type="text" id="5" name="5" />
</div>
<div class="formcol">
<label for="6">six</label>
<input type="text" id="6" name="6" />
</div>
That would be done using CSS by setting the "display" property to "inline" (since form elements are, by default, block level elements).
Do a search for "layouts without tables". Many sites describe formatting with CSS. Here is a simple intro: http://www.htmlgoodies.com/beyond/css/article.php/3642151
I suggest you blueprint CSS framework. Have a quick look at the demo page.
This is what I usually use when I need to design pretty complex forms.
HTML:
<fieldset> <legend>Consent group</legend> <form> <fieldset class="nolegend"> <p><label><span>Title</span> <input type="text" name="title" size="40" value="" /></label></p> <p><label><span>Short name</span> <input type="text" name="sname" size="20" value="" /></label></p> <p><label><br /><input type="checkbox" name="approval"> This consent group requires approval</label></p> </fieldset> <fieldset class="nolegend"> <p><label><span>Data use limitations</span> <textarea name="dul" cols="64" rows="4"></textarea></label></p> </fieldset> <input type="submit" value="Submit" /> </form></fieldset>
CSS:
body, input, textarea, select { font: 1em Arial, Helvetica, sans-serif;}input, textarea, select { font-size: .8em }fieldset,fieldset legend { background-color: #EEE;}fieldset { border: none; margin: 0; padding: 0 0 .5em .01em; top: 1.25em; position: relative; margin-bottom: 2em;}fieldset fieldset { margin: 0 0 1em 0;}fieldset legend { padding: .25em .5em 0 .5em; border-bottom: none; font-weight: bold; margin-top: -1.25em; position: relative; *left: -.5em; color: #666;}fieldset form,fieldset .fieldset { margin: 0; padding: 1em .5em 0 .5em; overflow: hidden;}fieldset.nolegend { position: static; margin-bottom: 1em; background-color: transparent; padding: 0; overflow: hidden;}fieldset.nolegend p,fieldset.nolegend div { float: left; margin: 0 1em 0 0;}fieldset.nolegend p:last-child,fieldset.nolegend div:last-child { margin-right: 0;}fieldset.nolegend label>span { display: block;}fieldset.nolegend label span { _display: block;}
I omitted couple lines of CSS with Safari hacks. You can check out live version of this code.
Pace KyleFarris but I just had to give Ben S a vote for having the guts to mention tables. Just look at the variety of CSS solutions on this page and around the internet for a ridiculously simple problem. CSS may one day become a good solution, but for the time being replicating the simple row and column grid that the table tag provides is extremely complex. I have spent countless fruitless hours with this prejudice against tables for things like a form. Why do we do this to ourselves?
input fields, by default, are inline. Therefore, you can simply use line them up without Another option if you want them lined up correctly is as follows:
<div id="col1" style="float: left;>
<input type="text" name="field1" />
<br />
<input type="text" name="field3" />
</div>
<div id="col2" style="float: left;>
<input type="text" name="field2" />
<br />
<input type="text" name="field4" />
</div>
I prefer to use fieldset to group all elements and p for each form field.
<html>
<head>
<style type="text/css">
fieldset {
width: 500px;
background-color: lightblue;
}
fieldset legend {
font-weight: bold;
}
fieldset p {
clear:both;
padding: 5px;
}
fieldset label {
text-align: left;
width: 100px;
float: left;
font-weight: bold;
}
fieldset .Validator {
color: red !important;
font-weight: bold;
}
</style>
<head>
<body>
<form>
<fieldset>
<legend>Data</legend>
<p>
<label for="firstName">First Name:</label>
<input name="firstName" id="firstName" class="required" type="text" />
<span class="Validator" style="display: none;">*</span>
</p>
<p>
<label for="lastName">Last Name:</label>
<input name="lastName" id="lastName" class="required" type="text" />
<span class="Validator">*</span>
</p>
</fieldset>
</form>
</body>
</html>