I am experiencing weird behavior of input when it is focused. As you can see through the images below, an extra white border appears whatever its outline-color is.
I tried setting padding: 0px; and box-shadow: none; too, but still I could not remove it. One thing I realized is that setting outline-style: solid; does the trick, but then I couldn't see rounded corner anymore.
The image below is the same input element which has completely same css rulesets:
input {
flex: auto;
border: 1px solid darkgrey;
border-radius: 4px;
background-color: transparent;
color: white;
font-size: 42px;
}
input:focus {
outline-style: auto;
outline-color: orange;
}
body {
background-color: #383838;
}
<input>
Don't use the auto value. Use solid instead
input {
flex: auto;
border: 1px solid darkgrey;
border-radius: 4px;
background-color: transparent;
color: white;
font-size: 42px;
}
input:focus {
outline-style: solid;
outline-color: orange;
}
body {
background-color: #383838;
}
<input>
In addition, in CSS3, outline-style accepts the value auto. The auto value permits the user agent to render a custom outline style, typically a style which is either a user interface default for the platform, or perhaps a style that is richer than can be described in detail in CSS, e.g. a rounded edge outline with semi-translucent outer pixels that appears to glow. ref
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.
In the Reveal focus docs its:
But, as the docs
Reveal focus increases the size of the focus visual, which might cause issues with your UI layout. In some cases, you'll want to customize the Reveal focus effect to optimize it for your app.
How would you approach creating the effect that does not affect the UI in the way described above?
My Reveal focus component:
Reveal glow is box-shadow
Primary focus visual is outline
Secondary focus visual is border
Background
but something seems off and I can't quite grasp it. Is it box-shadow, is it spacing (like margin, I don't set any as you can see), or is it yet something else? How would you fix it if you wanted it to look like on the gif below?
body {
background-color: #000;
padding: 5px 100px;
}
.tile {
display: inline-block;
height: 82px;
background-color: #555555;
}
.x1 { width: 19%; }
.x2 { width: 38%; }
.reveal-focus {
border: 1px solid transparent;
outline: 2px solid transparent;
}
.reveal-focus:focus {
outline-color: #61B250;
box-shadow: 0 0 15px 3px #61B250;
}
The shadow is being placed above elements that appear before the focused one, but below elements after it. You need to add position: relative to all the elements, and z-index: 1 to the focused one.
To make sure this doesn't interfere with any other stacking, apply position: relative; z-index: 0 to the container. This ensures that it has its own stacking context.
The GIF you show appears to also have a slight animation effect, with the glow being more intense for just a moment before fading to normal. This can be achieved quite simply with animation.
body {
background-color: #000;
padding: 5px 100px;
}
.tile {
display: inline-block;
height: 82px;
background-color: #555555;
}
.x1 { width: 19%; }
.x2 { width: 38%; }
.reveal-focus {
border: 1px solid transparent;
outline: 2px solid transparent;
position: relative;
}
.reveal-focus:focus {
border-color: #000;
outline-color: #61B250;
box-shadow: 0 0 15px 3px #61B250;
animation: glowfade 0.4s linear;
z-index: 1;
}
#keyframes glowfade {
from {box-shadow: 0 0 30px 6px #61B250;}
to {box-shadow: 0 0 15px 3px #61B250;}
}
Adjust values as desired.
I have the following CSS and HTML code:
<ul id="actions" class="frame frame-yellowglow">
</ul>
CSS
ul#actions {
clear: left;
width: calc(60% - 2px);
margin: 5px auto;
padding: 10px 0px;
text-align: center;
}
ul#actions:empty {
margin: 0;
padding: 0;
}
ul#actions li {
display: inline;
margin: 0px 3px;
}
.frame {
border-radius: 5px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
border: 1px #dddddd solid;
}
.frame:empty {
border: none;
box-shadow: none;
}
.frame-yellowglow {
border: 1px #D4B700 solid;
box-shadow: 0 0 4px #D4B700;
}
The ul is populated with icons for certain actions that can be performed. However, the ul does not match the :empty selector when empty and as such still renders; border, padding, shadow, and all.
[EDIT: To clarify, I'm talking here about when elements have not yet been added. Even when there's nothing within, it still doesn't match the :empty selector. ]
Why is this so?
According to MDN
The :empty pseudo-class represents any element that has no children at all. Only element nodes and text (including whitespace) are considered.
Your "empty" ul probably contains a whitespace text-node.
I want to apply styles to all input elements that are not in #mydiv div element.
input[type="text"],
input[type="password"]:not(:in(#mydiv)) /* something like this */
{
border: 1px solid #ccc;
padding: 1px;
color: #444;
min-width: 70px;
}
It's not possible to do that using css (with todays browsers anyway).
But you can do it in reverse:
input[type="text"], input[type="password"] {
border: 1px solid #ccc;
padding: 1px;
color: #444;
min-width: 70px;
}
#mydiv input[type="text"], #mydiv input[type="password"] {
border: none;
padding: 0px;
color: inherit;
min-wdith: 0px;
}
You apply to the styles to everything, then add reversing styles all the ones inside the special div.
CSS2 does not have a not in clause
Your solution will be to give them all a specific class
input.my_class {
...
}
CSS3 has the :not() but it does not traverse the parent.