CSS stretch textbox to fill remaining space - html

I have a div with a label and a textbox and I simply want the textbox to stretch out to fill the remaining space on the page. I know that the 100% width doesn’t include any padding or margin values so I’ve added that to textbox and div. I’ve searched many similar topics, but my textbox always drops to a new line below the label. What am I missing? I'm placing my css inline just for testing purposes.
<div style="padding-right:10px;">
<asp:Label ID="Label1" runat="server" Text="Label" style="float:left; width:150px; display:inline-block"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server" style="display:inline-block; width:100%; padding-right:0"></asp:TextBox>
</div>

You can use calc() + box-sizing: border-box; for known width label.
.container label,
.container input[type="text"] {
float: left;
}
.container label {
width: 150px;
}
.container input[type="text"] {
width: calc(100% - 150px);
box-sizing: border-box;
}
<div class="container">
<label>Label Example</label>
<input type="text">
</div>
Or, use flexbox, that makes it very easy also works for dynamic width.
.container {
display: flex;
align-items: flex-start;
}
.container input[type="text"] {
flex: 1; /*take all the available space*/
}
<div class="container">
<label>Label Example</label>
<input type="text">
</div>
If you need to support legacy browsers, try using CSS table. Note, to make it work I added a span tag around the input box.
.container {
display: table;
width: 100%;
}
.container label,
.container span {
display: table-cell;
}
.container label {
white-space: nowrap;
}
.container span {
width: 100%;
}
.container input[type="text"] {
width: 100%;
box-sizing: border-box;
}
<div class="container">
<label>Label Example</label>
<span><input type="text"></span>
</div>

Related

Aligning elements horizontally adjacent that are in different grid cells with CSS Grid and Flexbox

Currently I'm using a mixture between grid and flexbox to try and achieve a layout for a form.
I would like both input elements to horizontally lineup without setting a height on them. If I were to apply for padding on the text input, the range should continue to vertically center with the input adjacent to it.
Additionally I would like the label elements to also remain horizontally aligned too.
Please suggest solutions that DO NOT require changing the markup or using Javascript.
Currently what I have:
What I'm trying to achieve:
I know I could apply a fixed height or padding on the range to align it but I'm trying to make this as fluid as possible.
HTML:
<form class="grid">
<div class="group">
<label for="input-1">Label 1</label>
<input type="text" id="input-1" placeholder="placeholder" />
</div>
<div class="group">
<label for="input-2">Label 2</label>
<div class=range-wrapper>
<input type="range" id="input-2" placeholder="placeholder" />
<output>0</output>
</div>
</div>
</form>
SCSS:
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2rem;
}
.grid {
width: 80%;
max-width: 960px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 40px 10px;
padding: 50px;
background: #ccc;
}
.group {
display: flex;
flex-direction: column;
margin-top: auto;
label {
margin-bottom: 10px;
}
}
input {
font-size: inherit;
&[type="text"] {
padding: 14px;
}
&[type="range"] {
width: 100%;
}
}
.range-wrapper {
display: flex;
align-items: center;
output {
padding: 10px;
}
You can also check out the codepen here.
Many thanks!
** EDIT **
Should support multiline labels, if the label wraps multiple lines, elements should still horizontally align.
Multiline label example: Codepen
try this for your "group" class.
(or use a new class for that element with this styling)
.group {
display: flex;
flex-direction: column;
justify-content: center;
label {
margin-bottom: 10px;
}
}

Flexbox not expanding with content

I am trying to build a basic messenger view on a mobile screen. So there is a header at the top, a scrollable list of messages in the middle, and a bar at the bottom with a textarea and button to send a new message.
I am using an autosize plugin to makes the textarea expand as a user types their message. The problem is that as it changes the height property, it will start to overflow the height of the container that it is in, instead of that container expanding to take up more room.
A working sample is here: https://codepen.io/jwynveen/pen/RJdWLB?editors=1100#0
#container {
width: 412px;
height: 660px;
border: solid 2px black;
display: flex;
flex-direction: column;
}
#container h1 {
border-bottom: solid 1px gray;
margin-bottom: 0;
padding: 1rem;
}
#container #message-list {
flex-grow: 1;
flex-shrink: 1;
overflow-y: scroll;
}
#container #message-list .message {
margin: 1rem;
padding: 1rem;
border: solid 1px gray;
}
#container #message-input-bar {
display: block;
}
#container #message-input {
padding: 1rem;
display: flex;
border-top: solid 2px red;
}
#container #message-input textarea {
flex-grow: 1;
}
<html>
<div id="container">
<h1>My Header</h1>
<div id="message-list">
<div class="message">This is a dummy message.</div>
<div class="message">This is a dummy message.</div>
</div>
<div id="message-input">
<textarea style="height: 100px"></textarea>
<button id="send">Send</button>
</div>
</div>
</html>
If there are no messages in the center area, the textarea makes its container expand as expected. But once the center area has enough to scroll, the textarea starts to overflow.
Found a fix based on the suggestion by #vaishali-kapadia. I wrapped the #message-input with another div so that the added div is display:block and the existing one maintains the flexbox layout.
Changed from:
<div id="message-input">
<textarea style="height: 100px"></textarea>
<button id="send">Send</button>
</div>
To:
<div id="message-input-bar">
<div id="message-input">
<textarea style="height: 100px"></textarea>
<button id="send">Send</button>
</div>
</div>
With the added CSS (though not necessary since the div is display:block by default):
#message-input-bar {
display:block;
}
Solution 1
You have applied manual height to container. so it stops there after reaching that particular height.
Instead apply height: auto; so that container can expand as per the content
See this codepen -
https://codepen.io/vaishalik3/pen/QxoyMd?editors=1100#0
Solution 2 -
In case you want scrollbar as it is.
Apply display: block; instead of flex to #message-input
width: 100%; or as per your need to textarea
See this codepen - https://codepen.io/vaishalik3/pen/ERMPLd?editors=1100#0
Solution 3
Apply display: grid; to .container
display: flex; to #message-input
See this codepen - https://codepen.io/vaishalik3/pen/RJdqzq?editors=1100#0
Hope this helps :)
Remove
style="height: 100px"
from your textarea and provide height:100% to CSS.
https://codepen.io/anon/pen/ZRPQBX?editors=1100#0

Using "display:inline-block" but my DIV is still appearing on a new line

I have two block elements that I would like to be on the same horizontal line. One is a FORM and the other is a DIV.
<div id="miningArea">
<form id="curWorkForm">...</form>
<div id="buttonDescription">
To begin, click thde "Start" button.
</div>
</div>
I thought adding display:inline-block was the key to keeping the elements on the same line. But when I add
#buttonDescription {
display: inline-block;
}
My text element still appears beneath my FORM element -- https://jsfiddle.net/5j57hkLr/6/ . How can I get that other DIV element to appear on the same line?
When there is a lot of text, you have to limit the width of inline-block elements by applying width settings to them which allow both elements to fit into one line, for example width: 50% and width: 45%
Otherwise they will by default expand according to the text, which will result in 100% width when there's enough text to fill a full line.
These are the the 3 ways ways I would think about approaching this:
(Here is a your JSFiddle back with some changes.)
1:
.wrapper {
overflow: hidden;
border: red dashed 1px;
/* For Testing*/
}
.style {
margin: 0;
padding: 10px;
float: left;
}
<div class="wrapper">
<form>
<input class="style" placeholder="Enter Value" />
</form>
<button class="style">Submit</button>
</div>
2: Responsive
* {
box-sizing: border-box;
margin: 0;
}
input, button {padding:10px;}
input {width: 100%;} /* replace "input" with "input , button" if you want the button to take up full with*/
.column {
float: left;
width: 50%;
border: red dashed 1px; /*For Testing*/
}
.row:after {
content: "";
display: table;
clear: both;
}
#media screen and (max-width: 600px) {
.column {
width: 100%;
}
}
<meta name="viewport" content="width=device-width, initial-scale=1">
<div class="row">
<div class="column">
<form>
<input class="style" placeholder="Enter Value" />
</form>
</div>
<div class="column">
<button class="style">Submit</button>
</div>
</div>
3:
* {
box-sizing: border-box;
margin: 0;
}
#mainWrapper {
overflow: hidden;
display: inline-block;
}
button,
input {
width: 100%;
padding: 10px;
}
.formWrap {
float: left;
width: 300px;
}
.btnWrap {
float: left;
width: 100px;
}
<div id="mainWrapper">
<div class="formWrap">
<form>
<input placeholder="Enter Value" />
</form>
</div>
<div class="btnWrap">
<button>Submit</button>
</div>
</div>
add this to your css
#buttonDescription,form {
display: inline-block;
vertical-align:middle;
}
Inorder for two or more elements to be on same line, all the elements should be made display: inline or inline blocks
Here is a working example: https://jsfiddle.net/6wjftgf2/2/
#buttonDescription,form {
display: inline-block;
}
<div id="miningArea">
<form id="curWorkForm"><input placeholder="My Form"/></form>
<div id="buttonDescription">
<button>My Button</button>
</div>
</div>
You can also use flex for this work the code is as follows
.miningArea
{
display: flex;
justify-content: center;
flex-wrap: wrap;
align-items: center;
}
form
{
width: 60%;
}
div
{
width: 40%;
}
.miningArea {
display: flex;
flex-wrap: wrap;
}
form { width: 60%; }
div { width: 40%; }

Add items one under another when space available Flexbox

I have the following issue, I have forms with inputs inside flex-wrap, but in few forms I have <textarea rows="5"></textarea> and it takes more height than an input field. Is it possible to have the following structure inside flex-wrap:
Have these 2 input fields one below the other, but in their .holder divs?
https://jsfiddle.net/by06rreq/
CSS:
.flex {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.holder {
width: 30%;
}
input, textarea {
width: 100%;
}
.holder.textarea {
width: 65%;
}
HTML:
<div class="flex">
<div class="holder textarea">
<textarea name="test" rows="5"></textarea>
</div>
<div class="holder">
<input type="text">
</div>
<div class="holder">
<input type="text">
</div>
</div>
You can see.. Do you want like this. I have tried with multi-layout css. through column-count
.flex {
column-count: 2;
column-gap: 0;
}
.holder {
width: 50%;
margin-bottom: 15px;
}
input, textarea {
width: 100%;
}
.holder.textarea {
width: 65%;
margin-bottom: 0;
}
<div class="flex">
<div class="holder textarea">
<textarea name="test" rows="5"></textarea>
</div>
<div class="holder">
<input type="text">
</div>
<div class="holder">
<input type="text">
</div>
</div>
I'm not 100% sure on what you're asking for & I can't comment due to lack of reputation so I have no option to make a guess in an answer.
So you'd like a similar layout to this?
-TextArea-
-Input-
-Input-
You could apply display: block and width: 100% to your .holder class, and then adjust the size of your input controls through their relevant css classes.
If I've completely misunderstood what you're trying to achieve, just comment and I'll see if I can help you further :)
EDIT:
After reading your recent comments I can offer another solution. however, it isn't using flex.
.block {
width: 100%:
display: block;
}
.textarea {
display: inline-block;
width: 30%;
}
.textarea textarea {
width: 100%;
}
.holder {
display: inline-block;
vertical-align: top;
}
.holder input {
display: block;
vertical-align: top;
}
<div class="block">
<div class="textarea">
<textarea class="textarea" name="test" rows="5"></textarea>
</div>
<div class="holder">
<input type="text">
<input type="text">
</div>

Aligning without a table

So, I understand that tables are the spawn of satan. How should I align this without a table?
I have a bunch of input fields, each with a label to the left of it, and I would like the left side of the input fields to be aligned. Bad ascii art follows:
name ________________
date of birth ________________
Shakespeare villain I would like to be ________________
favo(u)rite do(gh)nut ________________
pet's blood group ________________
mother's maiden name ________________
favo(u)rite Led Zeppelin track ________________
I don't need exact code, just to be told how to do it.
This page looks incredibly helpful, but how do I do it with the text & input fileds?
Maybe a <div> with the text floating right and the input field vertically aligned at 50% ?
Try display: table-cell;
.wrapper {
display: table;
}
.inner {
display: table-cell;
}
#wrapper div.td1 {
text-align: right;
padding: 0;
margin: 0;
vertical-align: middle;
/* added incase of too long label text */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#wrapper div {
width: 50%;
display: inline-block;
text-align: left;
padding-left: 5px;
margin-right: -5px;
}
#wrapper {
width: 100%;
line-height: 1.5em;
}
<div id="wrapper">
<div class="td1">name</div><div><input type="text"></div>
<div class="td1">date of birth</div><div><input type="text"></div>
<div class="td1">Shakespeare villain I would like to be</div><div><input type="text"></div>
<div class="td1">favo(u)rite do(gh)nut</div><div><input type="text"></div>
<div class="td1">pet's blood grou </div><div><input type="text"></div>
<div class="td1">mother's maiden name</div><div><input type="text"></div>
<div class="td1">favo(u)rite Led Zeppelin track</div><div><input type="text"></div>
</div>
The best thing you can get here is to recreate table layout with different DOM elements plus some display:table-*** declarations :
div.parent { display:table; }
div.parent > row { display:table-row; }
div.parent > row > * { display:table-cell; }
div.parent > row > label { text-align:right; padding: 0 0.25em; }
div.parent > row > label::after { content:":"; }
<div class="parent">
<row>
<label>name</label>
<p>_____________</p>
</row><row>
<label>date of birth</label>
<p>_____________</p>
</row><row>
<label>Shakespeare villain I would like to be</label>
<p>_____________</p>
</row><row>
<label>favo(u)rite do(gh)nut</label>
<p>_____________</p>
</row><row>
<label>pet's blood group</label>
<p>_____________</p>
</row><row>
<label>mother's maiden name</label>
<p>_____________</p>
</row><row>
<label>favo(u)rite Led Zeppelin track</label>
<p>_____________</p>
</row>
</div>
A touch of flex
This may have some limitations depending on the rest of your layout; treat it as an experiment.
To reduce the amount of HTML used along with a tiny amount of CSS, we can play around with a flexbox layout.
Compatibility: IE 11+ and all modern browsers
The <form> container is given display: flex and, to align each label in the center of its input, align-items: center. flex-wrap: wrap is used to form rows.
The inputs and labels are given flex: 1 1 50%. This gives them an initial width of 50% which will then grow and shrink with the container. The initial value of 50% can be changed to make the inputs wider or smaller, as long as the label and inputs initial values add up to 100%.
The rows are spaced out with margin: 5px 0 5px on the inputs to provide a top and bottom margin. The top and bottom margin value should remain the same so the labels are centered.
box-sizing: border-box incorporates border and padding into the elements width and height
A guide to Flexbox is very useful.
Full Example
The form can be nicely controlled with min-width and max-width to maintain some flexibility.
* {
box-sizing: border-box;
}
form {
display: flex;
flex-wrap: wrap;
align-items: center;
max-width: 600px;
min-width: 300px;
}
label {
text-align: right;
flex: 1 1 50%;
padding-right: 10px;
}
input {
flex: 1 1 50%;
margin: 5px 0 5px;
}
<form>
<label for="label1">This is a really long label</label>
<input id="label1" type="text">
<label for="label2">Smaller label</label>
<input id="label2" type="text">
<label for="label3">Tiny</label>
<input id="label3" type="text">
</form>