I am building a login modal and would like to use input tags to enable browsers to autocomplete username and password however I am struggling to fully reset the User Agent Stylesheet styling for input tags. Whenever autocomplete does its thing the old styling comes back.
Here's my (simplified) react login form:
<form id="login-popup-container">
<div className="login-field-container">
<div className="login-value-title user">email</div>
<input className="answer login-info" type="text" />
</div>
<div className="login-field-container">
<div className="login-value-title password">password</div>
<input className="answer login-info" type="password" />
</div>
</form>
I have added this in my index.css:
input, input:focus, input:active, input:hover, input:-webkit-autofill, input:autofill, input:indeterminate, input:enabled, input:valid {
outline: none !important;
border:none !important;
background-image:none !important;
background-color:transparent !important;
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
box-shadow: none !important;
}
It works in a chrome incognito browser well enough
But in a regular chrome tab when autofill is performed by chrome this action brings the User Agent Stylesheet styling back to the input elements like this. As you can see above I have tried adding all the pseudo classes I could think of to the input tag reset styling but with no success.
Has anybody experienced this issue before / know why this is happening?
You can't override UA styles with !important
The user agent style sheets of many browsers use !important in their :-webkit-autofill style declarations, making them non-overrideable by webpages without resorting to JavaScript hacks.
https://developer.mozilla.org/en-US/docs/Web/CSS/:autofill
Also, more efficiently reset every single style on your inputs with the CSS all property!
input {
all: unset;
}
You can use these global values:
initial - set all properties to property default defined by CSS
unset - if normally inherited: inherit, if not: initial
revert - set all properties to default for element defined by UA
For anybody experiencing this issue... the answer to my question turned out to be a combination of Zach Jensz's answer and adding a transition delay to <input> elements. It's definitely more of a hack than an answer, but for me it works.
My css reset looks like this:
input {
all: unset;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
transition: all 5000s ease-in-out 0s;
}
and my styling for inputs looks like this:
.classname-used-for-my-inputs {
background: transparent;
background-color: transparent;
color: white;
border: none;
}
The reason the delay hack is necessary is because even after unsetting all the styles, upon an autocomplete of the email/password event the User Agent styles kept coming back (I could not figure out how to prevent this). But at least now the delay time is so long that for all practical purposes no one will ever notice them and so for my purposes it works.
If somebody explains why / proposes a non hacky solution I will update this.
Also for styled-components, you could only apply it in your global.styles folder
input {
all: unset;
}
Related
I'm currently working on a custom element which is basically a slightly augmented version of an input element, hosting all of its building blocks (including an input element) in a shadow DOM.
When the internal input element has focus, the host element should be styled with a colored outline and box-shadow, as seen below:
Therefore the focus and blur event handlers of the input toggle an attribute "focussed" on the host element with the encapsulated styles looking like this:
:host([focussed]) {
transition: outline 0.3s ease-in-out;
outline-color: var(--focus-color, var(--default-focus-color)) !important;
box-shadow: 0px 0px 3px var(--focus-color, var(--default-focus-color)) !important;
}
What I don't like about this approach:
Exposing a custom attribute on the host that needs to be observed, in order to ensure the correctness of the visually represented state (e.g. consumer calls setAttribute('focussed', ''))
Alternatives I considered:
Of course my first thought was to encapsulate the attribute within the shadow DOM (or even toggle a class) on a container element filling out the space of the host element, but the problem is that overflowing contents such as outline and box-shadow seem to be forcefully hidden by the host element - which seems kind of logical.
I could dictate a fixed padding on the host element to ensure the visibility of the outline and shadow, but this would require considering different browser rendering behaviour of box-shadow and would feel counter-intuitive for custom styling by the consumer.
I'm looking for a best practice approach here and I would very much appreciate your educated thoughts on this one.
this.attachShadow({
mode: 'open',
delegatesFocus: true
})
works in Chrome, Edge, Opera, not the others (yet)
This styles the input (in shadowDOM) itself with:
:focus {
transition: outline 1s ease-in-out;
outline: 2px solid var(--focus-color,blue);
box-shadow: 10px 0px 10px var(--focus-shadow-color,red);
}
And styles the host element with (global) CSS:
:focus {
outline: 5px solid green;
}
Full explanation and playground JSFiddle
use Chrome/Edge/Opera first, then see lacking behaviour in others:
https://jsfiddle.net/WebComponents/Lpqyg201/
It has some pointers for click/focus/blur workarounds.
For FireFox , Safari support I would add something not too fancy that can easily be removed.
For now it is unclear to me what the time frame at Mozilla and Apple is,
maybe Supersharp knows
For whatever odd reason, Angular does not blur out the clicked element, so I 'fixed' it like this:
*:focus { outline: none !important; }
It's not a real fix, instead every element should be blurred automatically, but I'm not sure how to do that without a directive, so this must do for now, unless someone has a better solution.
However, I can't seem to apply the same 'fix' for Bootstrap custom checkboxes.
<label class="c-input c-checkbox">
<input type="checkbox">
<span class="c-indicator"></span>
Remember Me
</label>
This is how it looks like when focused:
I tried removing outline, border, box-shadow - nothing seemed to work.
It's not a problem coming from your libraries, but your custom css. You have to be missing something, but this code should work.
Place it at the end of your custom css file.
.c-input .c-indicator {
border: none !important;
outline: none !important
}
I apply css in form it should apply when my form is invalid .I also write important but nothing happen .In other words I make a dynamic form from json ,Now I need to validate that form .so I apply css which is not working.why I am apply css because some one suggest that in this how to validate form using $pristine and $dirty in angular? you please why it is not apply
here is my plunker
http://plnkr.co/edit/ECLvOstUxq5tIDrYicF2?p=preview
/* Styles go here */
.ng-invalid {
border :1px solid red !important;
}
.ng-pristine {
border :1px solid blue !important;
}
.ng-pristine {
border :1px solid blue !important;
}
Updated plunker
http://plnkr.co/edit/ECLvOstUxq5tIDrYicF2?p=preview
I press login button nothing happen
You need to update your css into this
input.ng-invalid {
border :1px solid red !important;
}
the class ng-invalid applies to the form as well since it AngularJS detects that the form is invalid so it applies the class to the form.
Edit
It seem that you are using a third party module for your forms. It has it's own validation styles so we have to use it. Here are some notes:
I added the novalidate directive to your formly directive. This will prevent the browser to trigger its default validation, the browser's default validation will not trigger the ng-submit function if it finds an error.
I added an ng-class="{'form-submitted':submitted}" to the form directive itself. (This is similar to the approach of PatrickEvans' answer
In relation to Item 2, I modified the CSS to this. The red border will be applied if the form-submitted class is applied to the parent form.
.form-submitted input.ng-invalid {
border :1px solid red !important;
}
See Plunkr
You have invalid style values: 1 px solid red !important you have a space between the number and px which makes it invalid so it does not render that style.
If using Chrome, you can look at an elements applied styles and if there is a warning symbol next to the style (and has a line through it) it means it is an invalid value. Not sure what the other browsers Developer Tools looks like for this but this is what Chrome's looks like:
As for making the css only apply after hitting the login button you will need to setup a check. You can do this by using the ng-class directive
css
.ng-invalid.apply {
border :1px solid red !important;
}
html
<input type="email" ng-class="{apply:loginAttempted}" />
<button type="submit" ng-click="loginAttempted=true" />
the ng-class will apply the style apply to the element when loginAttempted is a truthy value. So when the element gets the ng-invalid and the apply classes then the border will be rendered.
Can anyone tell me why button focus borders are rendered with a black dashed border by default in IE11 and with a blue solid border in Chrome? You can see this if you go to http://angular-ui.github.io/ and tab over the Site/Code buttons with IE11 and Chrome.
I've tried various overrides like -webkit-appearance:none etc to no avail. Is this an AngularUI bug, or a browser quirk everybody knows about and have been working around that I'll need to special-case if I want the look to be uniform?
When you tab over the button, you are applying the element's :focus styling. Looking at the stylesheet which is being used, I cannot see any custom styling for this, so the browser is providing it's default focus styling.
If you want to override this, then you can write your own focus style. So for this particular button, you can use:
a.btn.btn-primary.btn-large:focus{
outline: 0;
/* add other styling to it */
}
Or if you want to just target all anchors on the page, then use
a:focus{
outline: 0;
}
Angular is adding the dotted lines on this occasion - to remove, do this in your CSS;
.btn-group > .btn:hover, .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active {
outline: 0;
}
I have tried EVERYTHING to get rid of this focus blue highlight and absolutely nothing seems to work.
I have tried:
input:focus {
outline: none;
}
which I've read on here is the correct solution. It's not working though. Using the latest Chrome / Safari / Firefox the blue highlight is still there when clicking into focus.
It works in IE7 / IE8 funnily enough. I tried a javascript solution I read on stack as well where I add an onclick:blur method to the input, but this just made the input field uneditable?
Any solutions guys? Would prefer a clean CSS solution if possible.
That bit of css would only work if there's nothing more specific. Remember, css goes by the most specific rule taking precedence, so saying
input#myid:focus { /* <--more specific, takes priority */
outline: blue;
}
input:focus { /* <--less specific, overridden by above */
outline: none;
}
You can force the override with !important, though that can lead to other problems later on:
input:focus {
outline: none !important;
}
Use Firebug to view the computed CSS for the element when it's hovered. It'll tell you where the rule(s) applied to element are coming from.
I was having the same problem and this worked for me
#search input[type="text"]:focus {
width: 180px;
outline: none;
}