Trying to create tableless control with dynamic content - css

I am pulling some content from a webservice that creates select lists with a label as a form of title. Rules are that the select lists must line up and stack on top of each other, and take up the rest of the screen real estate that the label does not take up.
I can do this by creating them with tables, but am looking for a more pure CSS route if possible.
tried using a combination of divs with display: table, display: table-row, display: table-cell but I couldn't get the stacking effect to work properly.
this is the effect I am looking for:
.horizontalFill {
width: 100%;
}
.noWrap {
white-space: nowrap;
}
<table class="horizontalFill">
<tr>
<td class="noWrap">
<label>some dynamic text</label>
</td>
<td class="horizontalFill">
<select class="horizontalFill">
</select>
</td>
</tr>
<tr>
<td class="noWrap">
<label>
other dynamic text here
</label>
</td>
<td class="horizontalFill">
<select class="horizontalFill"></select>
</td>
</tr>
</table>

You can try something similar to this:
label {
display: block;
overflow: hidden;
padding-bottom: 5px;
}
label .label {
display: block;
float: left;
width: 150px;
}
label .input {
display: block;
margin-left: 160px;
}
label select {
width: 100%;
}
<label class="row">
<span class="label">Label name one</span>
<span class="input">
<select>
<option>Select item</option>
</select>
</span>
</label>
<label class="row">
<span class="label">Label name two</span>
<span class="input">
<select>
<option>Select item</option>
</select>
</span>
</label>
<label class="row">
<span class="label">Label name three</span>
<span class="input">
<select>
<option>Select item</option>
</select>
</span>
</label>
It involves the label column being set to a static width, though, so it may not work out for you if you need that column to stretch or shrink. The label text will wrap to the next line without any issue, though.

Related

Material: Trying to style the form fields of a Mat-Card

I'm new to UI development and don't have deep knowledge of css. I've been googling examples to style a login page using Angular Material. I'm trying to get the form fields to expand the width of the card (minus the padding), but not having any luck.
Can someone tell me what my form fields should look like? Also, I see that a lot of the styles have "example-" in their name. Are these to be defined in my css?
Here's my stylesheet:
.example-icon {
padding: 0 14px;
}
.example-spacer {
flex: 1 1 auto;
}
.example-card {
max-width: 400px;
width: 75%;
margin: 10px auto;
}
.example-header-image {
background-image: image("./assets/logo.png");
background-size: cover;
}
.main-div {
height: 50vh;
display: flex;
justify-content: center;
align-items: center;
}
And the html page:
<div class="main-div">
<mat-card class="example-card">
<mat-card-header>
<!--<div mat-card-avatar class="example-header-image"></div>-->
<img mat-card-avatar src="./assets/logo.png">
<mat-card-title>Login</mat-card-title>
</mat-card-header>
<mat-card-content>
<form class="example-form">
<table class="example-full-width" cellspacing="0">
<tr>
<td>
<mat-form-field class="example-full-width">
<input matInput placeholder="Username" [(ngModel)]="username" name="username" required>
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="example-full-width">
<input matInput placeholder="Password" [(ngModel)]="password" type="password" name="password" required>
</mat-form-field>
</td>
</tr>
</table>
</form>
<mat-spinner [style.display]="showSpinner ? 'block' : 'none'"></mat-spinner>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button (click)="login()" color="primary">Login</button>
</mat-card-actions>
</mat-card>
</div>
You need to create style class in your .css file, which is used in template.
.example-full-width {
width: 100%;
}
You dont need do use prefix example for your style classes, but dont forget to rename them both in template(.html file) and .css file.

how to get select2 dropwdown to stay at constant width

I am using select2 for a dropdown in a form and I like using a table layout (although maybe this is part of the problem?) to keep the widths of all of the form-group elements the same.
The problem is that when I type text into the select2 dropdown, the width changes (and in weird ways). Is there a way I can force the initial width that the browser gives the select2 dropdown to remain fixed?
Here is my html:
<table>
<tr>
<td>
<div class="row">
<div class="form-group">
<label>Title</label>
<input name="title" class="form-control"/>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="row">
<div class="form-group">
<label>a label</label>
<input class="form-control"/>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="row">
<div class="form-group">
<label>a label</label>
<select id="tag_list" class='form-control' multiple="multiple">
<option value='1'>abba</option>
<option value='2'>zabba</option>
<option value='3'>doo</option>
</select>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="row">
<div class="form-group">
<label for="category_type">Category Type:</label>
<select name="category_type" id="category_type_list" class="form-control">
<option value="" disabled selected>If there is a matching type for the category, please select it</option>
<option value="1">A</option>
<option value="2">B</option>
</select>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="row action">
<div class="form-group">
<div class="inline">
<button class="btn btn-primary form-control" type="submit">submit</button>
</div>
<div class="inline">
<button class="btn btn-primary cancel">Cancel</button>
</div>
</div>
</div>
</td>
</tr>
</table>
and my css:
.form-group{
display: block;
}
table {
margin-left: 5%;
table-layout: fixed;
}
input {
height: 30px;
border: 1px solid #e3e3e3;
padding: 3px 10px;
width: 100%;
}
.inline{
float:left;
margin-right: 5px;
}
span.select2-container{
width: 100% !important;
tex-overflow: ellipsis;
}
Here is a fiddle example. You can try it out by typing something long enough into the select2 dropdown and pressing enter seeing that the width changes. How can I stop that from happening?
I Added a new css class that seems to work aimed at that specific select box.
The + is equivalent to the jquery next function. This should get you pointed in the right direction. Just to be safe, make sure this is set after you load the select2 css.
#tag_list + .select2-container .select2-selection--multiple {
max-width: 400px;
}
So if you want the search box to be the same size for all select2s (single or multi ) then try...
.select2-container .select2-dropdown,
.select2-container .select2-selection--multiple {
max-width: 300px;
}
I turned the last select box into a select2 and tried this.
What I am doing is using the DOM explorer built into IE to find the element that is giving me issues and what classes are being applied. Then I simple overwrite or append them.
by setting width=100% as below
<select id="tag_list" style="width:100%; display:block;" class='form-control' multiple="multiple">
<option value='1'>abba</option>
<option value='2'>zabba</option>
<option value='3'>doo</option>
</select>
.select2 dropdown to stay at constant width in table tag use below style in your code
<style>
.select2-container{
width: 100% !important;
}
</style>

How can i access only the first label?

How can I access the only the first label? I have tried with
.form-group label:nth-child(1){
margin-top: 4%;
}
however i got no result :\
<form class="login" method="post" action="/users/login">
<div class="form-group">
<label>Username</label>
<input type="text" class="form-control" name="username" placeholder="Username">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password" placeholder="Password">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
.form-group:first-child label{
margin-top: 4%;
}
Access the first form group and then its label:
.form-group:first-child > label {
display: inline-block;
margin-top: 4%;
}
Edit: this is assuming you only want to target the label for "Username".
It is because your css goes for the every-first (meaning every) label in every .form-group element.
You need to change it to first .form-group's label.
.form-group:first-child label {
//code
}
Revised:
.login .form-group:first-child label{
margin-top: 4%;
display: inline-block;
}
Use of :nth-child is to selecting element with same parent. In simple words, say you have a HTML like below:
<div>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
The span:nth-child(1) is first child of div with tag-name span. But, if you apply same selector with below HTML (Like in your case):
<div>
<span></span>
</div>
<div>
<span></span>
</div>
Selected elements are both the span because both span came first in their parent which is div

Make span and input equally sized

In the following snippet I want <span>1</span> to have the same width, as <input type="text" size="1" value="1" />
Same for second span and second input. And so on.
<!DOCTYPE HTML>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
<div>
<input type="text" size="1" value="1" />
<input type="text" size="1" value="2" />
<input type="text" size="1" value="3" />
</div>
</body>
</html>
How can I accomplish this with css?
UPD: Sorry, I did not make it clear, that it must be 2 rows. Row of spans and row of inputs
I assume that you want to retain the span elements inline behavior, but inline1 elements don't take width, so assign display: inline-block; to your span elements
div span {
display: inline-block;
width: 25px;
text-align: center;
border: 1px solid #f00;
}
div input[type=text] {
width: 25px;
}
Demo
1. Inline Elements
Note: As you might be aware, inline-block retains white space between the elements, to get rid of that, either call font-size: 0; on the parent element, or consider floating your elements to the left, and you don't have to use size attribute anymore, consider assigning width to the elements using CSS instead.
Also make sure you normalize your CSS for cross browser consistency.
Remove the size of one on the inputs and add a class.
(Just in case you dont know, 1 em = the current font-size)
<!DOCTYPE HTML>
<style>
.one {
width: 1em;
}
.two {
width: 1em;
}
.three {
width: 1em;
}
</style>
<body>
<div>
<span class="one">1</span>
<span class="two">2</span>
<span class="three">3</span>
</div>
<div>
<input type="text" class="one" value="1" />
<input type="text" class="two" value="2" />
<input type="text" class="three" value="3" />
</div>
</body>
</html>
JsFiddled here :
span, input {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
width:222px;
height: 33px;
padding:0;
margin:0;
display:block;
float:left
}
BUT, by forcing the input in a border-box layout, you will have to deal with some other situations....
Somehow, i feel ashamed trying to help you without seeing first what you have tried.
Well if you want to remain your span's, you could use something like this:
#wrapper
{
height: auto;
width: 500px;
}
span, input
{
width: 30%;
display: inline-block;
}
jsFiddle
However, your layout is so close to a table layout. So why not use the <table> element:
<table>
<tr>
<td>
<label>1</label>
</td>
<td>
<label>2</label>
</td>
<td>
<label>3</label>
</td>
</tr>
<tr>
<td>
<input type="text" size="1" value="1" />
</td>
<td>
<input type="text" size="1" value="2" />
</td>
<td>
<input type="text" size="1" value="3" />
</td>
</tr>
</table>
jsFiddle

How do I line up input fields and their labels in a grid like manner with css?

I'm trying to do something that must be relatively easy, but I've spent hours mucking around with this and I'm no getting to the answer.
I need to layout some input fields and their layers on a grid (or like a table I guess) with
lable input label input
label input label input
Because the input fields are different widths (and would look pretty crappy if they were all the same width) the best I've managed to get is
label input label input
label logerinput label input
How do I line up the second set of labels and there inputs?
I've made two classes for the labels
#dpi_form label {
display: inline-block;
width: 150px;
margin-left: 20px;
}
#dpi_form .right-label {
display: inline-block;
width: 150px;
margin-left: 220px;
}
and the associated controls are
<label for="req_retailer_index_fld">Select the retailer*:</label><select id="req_retailer_index_fld" name="req_retailer_index_fld" class="required selectbox ui-widget-content"><option>item 1</option><option>item 2</option></select>
<label for="req_region_index_fld" class="right-label">Select the region*:</label><select id="req_region_index_fld" name="req_region_index_fld" class="required selectbox ui-widget-content"><option>item 1</option><option>item 2</option></select><br />
<label for="req_customer_type_index_fld">Select the customer type*:</label><select id="req_customer_type_index_fld" name="req_customer_type_index_fld" class="required selectbox ui-widget-content"><option>item 1</option><option>item 2</option></select>
<label for="req_meter_state_index_fldi" class="right-label">Select the meter state*:</label><select id="req_meter_state_index_fld" name="req_meter_state_index_fld" class="required selectbox ui-widget-content"><option>item 1</option><option>item 2</option></select><br />
within a div.
I've tried absolute positioning, relative positioning, padding, all manner of right and left margins but still can't get the result I'm after.
I can find heaps of stuff or vertical alignment of controls.. but nothing showing me how to do this one.
Any clues please?
Peter.
Despite my comment about using tables on your question, this is how I would do it.
CSS:
label,
input {
display: block;
}
label {
padding: 4px 0 0;
}
.labels1 {
float: left;
width: 80px;
}
.labels2 {
float: left;
width: 80px;
}
.inputs1 {
float: left;
width: 200px;
}
.inputs2 {
float: left;
width: 200px;
}
HTML:
<div class="labels1">
<label for="input1">Input 1: </label>
<label for="input2">Input 2: </label>
<label for="input3">Input 2: </label>
</div>
<div class="inputs1">
<input type="text" value="" name="input1" id="input1" />
<input type="text" value="" name="input2" id="input2" />
<input type="text" value="" name="input3" id="input3" />
</div>
<div class="labels2">
<label for="input4">Input 4: </label>
<label for="input5">Input 5: </label>
<label for="input6">Input 6: </label>
</div>
<div class="inputs2">
<input type="text" value="" name="input4" id="input4" />
<input type="text" value="" name="input5" id="input5" />
<input type="text" value="" name="input6" id="input6" />
</div>
Then you can change the labels and inputs classes to the width you want.
Although I still think tables are easier because then you don't have to worry about setting widths yourself; you also don't have to worry about vertical alignment with tables.
use following styles.
for parent container
display: table;
for row container
display: table-row;
for cell container
display: table-cell;
example
<div style="display: table;">
<div style="display: table-row;">
<div style="display: table-cell;">
lable
</div>
<div style="display: table-cell;">
input
</div>
<div style="display: table-cell;">
label input
</div>
</div>
<div>
<div style="display: table-cell;">
lable
</div>
<div style="display: table-cell;">
input
</div>
<div style="display: table-cell;">
label input
</div>
</div>
</div>
Use a table, that's what they are for.
I would suggest using a table or for a pure CSS solution maybe the 960 grid system 960.gs
I would use floats. Here's a jsfiddle showing how I would do it:
http://jsfiddle.net/pSsap/
I'll reproduce the code below.
With html like this:
<form class="grid">
<section>
<label for="wind">wind</label>
<span class="field"><input id="wind" name="wind" type="input" class="regular"></span>
<label for="earth">earth</label>
<span class="field"><input id="earth" name="earth" type="input" class="regular"></span>
</section>
<section>
<label for="fire">fire</label>
<span class="field"><input id="fire" name="fire" type="input" class="long"></span>
<label for="air">air</label>
<span class="field"><input id="air" name="air" type="input" class="regular"></span>
</section>
</form>
And css like this:
form.grid section {
clear: both;
}
form.grid section label, form.grid section span.field {
display: block;
float: left;
}
form.grid section label {
width: 50px;
}
form.grid section span.field {
width: 150px;
}
input.regular {
width: 100px;
}
input.long {
width: 140px;
}
Solutions:
Use a list: <ol> or <ul>
Set a width for that list: (in the example, 960px is the width of the <ul>)
Float the lists: <li> and set a width to limit its floating point: (in the example, 320px is the set width)
If you want to have a consistent alignment with the <label> and <select> pairs, set a width to the <label> (make sure you set it as a block-level element first: in the example, the <label> was set to 160px)
Make sure to clear (clear: left) any elements following this list (<ul>) used.
The Markup:
<ul>
<li>
<label for="req_retailer_index_fld">Select the retailer*:</label>
<select id="req_retailer_index_fld" name="req_retailer_index_fld" class="required selectbox ui-widget-content">
<option>item 1</option><option>item 2</option>
</select>
</li>
<li>
<label for="req_region_index_fld" class="right-label">Select the region*:</label>
<select id="req_region_index_fld" name="req_region_index_fld" class="required selectbox ui-widget-content">
<option>item 1</option><option>item 2</option>
</select>
</li>
<li>
<label for="req_customer_type_index_fld">Select the customer type*:</label>
<select id="req_customer_type_index_fld" name="req_customer_type_index_fld" class="required selectbox ui-widget-content">
<option>item 1</option><option>item 2</option>
</select>
</li>
<li>
<label for="req_meter_state_index_fldi" class="right-label">Select the meter state*:</label>
<select id="req_meter_state_index_fld" name="req_meter_state_index_fld" class="required selectbox ui-widget-content">
<option>item 1</option><option>item 2</option>
</select>
</li>
</ul>
The CSS
ul {
background: #EEE;
width: 960px;
}
li {
background: #FFC0CB;
float: left;
list-style: none;
width: 320px;
}
label {
display: inline-block;
width: 160px;
}
The result is that, the list will just drop when the <ul> can't contain it any longer (since you have set a width in it). On the other hand, the width of the <li>s will consistently make them align to each other, while being floated.

Resources