'required' css selector syntax - css

I found following CSS in https://angular.io/docs/ts/latest/guide/forms.html
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
I have not seen .ng-valid[required] syntax before. I guess .ng-valid is a class. Is [required] some new CSS syntax?

With the CSS attribute selector *[required] you can format elements with the attribute required. The syntax isn't new. See the following example:
input[required] {
border:1px solid red;
}
<input type="text" required/>
<input type="text"/>
This is often used in <form>s to define some elements like <input> as required. With the CSS attribute selector *[required] you can format these required elements.
You can also use the :required pseudo-class to format the required elements:
input:required {
border:1px solid red;
}
<input type="text" required/>
<input type="text"/>
The :required CSS pseudo-class represents any <input> element that has the required attribute set on it. This allows forms to easily indicate which fields must have valid data before the form can be submitted.
source: https://developer.mozilla.org/en-US/docs/Web/CSS/:required

Related

Why do comma separated placeholder rules not get applied in css?

If I apply the following rule to an input element with id #one then the placeholder color will change,
#one::-webkit-input-placeholder {
color: red;
}
But if I use comma separater to combine placeholder rules of different browsers then the color doesn't apply, e.g.
#two::-webkit-input-placeholder,
#two::-moz-placeholder{
color: red;
}
Working example:
#one::-webkit-input-placeholder {
color: red;
}
#two::-webkit-input-placeholder,
#two::-moz-placeholder{
color: red;
}
<input id="one" type="text" placeholder="one">
<input id="two" type="text" placeholder="two">
Why does the #two placeholder not change its color to red?
This is because a browser will only apply a rule form a selector it can fully interpret.
For a webkit type browser -webkit-input-placeholder is valid but -moz-placeholder is not, so it trashes the entire selector, and vise-versa for a geeko based browser.
The solution is to separate browser specific selectors.
#two::-webkit-input-placeholder{
color: red;
}
#two::-moz-placeholder{
color: red;
}
I know it is now a complete answer, but you could add different classes for each input
#one::-webkit-input-placeholder {
color: red;
}
#two::-webkit-input-placeholder{
color: red;
}
#two::-moz-placeholder{
color: red;
}
<input id="one" type="text" placeholder="one">
<input id="two" type="text" placeholder="two">

Is there a selector that handles "the element contains an element with class"

I have HTML like this:
<div class="form-group">
<input type="email" class="form-control>
<div class="form-error">This is not valid email address</div>
</div>
I am printing div.form-error dynamically if the input has errors.
I need CSS code to make the input's border red if there is a div.form-error in the div.form-group.
I'am working with SASS, maybe it has a function to do this. I'm looking for a something like this:
.form-group {
&:contains('.form-error') {
input {
border: 1px solid red;
}
}
}
How can I do it?
Okay, so while my comment still stands – it is not possible to use CSS to style a previous sibling, or ancestor, based on a subsequent sibling or descendant – there is a way around it. Though it while it does require a change of your HTML it will still emulate the element-order that you posted in your question.
That said, the HTML is changed from the following:
<div class="form-group">
<input type="email" class="form-control" />
<div class="form-error">This is not valid email address</div>
</div>
To:
<div class="form-group">
<div class="form-error">This is not valid email address</div>
<input type="email" class="form-control" />
</div>
.form-group {
/* to use the flex layout model: */
display: flex;
/* to have the elements arranged
in a column instead of a row
(which you may or may not want): */
flex-direction: column;
/* aesthetics, adjust to taste: */
width: 50%;
border: 1px solid #000;
margin: 0 0 0.5em 0;
}
.form-group .form-error {
/* places the .form-error element(s)
at the end of the layout in position
2, which causes the <input> to take
position 1; note that the elements
are still in the same place for CSS
selection: */
order: 2;
}
/* This styles the email <input> element if
it follows the .form-error element: */
.form-error + input[type=email] {
border-color: red;
}
<div class="form-group">
<div class="form-error">This is not a valid email address</div>
<input type="email" class="form-control" />
</div>
Incidentally it's worth noting that according to caniuse.com, flexbox is available in all current browsers; though your users may not have updated their own browsers to the current (or previous) version as of writing.
There are, of course, other ways you can achieve this simply using the :invalid pseudo-class:
/* Selects any <input> element whose value is invalid: */
input:invalid {
border-color: red;
}
<div class="form-group">
<input type="email" class="form-control" />
<div class="form-error">This is not a valid email address</div>
</div>
And, of course, you can even use fading to show or hide the error message:
/* Selects any <input> element whose value is invalid: */
input:invalid {
border-color: red;
}
/* hides the .form-error element using the opacity
property which takes a value, which allows it
to be animated from hidden (opacity: 0) to shown
(opacity: 1): */
.form-error {
/* visually hidden: */
opacity: 0;
/* specifies that the opacity property should be
transitioned over a 0.3 second time in a linear
animation: */
transition: opacity 0.3s linear;
}
/* Selects the .form-error element that immediately
follows an <input> which is :invalid */
input:invalid+.form-error {
opacity: 1;
}
<div class="form-group">
<input type="email" class="form-control" />
<div class="form-error">This is not a valid email address</div>
</div>
Bibliography:
"Using CSS Flexible Boxes."
You can use child selectors and sibling selectors.
For your example:
.form-group {
.form-error ~ input {
border: 1px solid red;
}
}
As pointed out correctly by folks in the comments, you will need to alter mark up for this to work. You can use the sibling selector:
https://developer.mozilla.org/en/docs/Web/CSS/Adjacent_sibling_selectors
.form-group {
.form-error + input {
border: 1px solid red;
}
}
.form-error + input {
border: 1px solid red;
}
<div class="form-group">
<div class="form-error">This is not valid email address</div>
<input type="email" class="form-control" />
</div>

What is the difference between ng-valid[required], .ng-valid.required?

I was going through https://angular.io/docs/ts/latest/guide/forms.html as exercise then I came through this piece of code:
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
Why are both of .ng-valid[required], .ng-valid.required selectors used at the same time and cant we just replace this by only one of them?
The .ng-valid[required] rule is valid for
<input class="ng-valid" required>
The .ng-valid.required rule is valid for
<input class="ng-valid required">
Both rules are valid for
<input class="ng-valid required" required>
Now you can choose which solution you want to use and remove the not necessary rules on your CSS.

Keep focus styling if text is present

I've got an input box. I customise it in normal state and on focus.
My question is how do I keep the focus CSS styling if text is present in the input box?
.par input[type=sample]{
width:75px;
background-color: #000;
}
.par input[type=sample]:focus{
width:50px;
background-color: #FF0;
}
There are no pure CSS selectors to directly select and style text boxes based on their content. But if the field is a mandatory field (that is, you could add the required attribute) then the :valid pseudo selector can be used to identify if the text box has any text type inside it or not and based on it apply the required styles.
input[type=text] {
width: 75px;
background-color: #000;
}
input[type=text]:focus,
input[type=text]:valid {
width: 50px;
background-color: #FF0;
}
<input type="text" required />
<input type="text" required />
input[value=""]:focus {
background-color: yellow;
}
<input onkeyup="this.setAttribute('value', this.value);" value="" />
another way would be to check in jquery.. using ':contains' selector
you can have one more selector with :valid pseudo-class.
.par input[type=sample]:valid{
width:50px;
background-color: #FF0;
}

How do I remove the white border around this input? (JSFiddle provided)

http://jsfiddle.net/gn3LL/
.error { background-color: red; }
<input id="firstname" class="custom error" name="first_name" type="text" placeholder="" class="input-xlarge">
There is a small but noticeable white border around the inside of the input box. How do I remove it?
Just user border:none
input {border:none;}
Or in your error class
.error { background-color: red; border:none;}
DEMO
border:0px;
or
border:0px solid #000;
The problem is you have two class attributes in a single element.
It is not valid based on w3.org's 8.2.4.35 Attribute name state.
... if there is already an attribute on the token with the exact same
name, then this is a parse error and the new attribute must be removed
from the token.
So you need to combine them like this -
<input id="firstname" class="custom error input-xlarge"
name="first_name" type="text" placeholder="" >
Back to original question
jsfiddle
.error { background-color: red; border: 0; }
OR
input[type="text"] { border: 0; }
OR (After you combine them into one)
.input-xlarge { border: 0; }
.error { background-color:red; border:0; }

Resources