A problem that seems to pop up again and again in my projects is styling form elements and links to have the same height.
Here's an simple example (fiddle):
HTML:
<select><option>one</option></select>
<input type="text">
<button>foo</button>
test
CSS:
select,
input,
button,
a {
padding: 0.5rem;
margin: 0.25rem;
border: 1px solid red;
}
All elements receive the exact same styling with a padding, a margin and a border. But they all differ slightly in height and I don't really understand why.
Can someone
explain where the difference comes from? Chrome inspector tells me that the actual inner element of each has different sizes - shouldn't it be the same?
tell me what minimal changes I need to do to my CSS to achieve what I want without styling each of the elements slightly different? My goal is to pick the padding, margin and border sizes freely (using variables) and still have consistent heights.
Updated fiddle with solution
The minimal version:
You'll need to add the additional rules like below:
select,
input,
button,
a {
padding: 0.5rem;
margin: 0.25rem;
border: 1px solid red;
display: inline-block; /*new*/
font: inherit; /*new*/
}
But that will still not guarantee they receive the same height for certain input types in certain browsers. You can also reset the appearance but I would not recommend to do it globally, unless it's required by design.
-webkit-appearance: none;
appearance: none;
The non-minimal version:
*,
*:before,
*:after {
box-sizing: border-box;
}
::-moz-focus-inner {
border-style: none;
padding: 0;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
height: auto;
}
::-webkit-search-cancel-button,
::-webkit-search-decoration {
-webkit-appearance: none;
}
button,
input,
optgroup,
select,
textarea {
font-family: inherit;
font-size: 1rem;
line-height: 1.15;
margin: 0;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
[type="checkbox"],
[type="radio"] {
padding: 0;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
[type="color"],
[type="date"],
[type="datetime"],
[type="datetime-local"],
[type="email"],
[type="month"],
[type="number"],
[type="password"],
[type="search"],
[type="tel"],
[type="text"],
[type="time"],
[type="url"],
[type="week"],
select,
textarea,
button,
[type="button"],
[type="reset"],
[type="submit"] {
display: inline-block;
vertical-align: middle;
height: calc(2.25rem + 2px);
color: #333;
border: 1px solid #ccc;
border-radius: 3px;
}
[type="color"],
[type="date"],
[type="datetime"],
[type="datetime-local"],
[type="email"],
[type="month"],
[type="number"],
[type="password"],
[type="search"],
[type="tel"],
[type="text"],
[type="time"],
[type="url"],
[type="week"],
select,
textarea {
max-width: 100%;
padding: 0.5rem;
background-clip: padding-box;
background-color: #fff;
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.1);
}
[type="color"]:focus,
[type="date"]:focus,
[type="datetime"]:focus,
[type="datetime-local"]:focus,
[type="email"]:focus,
[type="month"]:focus,
[type="number"]:focus,
[type="password"]:focus,
[type="search"]:focus,
[type="tel"]:focus,
[type="text"]:focus,
[type="time"]:focus,
[type="url"]:focus,
[type="week"]:focus,
select:focus,
textarea:focus {
border-color: rgb(30, 144, 255);
box-shadow: 0 0 2px rgba(30, 144, 255, 0.8);
outline: 0;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
padding: 0.5rem 0.75rem;
background-color: #f7f7f7;
box-shadow: 0 1px 0 #ccc;
cursor: pointer;
-webkit-appearance: button;
}
button:hover,
[type="button"]:hover,
[type="reset"]:hover,
[type="submit"]:hover {
background-color: #fafafa;
border-color: #999;
}
button:focus,
[type="button"]:focus,
[type="reset"]:focus,
[type="submit"]:focus {
border-color: rgb(30, 144, 255);
box-shadow: 0 0 2px rgba(30, 144, 255, 0.8);
outline: 0;
}
button:active,
[type="button"]:active,
[type="reset"]:active,
[type="submit"]:active {
background-color: #eee;
border-color: #999;
box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5);
}
button:disabled,
[type="button"]:disabled,
[type="reset"]:disabled,
[type="submit"]:disabled {
background-color: #f7f7f7;
color: #a0a5aa;
border-color: #ddd;
box-shadow: none;
text-shadow: 0 1px 0 #fff;
cursor: default;
}
select {
-moz-appearance: textfield;
-webkit-appearance: textfield;
}
select::-ms-expand {
display: none;
}
select[multiple],
select[size]:not([size="1"]) {
height: auto;
padding: 0;
}
select[multiple] option,
select[size]:not([size="1"]) option {
padding: 0.5rem;
}
select:not([multiple]):not([size]),
select:not([multiple])[size="1"] {
padding-right: 2rem;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3C/svg%3E") right 0.25rem center no-repeat;
}
textarea {
height: auto;
overflow: auto;
}
<select>
<option>one</option>
</select>
<input type="text" placeholder="text">
<button>foo</button>
Most of the code above doesn't answer the question directly or even unrelated, and it doesn't include the <a> tag. But in a real web application, it's likely end up having more or less the same amount of CSS.
(Tested with Chrome only)
explain where the difference comes from?
It comes from user agent stylesheet which apply different style as default for each tag.
Those styles change according to the browser.
tell me what minimal changes I need to do to my CSS
input, select and button tags have a default font size which doesn't inherit from your body font-size declaration. Set their font-size value to inherit.
input, select, button {
font-size: inherit;
}
a tag is inline by default. Set its value to inline-block.
Also, set its box-sizing value to border-box.
a {
display: inline-block;
box-sizing: border-box;
}
select has a biggest height content because of its the dropdown icon.
You could fix it by removing its default appearance, but I wouldn't recommend it.
select {
-webkit-appearance: none;
}
Demo
body {
font-size: 16px
}
select,
input,
button,
a {
padding: 0.5rem;
margin: 0.25rem;
border: 1px solid red;
vertical-align: top;
}
input,
select,
button {
font-size: inherit;
}
a {
display: inline-block;
box-sizing: border-box;
}
/* Bad practice */
select {
-webkit-appearance: none;
}
<select>
<option>Select</option>
</select>
<input type="text" value="Input">
<button>Button</button>
Link
An other solution would be to use height + line-height properties for centering your elements and give them the same height.
body {
font-size: 16px
}
select,
input,
button,
a {
height: 40px;
line-height: 40px;
display: inline-block;
vertical-align: top;
margin: 0.25rem;
padding: 0 0.5rem;
border: 1px solid red;
font-size: inherit;
box-sizing: border-box;
}
<select>
<option>Select</option>
</select>
<input type="text" value="Input">
<button>Button</button>
Link
1. From what I understand, the CSS specification for form elements is very loose, so it can be difficult to apply styles at the same time to many different kinds of form elements. Because of this, these different elements all apply your style rules differently.
2. I was able to make the elements all have the same height with one more CSS rule inside the second set of selectors for your form elements:
body {
font-size: 16px;
}
select,
input,
button,
a {
padding: 0.5rem;
margin: 0.25rem;
border: 1px solid red;
font: 1rem "Helvetica", sans-serif;
}
You could change this font to whatever you like and it should still work. What this style primarily accomplishes is to "normalize" everything, especially the "a" element. The "a" element appears to want to keep its initial font-family and some form of its initial font-size. So, with the font style, you can make sure every element is inheriting the body's font size with the 1rem and that each element has a consistent font.
I have a project to create a website designed in PhotoShop. I want to create a to textbox in HTML and CSS which looks like this:
As you can see, there is no problem with the background or fonts; the problem is the textbox. How can I create textboxes with these curves?
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
div {
background: #444;
direction: rtl;
width: 300px;
padding: 20px;
}
label {
width: 100%;
color: #fff
}
input {
border-radius: 0 2em;
padding: 0 10px;
width: 100%;
border: none;
line-height: 2em;
margin-bottom: 20px;
}
textarea {
border-radius: 0 4em;
padding: 0 10px;
width: 100%;
border: none;
line-height: 2em;
margin-bottom: 20px;
}
input[type="submit"] {
max-width: 100px;
}
<div class="wrapper">
<label>Name</label>
<input type="text" />
<label>Email</label>
<input type="text" />
<label>Message</label>
<textarea></textarea>
<input type="submit" value="Submit" />
</div>
This is how to get the shape in your image. You will need to learn a bit about border-radius.
The following is an example:
div#test {
border: thin solid #666;
width: 8em;
height: 2em;
border-radius: 0 2em 0 2em;
}
<div id="test"> </div>
The border-radius property is responsible for rounding corners. It can be very sophisticated, but the simple one here will do the job. You will just need to adjust some of the values.
The four values in the border-radius property represent the radius of the individual borders, clockwise from the top-left corner.
I have the fiddle here: https://jsfiddle.net/ufLpqdtj/
My problem is trying to get my search box and button to always sit full width on the page regardless of the device it is running on.
In Javascript I could always make the text box width 100% minus the pixel width of the button (the button is always the same size) but I feel as if im missing something and that it can be done natively in CSS.
Any thoughts or suggestions?
#commonSearchContainer {
display: block;
clear: both;
width: 100%;
position: relative;
}
#commonSearchTerm {
width: 100%;
margin: 25px 0px 0px 0px;
padding: 5px;
border: 1px solid #999999;
height: 35px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.common-search-term-wrapper {
width: 90%;
display: inline-block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.common-search-button {
background-color: #E9700D;
border: 1px solid #ccc;
display: inline-block;
margin: 25px 0px 0px 10px;
width: 80px;
color: #fff;
padding: 7px;
font-style: italic;
cursor: pointer;
}
<div id="searchSection" class="common-search-section">
<div class="common-search-term-wrapper">
<input id="commonSearchTerm" type="text" autocomplete="off" class="common-search-term">
</div>
<div id="commonSearchSubmit" class="common-search-button">
Search
<div style="clear: both;"></div>
</div>
</div>
What I typically do for that sort of layout is make a parent container around the elements (like you have) and give it position: relative and width: 100%.
Then I use position: absolute and display: inline-block on the inner elements. Set the width for the fixed-sized elements and use left or right to position all of the elements.
In your case, it would be something like this: https://jsfiddle.net/ufLpqdtj/1/
Well you shouldn't use the div as a button. There are html elements for that.
If correctly understood what you want to achieve...
form {
width: 100%;
display: inline-flex;
justify-content: center;
}
#commonSearchTerm {
width: 80%;
}
#searchButton {
width: 80px;
border-radius: 0;
background-color: red;
border: none;
padding: 2px;
color: white;
}
<form >
<input id="commonSearchTerm" type="text" autocomplete="off" class="common-search-term">
<input id="searchButton" type="submit">
</form>
This is using flexbox which is is more flexible when creating responsive stuff.
So today i was messing around with some inputs. I had 2 inputs; 1 text field, 1 submit button.
I set the heights to be identical on them both, but, for some bizarre reason they weren't. I tried resetting padding, max/min height. To no avail. In the end i settled for identical font-size and paddings to achieve equal heights. What is the reasoning behind this, can anyone explain the logic, is this intentional?
JSFiddle for demonstration: http://jsfiddle.net/FecEe/
HTML
<p>See how the heights are set to be the same, but yet, they are displated differently?</p>
<input class="sample1" type="text" name="email" placeholder="john#example.com">
<input class="sample1" type="submit" name="post" value="Enter">
<br><br>
<p>See how the height isn't set explicitly but the inherited height from the text and padding make the height the same?</p>
<input class="sample2" type="text" name="email" placeholder="john#example.com">
<input class="sample2" type="submit" name="post" value="Enter">
CSS:
.sample1{
height: 50px; /* ...? */
margin-top: 25px;
margin-right: 5px;
padding:10px;
font-size: 2em;
outline:none;
border: 1px solid black;
}
.sample2{
margin-top: 25px;
margin-right: 5px;
padding:10px;
font-size: 2em;
outline:none;
border: 1px solid black;
}
The default stylesheet in WebKit (and probably other browsers) is to blame:
input[type="button"], input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button, button {
-webkit-align-items: flex-start;
text-align: center;
cursor: default;
color: ButtonText;
padding: 2px 6px 3px 6px;
border: 2px outset ButtonFace;
background-color: ButtonFace;
box-sizing: border-box
}
See that box-sizing: border-box? That's making your button's height behave intuitively (at least for me): the padding and borders "grow in" from your maximum height of 50px instead of "growing out".
The default box-sizing property of all elements (and therefore your textbox) is box-sizing: content-box, which is computed differently.
To fix it, just make them both use the same box model (I'd go with box-sizing: border-box;). Better yet, save yourself some trouble and do it for all elements:
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
There's even a polyfill for IE7 and IE6, if you support them.
use box-sizing: content-box; in sample1 class
.sample1 {
height: 50px;
margin-top: 25px;
margin-right: 5px;
padding: 10px;
font-size: 2em;
outline: none;
border: 1px solid black;
box-sizing: content-box;
}
.sample1 {
height: 50px;
margin-top: 25px;
margin-right: 5px;
padding: 10px;
font-size: 2em;
outline: none;
border: 1px solid black;
box-sizing: border-box;
}
i'm trying to customize a text input with css, i want the text inside it to have a margin of 10px to the left so i use:
#text{
text-indent: 10px;
border: 1px solid #333;
outline: none;
padding: 0;
margin: 0;
width: 168px;
height: 20px;
border-radius: 4px;
}
It works in all browsers except for IE10 which seems to ignore the text-indent property, how can i fix it?
<input type="text" id="text" />
you can use padding-left, it works on all browsers:
#text {
padding: 0 0 0 10px;
border: 1px solid #333;
outline: none;
margin: 0;
width: 158px; //decrease width with the same padding vale so that the width would stay the same
height: 20px;
border-radius: 4px;
}
If you want to use a special rule for IE, adding display: inline-block and a line-height, along with the text-indent rule, will fix this as well. This is an old trick for both IE7-9 as well.
input.special {
text-indent: 150px;
display:inline-block;
line-height: 18px;
}
Does the trick.
This is good if you are using liquid or responsive widths and you don't want to have to adjust your input's width on account of the padding.