Dynamic auto input text width with css - html

I am not sure how easy this is, but because I usually code in php and output the html, I can do any calculations from there
The problem:
I have a simple form, and I want the input text fields to start right after the labels, but end at the same position. i.e. have a max of date of birth, and then expand everyone up to there
I tried some things with max-width/min-width and width but nothing seems to work
.input_field {
max-width:150px;
width:100%;
}
I would prefer a non javascript solution if possible!

An example using FlexBox: you could also set a width (or min/max-width to the form element (or to ul element)
Codepen: http://codepen.io/anon/pen/oXdbab
HTML
<form>
<ul>
<li>
<label>Label regular</label>
<input type="text" />
</li>
<li>
<label>Label2 really really longer</label>
<input type="text" />
</li>
<li>
<label>Label</label>
<input type="text" />
</li>
</ul>
</form>
CSS
form ul {
list-style: none;
margin: 20px 0; padding: 0;
max-width: 500px;
}
form li {
display: flex;
margin: 10px 0 0 0;
}
form input {
margin-left: 2em;
flex-grow: 1;
}
Result
Final note: Flexbox module is not supported on IE<10. but, on those browser only, you may use a script inside a conditional comment, e.g.
<!--[if lte IE 9]>
<script>
...
</script>
<![endif]-->

Related

PureCSS grid boxes not 100% height with variable content

I am trying to integrate purecss (purecss.io) into wordpress and i have problems setting grid boxes 100% height. I apply a gray background (odd/even nth-child css property) and it clearly shows the problem with variable content inside the boxes.
How do i set the boxes 100% height, so that i can apply background uniformly?
In the screenshot, i want the grid box showing search form to be 100% height so that entire background is gray.
<widgets class="pure-g">
<div id="search-2" class="pure-u-1 pure-u-md-1-2 l-box widget widget_search"><form role="search" method="get" id="searchform" class="searchform" action="http://localhost/wp/">
<div>
<label class="screen-reader-text" for="s">Search for:</label>
<input type="text" value="" name="s" id="s" />
<input type="submit" id="searchsubmit" value="Search" />
</div>
</form></div> <div id="recent-posts-2" class="pure-u-1 pure-u-md-1-2 l-box widget widget_recent_entries"> <h2>Recent Posts</h2> <ul>
<li>
WordPress themes are just being released today all over the World 1200 GMT
</li>
<li>
Hello world!
</li>
<li>
Markup: HTML Tags and Formatting
</li>
<li>
Markup: Image Alignment
</li>
<li>
Markup: Text Alignment
</li>
</ul>
</div>
</widgets>
I apply gray background color to odd widgets with this css code
/** Front page widgets ***/
.widget { font-size: 1.7vw; }
.gray { background: #eee; }
.widget img {
display:block;
margin: 20px;
}
.widget:nth-child(odd) { background: #eee }
.widget p { overflow:hidden; margin-left: 2em; display: block }
.widget h2 { margin:0; padding-bottom: 0.7em }
This is an excellent use case for flexbox. Just set the display property of the parent of the grid elements to flex, like so:
.pure-g {
display: flex;
}
And the heights of the grid elements will be normalized.
As others have suggested already, you might also be able to achieve similar results by setting the display properties of involved elements to their respective table counterparts, essentially turning your grid into a fake table.
Other than that there's no way to normalize column heights with CSS without taking (one of) the elements out the content flow, which may not be desired.
In CSS, height: 100% doesn't quite behave as one would expect. Any percentual height won't resolve to an actual height unless their direct parent has as explicit height declared, but since you have dynamic content height you cannot/should not set a static value.
You could work around this by using javascript to dynamically set the height of the parent to the height of the tallest child, thus making percentual heights work inside of it, but that's an entirely different question.
Here I've got a way to do this, first make those divs display: table-cell. This will make them go equal height. And for responsiveness of your website at lower mobile resolutions, you can use #media query to set the divs back to display: block
See the live example what I mean.
You will see both the divs at equal height due to display: table-cell, but when you will drag the left border of the Result window to make its width smaller then you will see at window width: 500px they break on next line. You can also fully control this behavior as you want.
#search-2, #recent-posts-2 { /* or you can simply use .widget here */
padding: 20px;
display: table-cell;
}
#media all and (max-width: 500px) {
#search-2, #recent-posts-2 {
display: block;
}
}
widget {
display: table;
}
#search-2, #recent-posts-2 {
display: table-cell;
}
Working fiddle
https://jsfiddle.net/bj1kqn6k/4/
This will Work,
HTML
<div class="pure-g hellodiv">
<div id="search-2" class="pure-u-1 pure-u-md-1-2 l-box widget widget_search"><form role="search" method="get" id="searchform" class="searchform" action="http://localhost/wp/">
<div>
<label class="screen-reader-text" for="s">Search for:</label>
<input type="text" value="" name="s" id="s" />
<input type="submit" id="searchsubmit" value="Search" />
</div>
</form>
</div>
<div id="recent-posts-2" class="pure-u-1 pure-u-md-1-2 l-box widget widget_recent_entries"> <h2>Recent Posts</h2> <ul>
<li>
WordPress themes are just being released today all over the World 1200 GMT
</li>
<li>
Hello world!
</li>
<li>
Markup: HTML Tags and Formatting
</li>
<li>
Markup: Image Alignment
</li>
<li>
Markup: Text Alignment
</li>
</ul>
</div>
</div>
CSS
html,body{height:100%;margin:0 auto;}
.hellodiv {
display: table;background-color:red;height:100%;
}
#search-2, #recent-posts-2 {
display: table-cell;
}
/** Front page widgets ***/
.widget { font-size: 1.7vw; }
.gray { background: #eee; }
.widget img {
display:block;
margin: 20px;
}
.widget:nth-child(odd) { background: #eee }
.widget p { overflow:hidden; margin-left: 2em; display: block }
.widget h2 { margin:0; padding-bottom: 0.7em }
Some times to have such a layout, you need absolute or fixed positioning, I would go for fixed, since the div will always remain full height:
.widget_search {
position:absolute;
top:0;
bottom:0;
width:15em;
}
This can be achieved with flex-box. https://jsfiddle.net/pt9q18j9/
there are two parts to flexbox, the container and the items in the container
set your container, in this case widgets to be display:flex;
widgets{
display: flex;
}
then the items you want to display side by side get the flex-basis property. setting a value of 1 on each means they will default to being the same size, if you set something like 1 for search and 2 for entries, entries would attempt to take up twice the space
.widget .widget_search {
flex-basis: 1;
}
.widget .widget_recent_entries {
flex-basis: 1;
}
this is a very good article on flex-box https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Add below custom css in your css.
.pure-g {
display: table;
table-layout: fixed;
}
.widget {
font-size: 1.7vw;
vertical-align: middle;
}

Group items? Form

For fun I have taken a piece of code I got from a friend and tried to create a login field with username and password and I am having a hard time get the fields next to the words. There is a big gap between the word username and the box you type in.The same applies for password.
This is my code:
<form method="post" action="https://www.mattepunkten.com/action_login.php">
<input type="hidden" name="error_url" value="http://www."here you write url to webpage one should be directed to when typing wrong login".com">
Username:
<input type="text" name="fld_userid" size="15" style="width: 120px"><br>
Password:
<input type="password" name="fld_password" size="15" style="width: 120px"><br>
<input type="submit" name="cmd_invia" value="Login">
</form>
And my css code is the following.
input {
color: black;
margin: 10px 100px 0px 400px;
}
form {
color: white;
text-align: right;
position: fixed;
margin-top: 30px;
}
I am pretty new at this and would appreciate some tips! Thanks!
Well your margins are huge, try to make them smaller and see how it looks:
input {
color: black;
margin: 10px;
}
The style you are using has the following format:
margin: <top> <right> <down> <left>;
So with 100px right and 400px left they will get very far away :)
To be able to style the text you need it to be an element, so a simple answer would be to wrap it in some tag, but this is a style I personally enjoy, and adds a lot more meaning:
html
<label>
<span>Username:</span>
<input name="fld_userid">
</label>
css
label { display: block; text-align: center; }
input, span { display: block; width: 200px; }
This should stack both the text and the input on top of each other, while keeping them grouped by the label, so when you interact with the text the browser properly focus its related input.
I will add an explanation
margin: 10px 100px 0px 400px;
stands for:
top margin is 10px
right margin is 100px
bottom margin is 0px
left margin is 400px
Have you tried working with labels at all - keeping it semantic, and formatted, plus if you wrap your inputs it'll give it a larger hit area for said fields. In addition - I removed the input margin, removed the forms positioning and float so it retained it's block level, and adjusted the overall form margin so it's centered.
HTML
<form method="post" action="https://www.mattepunkten.com/action_login.php">
<input type="hidden" name="error_url" value="#"/>
<label>Username:
<input type="text" name="fld_userid" size="15"/><label>
<label>Password:
<input type="password" name="fld_password" size="15"/></label>
<input type="submit" name="cmd_invia" value="Login"/>
</form>
CSS
label {
display: block;
}
form {
text-align: center;
margin-top: 30px auto;
}
http://jsfiddle.net/evanbriggs/kad7yy1L/
Its better form to contain your labels in a <label> tag.
For example:
<div class="form-element">
<label for="foo">Label</label>
<input type="text" name="foo" id="foo" />
</div>
CSS to style it left justified:
.form-element label {
display: inline-block;
width: 150px;
}

Control layout of text input and checkboxes within a table cell

I have some HTML that displays a text input and 2 checkboxes side by side. The HTML is generated by a tool and so I cannot alter the way the HTML is built, I can only apply styling to it using CSS. My simplified HTML and CSS is:
<html>
<head>
<style type="text/css">
td {
padding: 0;
}
fieldset {
display: inline;
padding: 0;
margin: 0
}
input[type="text"] {
margin: 0;
padding: 0;
}
table.checkboxs {
border-collapse:collapse;
}
table.checkboxs td {
border: none;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<input type="text" id="item1" value="" />
<fieldset>
<table summary="" class="checkboxs" border-collapse="">
<tr>
<td><input type="checkbox" id="chkbox_0" name="chkbox" value="1" /><label for="chkbox_0">One</label></td>
<td><input type="checkbox" id="chkbox_1" name="chkbox" value="2" /><label for="chkbox_1">Two</label></td>
</tr>
</table>
</fieldset>
</body>
</html>
This ends up with the checkboxes displayed higher up than the text item like this:
What I would like is them aligned together like this:
That seems simple enough, but I cannot figure out how to achieve it. If you remove either the text input or the fieldset then the remaining element takes up the minimum vertical space, it is only when they are together that the text input gets pushed down the page.
By all means point out any shortcomings in the HTML, but as I said that is really not under my control, I can only influence the layout using CSS.
There are two quick solutions I can think of. The first is to get the table to behave and align more like regular text by setting:
table.checkboxs {
display:inline-block;
vertical-align:middle;
}
JSFiddle example
Or by aligning the textbox to behave more like the table:
input[type="text"] {
vertical-align:top;
}
JSFiddle example
Try to give float:left to both of them, input and fieldset and then use margin-top if needed to achieve what you want.
try
input {
display: inline-block;
}
fieldset {
display: inline;
padding: 0;
margin: 0
}

Why is this CSS nowrap not working?

I'm trying to keep the bar_top_container div from wrapping it's contents no matter how wide the page is (i.e. both selects should appear always on the same line), this is not working however when the page width is to small for them to both fit on one line, how can i fix this?
Styles:
#bar_top_container { position: relative; white-space: nowrap; }
#bar_top_block { float: left; padding-left: 10px; padding-right: 10px; border-right: 1px solid #4965BB; }
#clear { clear: both; }
HTML:
<div id="bar_top_container">
<div id="bar_top_block">
<span class="bold">select1: </span>
<select><option value="asdf">asdf</option></select>
</div>
<div id="bar_top_block">
<span class="bold">asdf: </span>
<select><option value="blah">-- select action --</option></select>
</div>
<div id="clear"></div>
</div>
You can have both block and inline properties for an element if you display it as ... inline-block!
Here is your code corrected and working:
span.bold are labels
a label is associated to its form element via the for/id attributes
bar_top_block is an id used twice. Should be a class
no need for float: left; as display: inline-block; is used
thus no need for a clearing element either
the .bar_top_block elements are also displayed inline so any whitespace between them is displayed as whitespace. To avoid this, I added a comment that avoid any whitespace though still letting the HTML code readable. The text within is 'no whitespace' so the developer will know that this comment is there for a reason and shouldn't be stripped :)
you can remove the width on body, it's just here for the example
you can play with the overflow property on the container
as IE7 and below don't understand the inline-block value on block elements like div, you must use display: inline and give the element the hasLayout with, for example, zoom: 1;
the best way to target IE7 and below and only those browsers is with a conditional comment
I added support for Fx2 but this is merely for historical reasons :)
.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>Stack Overflow 3150509 - Felipe</title>
<style type="text/css">
body {
width: 300px;
}
#bar_top_container {
overflow: auto;
white-space: nowrap;
border: 1px solid red;
}
.bar_top_block {
display: -moz-inline-stack; /* Fx2, if you've to support this ooold browser. You should verify that you can still click in the elements, there is a known bug with Fx2 */
display: inline-block;
padding-left: 10px;
padding-right: 10px;
border-right: 1px solid #4965BB;
}
</style>
<!--[if lte IE 7]><style type="text/css">
.bar_top_block {
display: inline;
zoom: 1;
}
</style> <![endif]-->
</head>
<body>
<form method="post" action="#" id="bar_top_container">
<div class="bar_top_block">
<label for="select1">Obviously I am a label: </label>
<select id="select1"><option value="asdf">asdf</option></select>
</div><!-- no whitespace
--><div class="bar_top_block">
<label for="select2">I'm a label too and I need a for attribute: </label>
<select id="select2"><option value="blah">-- select action --</option></select>
</div>
</form>
</body>
</html>
Floating elements wrap as white-space: nowrap does not work for block elements but only for inline elements and text.
I'm suggesting to use a valid form usage:
<form>
<label>select1: <select><option value="asdf">asdf</option></select></label>
<label>asdf: <select><option value="blah">-- select action --</option></select></label>
</form>
Hope it helps.

Input type=text to fill parent container

I'm trying to let an <input type="text"> (henceforth referred to as “textbox”) fill a parent container by settings its width to 100%. This works until I give the textbox a padding. This is then added to the content width and the input field overflows. Notice that in Firefox this only happens when rendering the content as standards compliant. In quirks mode, another box model seems to apply.
Here's a minimal code to reproduce the behaviour in all modern browsers.
#x {
background: salmon;
padding: 1em;
}
#y, input {
background: red;
padding: 0 20px;
width: 100%;
}
<div id="x">
<div id="y">x</div>
<input type="text"/>
</div>
My question: How do I get the textbox to fit the container?
Notice: for the <div id="y">, this is straightforward: simply set width: auto. However, if I try to do this for the textbox, the effect is different and the textbox takes its default row count as width (even if I set display: block for the textbox).
EDIT: David's solution would of course work. However, I do not want to modify the HTML – I do especially not want to add dummy elements with no semantic functionality. This is a typical case of divitis that I want to avoid at all cost. This can only be a last-resort hack.
With CSS3 you can use the box-sizing property on your inputs to standardise their box models.
Something like this would enable you to add padding and have 100% width:
input[type="text"] {
-webkit-box-sizing: border-box; // Safari/Chrome, other WebKit
-moz-box-sizing: border-box; // Firefox, other Gecko
box-sizing: border-box; // Opera/IE 8+
}
Unfortunately this won't work for IE6/7 but the rest are fine (Compatibility List), so if you need to support these browsers your best bet would be Davids solution.
If you'd like to read more check out this brilliant article by Chris Coyier.
Hope this helps!
You can surround the textbox with a <div> and give that <div> padding: 0 20px. Your problem is that the 100% width does not include any padding or margin values; these values are added on top of the 100% width, thus the overflow.
Because of the way the Box-Modell is defined and implemented I don't think there is a css-only solution to this problem. (Apart from what Matthew described: using percentage for the padding as well, e.g. width: 94%; padding: 0 3%;)
You could however build some Javascript-Code to calculate the width dynmically on page-load... hm, and that value would of course also have to be updated every time the browserwindow is resized.
Interesting by-product of some testing I've done: Firefox does set the width of an input field to 100% if additionally to width: 100%; you also set max-width to 100%. This doesn't work in Opera 9.5 or IE 7 though (haven't tested older versions).
How do I get the textbox to fit the container in 2019?
Just use display: flex;
#x {
background: salmon;
padding: 1em;
display: flex;
flex-wrap: wrap;
}
#y, input {
background: red;
padding: 0 20px;
width: 100%;
}
<div id="x">
<div id="y">x</div>
<input type="text"/>
</div>
This is unfortunately not possible with pure CSS; HTML or Javascript modifications are necessary for any non-trivial flexible-but-constrained UI behavior. CSS3 columns will help in this regard somewhat, but not in scenarios like yours.
David's solution is the cleanest. It's not really a case of divitis -- you're not adding a bunch of divs unnecessarily, or giving them classnames like "p" and "h1". It's serving a specific purpose, and the nice thing in this case is that it's also an extensible solution -- e.g. you can then add rounded corners at any time without adding anything further. Accessibility also isn't affected, as they're empty divs.
Fwiw, here's how I implement all of my textboxes:
<div class="textbox" id="username">
<div class="before"></div>
<div class="during">
<input type="text" value="" />
</div>
<div class="after"></div>
</div>
You're then free to use CSS to add rounded corners, add padding like in your case, etc., but you also don't have to -- you're free to hide those side divs altogether and have just a regular input textbox.
Other solutions are to use tables, e.g. Amazon uses tables in order to get flexible-but-constrained layout, or to use Javascript to tweak the sizes and update them on window resizes, e.g. Google Docs, Maps, etc. all do this.
Anyway, my two cents: don't let idealism get in the way of practicality in cases like this. :) David's solution works and hardly clutters up HTML at all (and in fact, using semantic classnames like "before" and "after" is still very clean imo).
This behavior is caused by the different interpretations of the box model. The correct box model states that the width applies only to the content and padding and margin add on to it. So therefore your are getting 100% plus a 20px right and left padding equaling 100%+40px as the total width. The original IE box model, also known as quirks mode, includes padding and margin in the width. So the width of your content would be 100% - 40px in this case. This is why you see two different behaviors. As far as I know there is no solution for this there is however a work around by setting the width to say 98% and the padding to 1% on each side.
#Domenic this does not work. width auto does nothing more then the default behavior of that element because the initial value of width is auto ( see page 164, Cascading Style Sheets Level 2 Revision 1 Specification). Assigning a display of type block does not work either, this simply tell the browser to use a block box when displaying the element and does not assign a default behavior of taking as much space as possible like a div does ( see page 121, Cascading Style Sheets Level 2 Revision 1 Specification). That behavior is handled by the visual user agent not CSS or HTML definition.
i believe you can counter the overflow with a negative margin. ie
margin: -1em;
The default padding and border will prevent your textbox from truly being 100%, so first you have to set them to 0:
input {
background: red;
padding: 0;
width: 100%;
border: 0; //use 0 instead of "none" for ie7
}
Then, put your border and any padding or margin you want in a div around the textbox:
.text-box {
padding: 0 20px;
border: solid 1px #000000;
}
<body>
<div id="x">
<div id="y">x</div>
<div class="text-box"><input type="text"/></div>
</div>
</body>
This should allow your textbox to be expandable and the exact size you want without javascript.
To make the input fill up width of parent, there're 3 attributes to set: width: 100%, margin-left: 0, margin-right: 0.
I just guess zero margin setting can help, and I had tried it, however I don't know why margin (left and right; of course top and bottom margins don't affect here) should to be zero to make it works. :-)
input {
width: 100%;
margin-left: 0;
margin-right: 0;
}
Note: You may need to set box-sizing to border-box to make sure the padding don't affect the result.
I use to solve this with CSS-only tables. A little bit long example but
important for all who wants to make entry screens for large amount of fields
for databases...
// GH
// NO JAVA !!! ;-)
html {
height: 100%;
}
body {
position: fixed;
margin: 0px;
padding: 0px;
border: 2px solid #FF0000;
width: calc(100% - 4px);
/* Demonstrate how form can fill body */
min-height: calc(100% - 120px);
margin-top: 60px;
margin-bottom: 60px;
}
/* Example how to make a data entry form */
.rx-form {
display: table;
table-layout: fixed;
border: 1px solid #0000FF;
width: 100%;
border-collapse: separate;
border-spacing: 5px;
}
.rx-caption {
display: table-caption;
border: 1px solid #000000;
text-align: center;
padding: 10px;
margin: 10px;
width: calc(100% - 40px);
font-size: 2.5em;
}
.rx-row {
display: table-row;
/* To make frame on rows. Rows have no border... ? */
box-shadow: 0px 0px 0px 1px rgb(0, 0, 0);
}
.rx-cell {
display: table-cell;
margin: 0px;
padding: 4px;
border: 1px solid #FF0000;
}
.rx-cell label {
float: left;
border: 1px solid #00FF00;
width: 110px;
padding: 4px;
font-size: 1em;
text-align: right;
font-family: Arial, Helvetica, sans-serif;
overflow: hidden;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.rx-cell label:after {
content: " :";
}
.rx-cell input[type='text'] {
float: right;
border: 1px solid #FF00FF;
padding: 4px;
background-color: #eee;
border-radius: 0px;
font-family: Arial, Helvetica, sans-serif;
font-size: 1em;
/* Fill the cell - but subtract the label width - and litte more... */
width: calc(100% - 130px);
overflow: hidden;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
input[type='submit'] {
font-size: 1.3em;
}
<html>
<meta charset="UTF-8">
<body>
<!--
G Hasse, gorhas at raditex dot nu
This example have a lot of frames so we
can experiment with padding and margins.
-->
<form>
<div class='rx-form'>
<div class='rx-caption'>
Caption
</div>
<!-- First row of entry -->
<div class='rx-row'>
<div class='rx-cell'>
<label for="input11">Label 1-1</label>
<input type="text" name="input11" id="input11" value="Some latin text here. And if it is very long it will get ellipsis" />
</div>
<div class='rx-cell'>
<label for="input12">Label 1-2</label>
<input type="text" name="input12" id="input12" value="The content of input 2" />
</div>
<div class='rx-cell'>
<label for="input13">Label 1-3</label>
<input type="text" name="input13" id="input13" value="Content 3" />
</div>
<div class='rx-cell'>
<label for="input14">Label 1-4</label>
<input type="text" name="input14" id="input14" value="Content 4" />
</div>
</div>
<!-- Next row of entry -->
<div class='rx-row'>
<div class='rx-cell'>
<label for="input21">Label 2-1</label>
<input type="text" name="input21" id="input21" value="Content 2-1">
</div>
<div class='rx-cell'>
<label for="input22">Label 2-2</label>
<input type="text" name="input22" id="input22" value="Content 2-2">
</div>
<div class='rx-cell'>
<label for="input23">Label 2-3</label>
<input type="text" name="input23" id="input23" value="Content 2-3">
</div>
</div>
<!-- Next row of entry -->
<div class='rx-row'>
<div class='rx-cell'>
<label for="input21">Label 2-1</label>
<input type="text" name="input21" id="input21" value="Content 2-1">
</div>
<div class='rx-cell'>
<label for="input22">Label 2-2</label>
<input type="text" name="input22" id="input22" value="Content 2-2">
</div>
<div class='rx-cell'>
<label for="input23">Label 2-3</label>
<input type="text" name="input23" id="input23" value="Content 2-3">
</div>
</div>
<!-- And some text in cells -->
<div class='rx-row'>
<div class='rx-cell'>
<div>Cell content</div>
</div>
<div class='rx-cell'>
<span>Cell content</span>
</div>
</div>
<!-- And we place the submit buttons in a cell -->
<div class='rx-row'>
<div class='rx-cell'>
<input type="submit" name="submit1" value="submit1" />
<input type="submit" name="submit2" value="submit2" />
</div>
</div>
<!-- End of form -->
</div>
</form>
</body>
</html>