Angular can't remove focus outline from a Boostrap custom checkbox - javascript

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
}

Related

Trouble with <input> styling and autofill

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;
}

How can I change the border color on my <select> element without effecting bootstrap css styling?

I have a bootstrap (v4.5.3) form, where my selects look like this in firefox:
When someone tries to submit the form, I have some JS code that runs, and does validation. One of the things it checks for is that someone actually chose an option, and didn't leave it on -- Select an Option --. When I detect this, my javascript would stop form submission, and highlight the option by setting the border to red:
ELEMENT.style.borderColor = "red";
Unfortunately, when I do that, my select loses whatever styling bootstrap put on it, and looks like this:
I left the bottom one untouched for easy comparison.
Am I highlighting it wrong? Is there some css class I'm supposed to use instead of changing the borderColor?
Edit: See https://jsfiddle.net/xbqucoLp/ for example
Bootstrap actually comes with validation CSS built in. The style of the select in bootstrap is different to what you have in your question so it may not be to your liking. It does however keep the select arrow consistent unlike what you currently have.
See https://getbootstrap.com/docs/5.0/forms/validation/ for details
Here is a working fiddle: https://jsfiddle.net/0gqL7641/1/
The advantage of using this is that when you choose an option it changes from red to green.
If the above is unacceptable to you, then the following will work:
You can use outline instead of border and this doesn't change the styling of select
this.style.outline = "solid 1px red";
Another way of changing the outline without touching border is to use shadow
.redOutline {
-webkit-box-shadow: 0px 0px 3px 3px rgba(255,0,0,0.5);
box-shadow: 0px 0px 3px 3px rgba(255,0,0,0.5);
}
and use the following to add the outline
this.classList.add("redOutline");
You can tweak the shadow CSS using this tool https://html-css-js.com/css/generator/box-shadow/
Have you tried adding a class to the element instead?
like this
element.classList.add("mystyle");
that might work as long as the only thing that class contains is a border color with !important
Ah I didn't realize there was a difference sorry. Usually for these custom selects, there are classes that overlay the browser select to get custom features. I would see if you can target those classes and change their border color. Looking for the elements in the browser dev-tools allows you to change their css in the browser to test if you can do that to see what element you need to target.

override default focus with css or reseting it

I want something like css reset, but only for the :focus. If there's none of this yet, would be good to know the possible properties to reset(override) in order to make new :focus that will override the previously one(set by the web-site css). For example, z-index may effect on :focus for some specific elements in some browsers. So the :focus should include z-index with some huge number and in order to work it should include position too. perhaps it's wrong example, but I think you got the idea here.
You may want to post some code with some examples of problems that you are having in a jsfiddle or in the question.
That said, there are some elements that tend to get default styling for :focus in the browser - input, a. There is some great information here about potential fixes, for instance:
/* put universal focus changes here */
*:focus {
outline: none;
}
/* put anchor focus changes here */
a:focus {
...
}
/* put input focus changes here */
input:focus {
...
}
I'm not certain what you are trying to accomplish with the z-index setting, but you could handle it as above.

why css not apply on form in angular js

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.

How to trigger bootstrap's mouseover effect programmatically

In twitter bootstrap, some elements get "greyed out" when the mouse hovers over them. This is true of buttons and linked list group items. Two examples are here: http://imgur.com/a/ABhkT#0
Can this effect be triggered programmatically? If so, how?
Yes, Using the 'onmouseover' attribute. It is quite similar to the 'onclick', except obviously for hovering instead.
Like the 'onclick', you will have to include a java script function that would change the css style for that element.
Depending on what you are trying to have this effect on, you could either put it right into the tag that is the object, or use <span></span>.
Ex:
<div onmouseover="fade()">
<p>text to fade</p>
</div>
Javascript:
function fade(){
code to change style
}
should be straight forward, this would fade everything inside the div (including the background)
Ok, I figured it out.
If the effect were being caused by a css class, one could simply apply the class to the element, like this:
$('<my_element>').addClass('bootstrapMouseoverGrey')
This doesn't work, though, because the effect isn't caused by a class. It's caused by a pseudoclass. Pseudoclasses can't be added programmatically.
One workaround is to create a new actual class with the exact same definition as the pseudoclass. In my case, the pseudoclass is a.list-group-item:hover, defined in bootstrap.css.
a.list-group-item:hover,
a.list-group-item:focus {
text-decoration: none;
background-color: #f5f5f5;
}
I edited bootstrap.css to make a new (actual) class, bootstrapMouseoverGrey, with the same definition as the pseudoclass.
a.list-group-item:hover,
a.list-group-item:focus,
.bootstrapMouseoverGrey {
text-decoration: none;
background-color: #f5f5f5;
}
Now, I can just add this class to an element using the line at the top of the answer. This gives me the result I want. Works like a charm!
Using jQuery:
var event = jQuery.Event('<event_name>');
event.stopPropagation();
$('<selector>').trigger(event);
Taken from the docs.

Categories

Resources