How to target label element based on input element's dynamic class? - css

HTML
<label for="email">Email</label>
<input type="text" name="email"></input>
The class attribute of the email input element may change, like if the user enters an invalid email format. I only want that label to change to red when the input it's for gets the class "invalid".
In fact, I want ALL my labels with a for attribute to be "invalid aware" of their assigned input elements.
CSS Attempt:
label[for=*.invalid]{
color: red;
}
The above is probably incorrect because I might have to specify a specific form element by name.

Option 1
If you're adding a dynamic class to the input element (.invalid), why not add a class to the label element, as well? This would simplify the styling of the label when the input fails validation.
Option 2
I understand that changing the label color to red highlights an error to the user. In this option you still highlight an error to the user, but in a slightly different way. The CSS :valid and :invalid pseudo-classes represent form and input elements that validate or fail to validate. These pseudo-classes style the input not the label.
Option 3
This option involves the sibling and attribute selectors. You would have to reverse the order of your label and input in the HTML (but this doesn't have to change the appearance on the screen; see below).
HTML
<input type="text" name="email" class="invalid"></input>
<label for="email">Email</label>
CSS
input[class="invalid"] + label { color: red; }
Changing the visual order of elements with CSS Flexbox
Despite the order of elements in the DOM, you can still change the visual order of elements with CSS Flexbox. So if you didn't want to put the label after the input for the sake of appearance there's an easy workaround: Wrap the input and label in a flexbox and use the order property to arrange their display order.
A few side notes...
HTML5 provides an input type="email"‌​, which you may want to consider instead of type="text". One benefit being that when mobile devices see type="email" they often launch an e-mail-friendly keyboard.
Second, the input element is a void element. No closing tag required. You can safely remove the </input>.
Lastly, the for attribute associates a label element with a matching ID. In your code, you would need to add id="email" to your input for the label click feature to work.

The for attribute has to match the id (not the name, not the class) of the associated input.
In order to change the label based on a feature of the input you need to either:
Use combinators to draw a connection between the two elements (which is impossible when the label precedes the input) or
Use JavaScript to modify the label (e.g. by adding a class).

Related

Can't use the '_peerFocus' property in ChakraUI

I am using ChakraUI in a form component.
I have an input and a label that are siblings. I want to change the color of the label when I focus on the input field.
I tried to use the _peerFocus property, however it is not working. Any idea why?
<Input data-peer className="peer" {...rest}/>
<FormLabel _peerFocus={{color: "#ff0000"}}>label</FormLabel>
Thanks

I don't want to use Xpath to map the Label element

I don't want to use xpath to map these elements, as we can see the class is the same for everyone. How to do please?
<label class="sc-fzowVh juqfMo">CNPJ:*</label>
<label class="sc-fzowVh juqfMo">CPF: (do usuário)*</label>
xpath:
//*[#id="boxCadastro"]/div/div[2]/div[1]/div/label
//*[#id="boxCadastro"]/div/div[2]/div[2]/div/label
See the image please: enter image description here
Without seeing the HTML surrounding each of those label elements in order to be able to use scoping, the only option is to go with text matching on the label contents
element :label1, :css, 'label', text: 'CNPJ:*'
element :label2, :css, 'label', text: 'CPF: (do usuário)*'
or using the :label selector type
element :label1, :label, 'CNPJ:*'
element :label2, :label, 'CPF: (do usuário)*'
although having label elements without for attributes is generally a bad practice and negatively affects page accessibility, so you may want to talk to your developers about improving their HTML

CSS selector for a label wrapped around a particular control?

I have this label and checkbox
<label><input type="checkbox" id="SameAsPrimaryAddress" />Same As Primary Address</label>
Is there a CSS selector that will only affect the label text and not the checkbox or do I have to separate my label from the input or give the label an ID or class to be able to do this?
It depends
In that case and if you only need that HTML, you can.
But
It is better to wrap your text with a span or a div to avoid problems you can encounter.
Here's a demo
http://jsfiddle.net/6aS4k/
Then you can add style with label span {}
Your answer: No. There is no selector to only target the free floating text of an element, without affecting the inherited properties of other elements within. To explicitly style your text, you would actually want to wrap your text in another element to target in your CSS, like a span.
However, in your specific case, that checkbox does not have many (if any) inherited properties in most browsers default stylesheet. So, a long as you aren't using a reset stylesheet or otherwise normalizing that input to inherit style properties you could get away with styling the label to affect only the text.
In the end, I would recommend that your label should actually correspond to your input separately, which would also semantically make sense. This would also allow you to make use of the for attribute, which will allow clicking on your label to toggle the corresponding checkbox as well, which is a win for usability!
<div>
<input type="checkbox" id="SameAsPrimaryAddress" />
<label for="SameAsPrimaryAddress">Same As Primary Address</label>
</div>

Fill width with two divs, one of which might be absent

I'm trying to create a very basic chat system, part of which will be the entry box for lines of chat. If the user is logged in, that's all I need; but if the user is not logged in, I want an additional text box to allow them to enter their name.
I have the following HTML (although of course it can be altered):
<form>
<input type="text" placeholder="Name?" name="name" id="name"> <!-- This line may be absent -->
<input type="text" placeholder="What do you want to say?" name="say" id="say">
</form>
Is it possible to style this with CSS so that #name and #say together fill the whole width of the form, with #say taking all the width if #name is absent?
(The backend is Ruby on Rails; I have javascript available, so can use a JS solution, but would prefer pure CSS if possible)
For a simple, all-CSS solution, try the first-child pseudo-selector to overide a default half-width when #say is the first element inside of the form:
#name, #say{width:100px}
#say:first-child{width:200px}
This works perfectly fine with your simple markup structure. (I've tested it)
With whichever of the two languages you'll be using to determine whether the user is logged in, create a conditional statement that adds a html class to the input field that alters it's width say .input-full and .input-partial
IF user is logged in
SET class to input-full
ELSE
SET class to input-partial
ENDIF
sorry for the psedo code, then have appropriate CSS for each.
oooh, didn't see the CSS only, sorry. Without CSS3 and a disregard for IE I don't think you can do this with straight CSS.

HTML, accessibilty: is it possible to label two controls with a single label?

I have found an example in the net where the label tag and its 'for' attribute were used to hint the browser to which control the label belongs to. E.g:
<form>
<label for="male">Male</label>
<input type="radio" name="sex" id="male" />
<br />
<label for="female">Female</label>
<input type="radio" name="sex" id="female" />
</form>
My question is if I actually have two controls where the same single label should be assigned to the combination of both (not to each one, if possible), eg:
a label text + a numeric input field + a text (unit) input field
Should I
assign the label only to the numeric input field (because it can't be done) or
is it possible to put the numeric and text input field into a single span tag and attach the label to that span?
or can both input controls be placed inside the single label tag?
Which solution will work for accessibility on all browsers?
The for attribute of labels can indeed be used with any element (so long as the ID matches) but only for a single element. Additionally, it really only makes sense for form elements.
From the spec:
for = idref [CS]
This attribute explicitly associates the label being defined with another control. When present, the value of this attribute must be the same as the value of the id attribute of some other control in the same document. When absent, the label being defined is associated with the element's contents.
And:
To associate a label with another control implicitly, the control element must be within the contents of the LABEL element. In this case, the LABEL may only contain one control element.
(emphasis mine)

Resources