This question already has answers here:
Is there a "previous sibling" selector?
(30 answers)
What does the "~" (tilde/squiggle/twiddle) CSS selector mean?
(3 answers)
Closed 2 years ago.
I have label and email input like this:
#emaillabel {
color: red;
visibility: hidden;
}
#email:focus~#emaillabel {
visibility: visible;
}
<label id="emaillabel">Email</label>
<input id="email" type="email" required placeholder="Email">
The problem is that label is shown in expected behaviour only when i put it html code after input.
In other words when i click on input i want see label that are before input.
I can use only css
Given your current HTML structure, what you want to do CSS-wise is not possible, because you can only select forward.
That is, CSS has no previousSibling or parent/ancestor selector.
As a sidenote, your label is missing the for-attribute which works as the connector between the two.
What you can do is wrap both in a div (if it isn't already wrapped in another element, in that case just use that element) and use :focus-within pseudo class on the parent. Browser support for :focus-within is very broad, with IE being the usual exception. To make sure only browsers that support :focus-within hide the label, wrap the CSS declarations in a
#supports selector(:focus-within)
block:
.input-label-group label {
color: red;
}
#supports selector(:focus-within) {
.input-label-group label {
visibility: hidden;
}
.input-label-group:focus-within label {
visibility: visible;
}
}
<div class="input-label-group">
<label id="emaillabel" for="email">Email</label>
<input id="email" type="text" required placeholder="Email">
</div>
To make things a little more intuitive, you could - instead of switching visibility - also apply fadein/out using opacity and transition:
.input-label-group label {
color: red;
}
#supports selector(:focus-within) {
.input-label-group label {
opacity: 0;
transition: opacity 0.2s ease-in-out;
}
.input-label-group:focus-within label {
opacity: 1;
}
}
<div class="input-label-group">
<label id="emaillabel" for="email">Email</label>
<input id="email" type="text" required placeholder="Email">
</div>
Related
when I set the input type to email I can't use the valid selector to it in css and when I change the type to text it works perfectly
.span-name{
display:block;
}
input:focus ~ .span-name,
input:valid ~ .span-name{
transform: translateY(-100%);
}
<input type="email" name = "email_config" required >
<span class = "span-name">Email Configuration</span>
Your translateY isn't doing anything useful because transform doesn't work on inline elements, but it is being applied. Here I've also applied the color purple when it is valid, and you can see that it is working as expected. I also applied display: inline-block which will let the translateY do what I suspect you want it to do. I also changed the sibling selector to the next sibling selector so that I could re-use that style for both the email and text configurations.
input:focus+.span-name,
input:valid+.span-name {
transform: translateY(-100%);
color: purple;
display: inline-block;
}
<input type="email" name="email_config" required>
<span class="span-name">Email Configuration</span>
<br>
<input type="text" name="email_config" required>
<span class="span-name">Text Configuration</span>
I'm looking for a CSS only Answer, I can solve with Javascript/Jquery but I'm attempting to solve without.
IN short, I have to Radio buttons, I would like one div to be displayed if the first one is selected and a Second div if the second one is selected.
I have Created a jsfiddle with a simplified version of myProblem
https://jsfiddle.net/lukehammer/x7yw432d/5/ I can not get it to work in the JS fiddle or my code.
<label>
<input id="Type1" name="UserType" type="radio" value="Contractor">
Contractor
</label>
<label>
<input id="Type2" name="UserType" type="radio" value="Managment">
Managment
</label>
<div class = "hideAtStart" id = "contractorDisplay">
Show me I'm a contractor.
</div>
<div class = "hideAtStart" id = "ManagerDisplay">
Show me I'm a managerr.
</div>
CSS
.hideAtStart {
display: none;
}
#Type1:checked ~ #contractorDisplay{
display : block;
}
#Type2:checked ~ #ManagerDisplay{
display : block;
}
Question
How can I show a div when a radio button is pressed ?
**Bonus Points **
BounS Points if the Transition can fade in/out.
Layout
Set each radio before a div (fieldset in this demo)
On each radio:
Assign a unique #id
Assign an identical [name]
Next make 2 labels with the attribute [for] and set each attribute's value to an #id of a radio. The [for] attribute of the labels are synced to the radio with the same #id so that when the label is clicked so is the radio.
Place these labels anywhere you want on the page.
To make things easier assign a class that will group alike tags together.
Style
Hide the radios and the div that sits after each radio by setting display:none
Make the following ruleset (remember step 5 of Layout)
.radio:checked + .classOfDiv { display:block }
CSS rulesets are read backwards by the browser:
Any element that has the className of .classOfDiv that has a sibling element that is placed before (in code it's more like above or to the left) it and that sibling (older brother?) has the className of .radio and happens to be checked as well...set that .classOfDiv display property to block.
The + is called an Adjacent Sibling Combinator which is the key to this ruleset. See the References located after the Demo for more details.
Demo
.rad,
.set {
display: none;
opacity: 0;
}
.rad:checked+.set {
display: block;
opacity: 1;
}
.btn {
display: inline-block;
border: 2px inset grey;
border-radius: 6px;
padding: 2px 3px;
cursor: pointer
}
.btn:hover {
border-color: tomato;
color: tomato;
transition: .75s ease;
}
legend {
font-size: 1.5em
}
<form id='main'>
<fieldset>
<legend>SWITCH</legend>
<label for='rad0' class='btn'>OPEN SET 0</label>
<label for='rad1' class='btn'>OPEN SET 1</label>
</fieldset>
<input id='rad0' class='rad' name='rad' type='radio'>
<fieldset class='set'>
<legend>SET 0</legend>
</fieldset>
<input id='rad1' class='rad' name='rad' type='radio'>
<fieldset class='set'>
<legend>SET 1</legend>
</fieldset>
</form>
References
Adjacent Sibling Combinator
for Attribute
This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Is there a "previous sibling" selector?
(30 answers)
Closed 4 years ago.
Is this impossible? I've created a responsive menu system, but the :checked event of my checkbox doesn't get caught in my css
CSS
#sectiona:checked + #asection {
display: block;
}
HTML
<li >
<label for="sectiona" class="showhide">Search for a term</label>
<input type="checkbox" id="sectiona" value="button" style="display:none;"/>
</li>
I've see something like this before. If this isn't possible, I'll have to redesign my menus. It has to be HTML and CSS. No Javascript is allowed...
If undersood correctly you trying to show/hide checkbox input based on label click.
the visibility could do the trick.
Css:
input#sectiona:checked {
visibility: visible;
}
input#sectiona {
visibility: hidden;
}
<li >
<label for="sectiona" class="showhide">Search for a term</label>
<input type="checkbox" id="sectiona" value="button" />
</li>
in that case you can also add display: block;
input#sectiona:checked {
visibility: visible;
display: block;
}
Wondering whether if there is a css-only way to perform to toggle styles on the corresponding label on input's focus.
So far I have:
$(document).on('focus active', 'input',function(){
$('label[for='+$(this).attr('id')+']').addClass('active');
});
$(document).on('blur', 'input',function(){
$('label[for='+$(this).attr('id')+']').removeClass('active');
});
HTML:
<div class="row">
<label for="contact_form_mail">Email</label>
<input id="contact_form_mail" name="contact_form_mail" type="email" placeholder="Your e-mail address...">
</div>
And CSS:
.active{ color:red; }
Edit: I am surely aware of the child and sibling selectors "workarounds", but rearranging clean markup for the pure sake of styling seems not right, so if there is another pure css way this answer wins!
http://jsfiddle.net/fchWj/3/
Try this way:- Place your label after input and float it left. And apply siblings.
Html
<div class="row">
<input id="contact_form_mail" name="contact_form_mail" type="email" placeholder="Your e-mail address...">
<label for="contact_form_mail">Email</label>
</div>
CSS
label {
float:left;
}
input:focus + label {
color:red;
}
Demo
This is a hack to get the adjacent sibling selector work as it applies only on the following element and not the preceding one. ~ will select all the adjascent siblings after this element. So if you are having different .row for each section of inputs then use +.
If you are willing to switch elements, than here you go
Demo
<div>
<input type="text" />
<label for="e_mail">E-Mail</label>
</div>
label {
float: left;
margin-right: 5px;
}
input[type=text]:focus + label {
color: red;
}
Explanation: We are using + adjacent selector here, so when the textbox is focused, we select the label tag and apply color red
Note: Don't forget to clear floats ;)
It's possible with CSS only, without switching the order of the label and input. You can use a :focus-within CSS pseudo-class on the parent element, which applies to elements, that has a child element with the focus.
In your example, you could use the following:
.row:focus-within label {
color: red;
}
Note, that this pseudo-class is relatively new, so only modern browsers support it.
There is, but only if you place the label after the input.
<input name="field" type="text" />
<label for="field">Label Here</label>
input:focus + label{
color: red;
}
Now if you want the label to be placed before it, then you need to do some css styling with position absolute to place the label before the input field, then add some margin left on the input to move it to the right.
<div>
<input name="field" type="text" />
<label for="field">Label Here</label>
</div>
div{
position: relative;
}
input{
margin-left: 40px;
}
label{
position:absolute;
left:0;
}
This give you label on top of input, highlight label while input focus.
HTML
<div class="row">
<input id="contact_form_mail" name="contact_form_mail" type="email" placeholder="Your e-mail address...">
<label for="contact_form_mail">Email</label>
</div>
<code>
.row{
display:flex;
flex-direction:column-reverse;
align-self:flex-start;
}
.row input:focus{
border: 1px solid red;
}
.row input:focus+label{
color:red;
}
</code>
First we can use a selector that matches a label immediately followed by the input tag (input:focus + label). But there is still the problem, that the label follows after the actual input field. If one would like to have it above the text input we need to switch the positions of the controls. This can be done with a CSS pseudo-table.
<div class="pseudo-table">
<input id="yourname" name="yourname" type="text" placeholder="Name...">
<label for="yourname">Name</label>
</div>
The style for the artifical table is...
.pseudo-table { display: table; }
With this in place we could transform the label e.g. to a table-header-group:
label { display: table-header-group; }
and the input field to a table-row-group:
input { display: table-row-group; }
In combination with our followed by selector we're done and it looks right:
input:focus + label {
color:red;
font-weight: bold;
}
For a demo please see this Fiddle
HTH
There is no selector to match a preceding element...
This matches a label immediately followed by an input tag.
input:focus + label {
color: red;
}
Scenario
I have a CSS selector that is supposed to display sub-content when a label is clicked. The selector is along the lines of input:checked + element + element giving that final element a display of block (default is none). The problem is that it works in all the major browsers with the exception of webkit. Chrome, Safari, and a mobile browser for android (v2.2 sorry, I'm behind the times) all fail to display the element. When I inspect the element in Chrome, it shows that it is supposed to be display: block but it doesn't render it. I can unchec and check the property in developer tools and it displays, but not before.
I assume that this is a bug in webkit.
Question
Here is the multipart question: Is this a known bug in webkit? Am I doing anything wrong with my selectors? And how can I work around the issue for webkit browsers (any creative suggestions)?
Code
HTML
<input id="c1" type="checkbox">
<label for="c1">Ein</label>
<section>Content</section>
<input id="c2" type="checkbox">
<label for="c2">Zwei</label>
<section>Content</section>
<input id="c3" type="checkbox">
<label for="c3">Drei</label>
<section>Content</section>
CSS
input {
float:left;
clear:left;
visibility: hidden;
position:absolute;
}
label {
color:green;
display:block;
cursor:pointer;
}
section {
display:none;
}
label:after {
content:" +";
}
input:checked + label:after {
content:" -";
}
input:checked + label + section {
display:block;
}
Demo
Demo: http://jsbin.com/epibin/2
Source: http://jsbin.com/epibin/2/edit
Chain A Pseudo-Class
This demonstrates that this code fixes the bug (note that nth-child(n) matches any element, but the adding of it into the chain causes it to work):
input:checked + label:nth-child(n) + section {
display:block;
}
#ScottS provides a solid solution. Another possible one that worked for me and makes more sense from an outsiders "why the heck did they do that" point of view:
input:checked ~ section {
display:block;
}
which selects every 'section' that come after and are siblings of 'input:checked'.
There are two conditions I can think of where #ScottS's version is superior because the element in the position of 'label' gets selected as well in my solution:
(1) 'input's sibling #1 & #2 are the same elements (instead of 'label' & 'section')
(2) you are trying to be general by using the '*' selector.
sounds like a match to Bug 45168 – CSS multiple adjacent sibling selector sequence is ignored if prefixed with a pseudo-class selector
if you swap the <label> and <input> structure in the markup (and adjust the CSS accordingly) it works.
http://jsbin.com/epibin/10/edit
(but now the + - don't toggle)
EDIT:
putting the <label> and <section> in a div container works: http://jsbin.com/epibin/12/edit
As mdmullinax states, this is an outstanding bug in chrome.
This hack worked for me from the link in the accepted answer:
body { -webkit-animation: bugfix infinite 1s; }
#-webkit-keyframes bugfix { from { padding: 0; } to { padding: 0; } }