Where do inputs get their extra width from? - html

I am trying to create a button div and input to all be 80% the width of their container.
However the input is always bigger than 80%. Why is this? Do I need to use calc in some way to get it to 80%.
Even when setting the padding to 0px it is still bigger:
https://jsfiddle.net/0rcv1ypb/
<input/>
<button></button>
<div></div>
input{
display: block;
width: 80%;
}
button{
display: block;
width: 80%;
height: 20px;
}
div{
width: 80%;
height: 20px;
background: black;
}
As a side question: the default width for input appears to be 145px. Where does this value come from as it is not in the agent style sheet.

Because the default browser styling is box-sizing: content-box.
Reset it and all elements get the same width as expected, even with different paddings/borders.
* {
box-sizing: border-box;
}
input{
display: block;
width: 80%;
}
button{
display: block;
width: 80%;
height: 20px;
}
div{
width: 80%;
height: 20px;
background: black;
}
<input/>
<button></button>
<div></div>
Take a look at the box-model and here.

Related

How to alter my CSS to ensure that the textarea height always matches the height of its div container?

I have a textarea inside a div, and I wish for the text area height to match the height of the div container.
Currently, the width fits perfectly, however the textbox (which begins empty) only fills about 20% of the div height.
And when an ajax call grabs some text and populates the textarea, the textarea height remains at about 20% of the div and provides a scroll bar.
How can I alter my CSS to ensure that the textarea height always matches the height of its div container?
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 5px auto;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBoxDiv {
width: 90%;
min-height: 50%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
You need to explicitly set a height of the parent container (whether that is in px or rem etc) - that way the height: 100% of the textarea will fill to the container.
The expand on text content cannot be done with simple css - you need js to determine the heaight of the content and adjust the parent container accordingly.
The only way tyou can keep height: 100% on the parent container is its ancestor has a height set (eg 100vh) - that way the browser can determine the height of each DOM element and size the text area accrodingly.
UPDATE - I have added a js function to automatiucally increae the height of the parent container on the input. (the textarea autoincreases in height since it is 100% of the parentThis will need massaging - but when you type into the textarea the height will auto expand.
function setHeight(element) {
const container = document.getElementById("answerBoxDiv");
const height = element.scrollHeight;
if(height > 100) {
container.style.height = (element.scrollHeight)+"px";
}
}
#answerBoxDiv {
width: 90%;
height: 100px; **// this is needed - but can be in px / rem / vh or other but NOT % unless its parent has its height set.**
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
resize: vertical;
overflow: hidden
}
<div id="answerBoxDiv">
<textarea id="answerBox" oninput="setHeight(this)"></textarea>
</div>
You can use the CSS height: 100%; property on the textarea element to make it fill the entire height of its parent container, the #answerBoxDiv. Additionally, you can remove the min-height property from the #answerBoxDiv to make sure the container's height is always equal to the height of its content.
Here's the updated CSS:
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 0;/*keep it zero*/
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBoxDiv {
width: 90%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 0px;/*keep it zero*/
font-size: 10px;
text-align: left;
position: relative;
}
And the updated HTML:
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
Percentage height does not work with a min-height parent, you would either need to give your parent a height or you could use flex:
html,
body {
height: 100%;
margin: 0;
}
#answerBox {
flex-grow:1;
width: 100%;
box-sizing: border-box;
margin: 5px auto;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBoxDiv {
width: 90%;
min-height: 50%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
display: flex;
flex-direction: column;
}
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
You can try this
#answerBox {
height: 100%;
resize: none;
}
try keeping the min-height of the textarea as 100% or nearby or try using
object-fit: contain(or cover) on your text area
Give specific height for #answerBoxDiv parent div. So you will get appropriate height for this div.
<div class="parent-div" style="height: 100%;">
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
</div>
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 0;
padding: 5px;
font-size: 10px;
text-align: left;
resize: none;
border: none;
}
#answerBoxDiv {
width: 90%;
min-height: 50%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 0;
position: relative;
}

Is it possible to set the width of an element based on the height of the parent element? How to do this?

I'm researching a few things about CSS and I had that doubt. I searched about it in other posts on the web, but i don't find yet.
If i have some img with height equals 80% of its parent div (its width will also be the same), how can i set the input's width to fill in the remaining space.
The code snippet might look like the one below:
.forms {
display: block;
width: 70%;
height: 36px; /*This height change for different devices*/
padding: 2px;
border-style: solid;
border-width: 1px;
border-radius: 4px;
outline: 0;
font-size: 14px;
line-height: 30px;
}
#inputSearch {
position: relative;
width: 80%;
display: inline-block;
border: 0;
outline: 0;
}
#imgSearch {
position: relative;
float: right;
height: 80%;
top: 10%;
right: 6px;
}
<div id="parent" class="forms">
<input id="inputSearch" type="text">
<img id="imgSearch" src="https://www.freeiconspng.com/uploads/search-icon-png-21.png">
</div>
In my case, i can not change the parent div attributes, like display, because i am using a project pattern. There are other elements next to parent div. Hence, i want to change only the children attributes.
I would appreciate if someone guide me about that.
This could be a possible solution if i understood right the problem.
Try this using flex properties :
#parent{
display : flex;
//optional alignment
align-items: center;
}
#inputSearch{
flex-grow: 1;
}
#imgSearch{
width: 80%;
height: 80%;
}

How to make <input> and <a> element inline in a <div>

I have a div containing an input and an a element:
.wrapper {
width: 300px;
display: inline-block;
}
.custom-input {
display: block;
width: 100%;
}
.button {
width: 20px;
height: 20px;
background-color: #ccc;
display: block;
}
<div class="wrapper">
<input class="custom-input" type="text" />
<a class="button"></a>
</div>
Here's a jsfiddle.
I want my input and my button inline. The input with button always has 100% width of the wrapper. In some cases, I want to remove the button. The input then has 100% width of the wrapper div.
It is only inline when I use inline-flex for the wrapper. But I want it to be able to run on old browsers (IE 8-9), and I want my input and my element to always have 100% width of wrapper.
How can I do it?
Using width: 100% on your input will make it take all the horizontal space available, pushing the button to the line below.
This should work :
.wrapper{
width: 300px;
display: inline-block;
}
.custom-input{
display: inline-block;
}
.button{
width: 20px;
height: 20px;
background-color: #ccc;
display: inline-block;
}
Here's the updated jsfiddle : http://jsfiddle.net/k6yhtf92/3/
try to use display: inline-block instead display:block
updated css
.wrapper{
width: 300px;
display: block;
}
.custom-input{
display: inline-block;
}
.button{
width: 20px;
height: 20px;
background-color: #ccc;
display: inline-block;
}

Set a responsive layout for 4 divs that are in a footer. Needs to stay centered on all sides relative the edges of the footer

Within a footer there are 4 small boxes (created with divs that have a red border around them) and they all need to be made responsive to the width of the browser window as it is re-sized. They need to be centered and have an equal percentage space in between each other no matter what the window size is. Boxes have to stay 100px by 100px.
Here is a rough illustration of what I mean: http://s14.postimg.org/58xunsv0h/example_of_boxes.png
#footer {
width: 100%;
clear: both;
text-align: center;
background-color: black;
opacity: 0.7;
height: 200px;
}
#fbox1 {
border: 5px outset #ea2f2f;
width: 100px;
height: 100px;
position: inline-block;
float: left;
}
#fbox2 {
border: 5px outset #ea2f2f;
width: 100px;
height: 100px;
position: inline-block;
float: left;
}
#fbox3 {
border: 5px outset #ea2f2f;
width: 100px;
height: 100px;
position: inline-block;
float: left;
}
#fbox4 {
border: 5px outset #ea2f2f;
width: 100px;
height: 100px;
position: inline-block;
float: left;
}
<body>
<div id="footer">
<div id="fbox1">
</div>
<div id="fbox2">
</div>
<div id="fbox3">
</div>
<div id="fbox4">
</div>
<div>
</body>
You have two very simple ways to do that.
If you are targeting modern browsers, then you could make use of the CSS3 flex model. This is the simplest method. You won't have to change anything in your markup. Of course, I would suggest using the footer tag instead of div, because it semantically is a footer.
In this example, I am omitting browser prefixes for two reasons: (1) brevity of this snippet, and (2) most modern browsers now don't need prefixes for this. This example snippet works perfectly as-is in IE-11, FF-34 and GC-39.
The trick is to use the justify-content: space-around; property to distribute the spacing evenly between the divs. Remember, that space-around will cause the space before the first div and space after the last div to be half of the spacing between divs. This will cause, the spacing after the last div to be large because of the size of the div. To mitigate this, use margin: auto.
Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
And: http://dev.w3.org/csswg/css-flexbox/#propdef-justify-content
Fiddle: http://jsfiddle.net/abhitalks/j8fpp0so/2/
Snippet:
footer {
background-color: #000; opacity: 0.7;
height: 200px;
display: flex;
justify-content: space-around; /* this is important */
align-items: center; text-align: center;
}
footer > div {
border: 1px solid red;
width: 100px; height: 100px;
margin: 0 auto; /* this is important */
}
<footer>
<div></div>
<div></div>
<div></div>
<div></div>
<footer>
If you really need to support older browsers i.e. back up to IE-8, FF-31, GC-31 etc., then you could make use of display:table and display:table-cell to achieve that. This is also very simple, but you would have to change your markup a little bit. Just wrap your inner-divs inside wrapper-divs. Apply display to the footer container and the wrapper-divs.
The trick here is to use the display:table-cell on the wrapping divs which, will cause them to evenly distribute. But, this will cause them to stretch. To mitigate this, we apply vertical-align to the wrapper divs and also a margin: auto to the inner divs.
Fiddle: http://jsfiddle.net/abhitalks/Lvysyuuh/
Snippet:
#footer {
background-color: #000; opacity: 0.7;
width: 100%; height: 200px;
display: table; /* this is important */
}
#footer > div {
display: table-cell; /* this is important */
text-align: center; vertical-align: middle; /* this is important */
}
#footer > div > div {
border: 1px solid red;
width: 100px; height: 100px;
margin: 0 auto; /* this is important */
}
<div id="footer">
<div><div></div></div>
<div><div></div></div>
<div><div></div></div>
<div><div></div></div>
<div>
//HTML BLOCK
<div id="footer">
<div class="fbox"></div>
<div class="fbox"></div>
<div class="fbox"></div>
<div class="fbox"></div>
<div>
//CSS BLOCK
#footer {
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items:center;
width: 100%;
background: black;
opacity: 0.7;
height: 200px;
}
.fbox {
display: flex;
display: -webkit-flex;
flex: 1;
-webkit-flex: 1;
min-height: 100px;
min-width: 100px;
max-width: 100px;
max-height: 100px;
margin: 0 auto;
border: 5px outset #ea2f2f;
}
Alternative to flex box if you can't use that for compatibility reasons:
The formula for the width of the space between blocks is (footer_width - 4*box_width)/5. Basically you've got a percentage width minus a fixed width: footer_width/5 - 4*box_width/5 ->
20% of footer width - 4*110px/5 -> 20% - 88px. Note the boxes actually take up 110px because of the border. We can do this at least two ways:
Using float:
You want 20% - 88px between each box. Float each box to the left with a margin-left of 20%. Then pull the boxes to the left by setting a negative right margin on each box. this does not effect the first box, but does make the space between boxes correct, so position all of them relatively and move them over 88px to the left.
#footer {
width: 100%;
clear: both;
background-color: black;
opacity: 0.7;
height: 200px;
box-sizing: border-box;
position: relative;
}
div div {
border: 5px outset #ea2f2f;
width: 100px;
height: 100px;
float:left;
margin-left:20%;
margin-right:-88px;
position:relative;
left:-88px;
top:45px;
}
This way feels a little fragile to me, but I can't immediately see why...
Using absolute positioning:
You want 20% - 88px between each box. Start with the first box. Move it over 20%, then back left 88px by using the left and margin-left properties. Next box we need to move the same, but from the right edge of the first box, so we need to move it over 20% - 88px + 110px to get to the right edge of the first box, then the +20% - 88px again, giving 40% - 66px. Repeat for each box. You can see the pattern below. Note the position:relative on #footer.
#footer {
width: 100%;
clear: both;
background-color: black;
opacity: 0.7;
height: 200px;
box-sizing: border-box;
position: relative;
}
div div {
border: 5px outset #ea2f2f;
width: 100px;
height: 100px;
position: absolute;
top:45px;
}
#fbox1 {
left: 20%;
margin-left: -88px;
}
#fbox2 {
left: 40%;
margin-left: -66px;
}
#fbox3 {
left: 60%;
margin-left: -44px;
}
#fbox4 {
left: 80%;
margin-left: -22px;
}
You might also be able to use inline-block with text-align:justify as seen here: "text-align: justify;" inline-block elements properly?
Hope this helps!
EDIT:
Just noticed your req that they be vertically centered as well. In this case, because you have a fixed height container and fixed height boxes, in both cases above you just have to nudge each box down by (200px - 110px)/2 = 45px which can be done with top:45px;.

css: let input field fill the space left

I'm trying to let a label and an input field fill the whole width of a from. Here is my attempt. This is the HTML
<form>
<p>
<label>Username:</label>
<input/>
</p>
</form>
and CSS
form {
widht: 400px height: 500px;
background-color: lightgrey;
}
label {
float: left;
}
input {
width: 100%;
box-sizing: border-box;
}
When I put a with: 100% in the input field it moves below the label and without the width it is too small. Any suggestions ?
Use a wrapper element around your input and set overflow: hidden; (Make sure you use a block level element, if you are using span than declare display: block; in your CSS)
Demo
<label>Blah Blah</label>
<div><input type="text" /></div>
label {
float: left;
}
div {
overflow: hidden;
}
input[type=text] {
width: 100%;
}
you have to set width attribute properly.
Live Demo
label {
float: left;
width: 15%;
}
input {
width: 83%;
box-sizing: border-box;
}
If you firebug it, you will know that Your border is actually putting some padding to the container p. So, if you just put border to none then you will be good to do.
If you want to use border and dont want the input to go outside the form, then you need to either shorten the width of the input a little and apply border or you give some padding to your form.
Try This CSS
form {
background-color: #D3D3D3;
height: 500px;
width: 400px;
}
form p{
float: left;
position: relative;
width: 100%;
}
label {
float: left;
position: relative;
width: 100%;
}
input {
border:0;
float: left;
height: 20px;
margin: 0 auto;
padding: 0;
position: relative;
width: 100%;
}
Here is the DEMO