Cannot change the background image while the radio button is hovered - html

I wrote a radio list with image animate. When it was hovered and checked, it can change to another image.
it's works on all of the browsers but on IE its not work when I hover on it.
I don't know if I wrote some css wrong or miss something about ie issue?
the html is:
<ul>
<li>
<input type="radio" id="f-option" name="gender">
<label for="f-option" class="gender female"><img src="images/52x42.png"></label>
<div class="check"></div>
</li>
</ul>
and my css is:
.user-form ul li label.gender.female {
background-image: url(../images/female.png);
}
.user-form input[type=radio]:checked ~ label.gender.female,
.user-form input[type=radio]:hover ~ label.gender.female {
background-image: url(../images/female-checked.png);
}
its works all of the browser but not work on ie
can anybody help me fix it?
The online demo is in this bottom of page:
http://bestinthink.com/wg/buy-p1.html

Try the below. I'm accessing the female class directly after the label as .gender and .female were siblings.
.user-form ul li label.gender.female {
background-image: url(../images/female.png);
}
.user-form input[type=radio]:checked ~ label .female,
.user-form input[type=radio]:hover ~ label .female {
background-image: url(../images/female-checked.png);
}

Your example works in modern browsers because they treat hovering over your label element as though you are hovering over the radio element itself, even though the radio element is set to visibility:hidden. IE doesn't behave that way. You have to explicitly hover over the radio element — which you can't do because you've hidden it — to see your input[type=radio]:hover styles.I suggest changing the background-image on label:hover rather than input[type=radio]:hover. The below code might work for you.
.user-form input[type=radio]:checked ~ label.gender.female,
.user-form label.gender.female:hover {
background-image: url(../images/female-checked.png);
}
Use it and let me know how it goes.☺
I'll update if I find a less hacky solution.

Related

Problem with pointer-events and a:focus in CSS

I have a problem with my navbar, can someone help me ?
I have different links (<a>) that "unfold" an unordered list (<ul> of links <li><a><li>).
My <ul> is set to opacity: 0, and in my CSS I have :
.tab ul {
opacity: 0;
pointer-events: none;
}
.tab a:focus + ul {
opacity: 1;
transform: translateY(0px);
pointer-events: all;
}
(this is only the part of the code that doesn't work)
When I click the link, the tab does unfold, and pointer-events is set to all (I know it is because the sublinks color changes when hovered).
My problem is that whenever I click a sublink, the focus on the tab link is lost, and it seems to set pointer-events to none BEFORE executing the sublink's action (a basic href="page.html").
I tried removing :focus (as if the tab was in constant focus state), and the sublinks redirect me on the pages as intended.
I also tried putting pointer-events: all on ul > li > a, but it didn't work.
That's why I came to the conclusion that the tab link lose focus and the pointer event is set to none before the sublink is actually clicked.
Does someone know a way to work around this and execute the sublink's action before the focus loss ?
The tab is unfold and the sublink is hovered (mouse invisible on the screenshot thought) :
If I understood you correctly, then maybe add this solution can help you:
.tab a + ul:hover {
opacity: 1;
transform: translateY(0px);
pointer-events: all !important;
}
Because the focus of the link is lost, the submenu disappears, but you can leave the submenu by ul:hover.
P.S. By the way, on the example of the site that you specified, add this code at the end, it quite works (I tried using Web Inspector):
.menu-loisirs a + ul:hover, .menu-sports a + ul:hover {
opacity: 1;
transform: translateY(0px);
pointer-events: all !important;
}
For this kind of interaction, :focus-within is usually quite suitable. When the "trigger" link and wrapper of its children share same wrapper, it makes sense to bind logic to state of that parent wrapper. To make such structure keyboard accessible, can use .wrapper:not(:hover):not(:focus-within) .trigger + .content { /* visually hidden state styles */}:
.tab:not(:hover):not(:focus-within) a + ul {
display: none; /* for brevity, use accessible hiding in real world */
}
/* not necessary */
p[id]:not(:target) {
display: none;
}
a[href]:empty:before {
content: '🔗 ' attr(href);
}
p[id]:empty:before {
content: '§ ' attr(id)
}
<div class="tab">
<ul>
<li>
</li>
<li>
</li>
</ul>
</div>
<div class="tab">
<ul>
<li>
</li>
<li>
</li>
</ul>
</div>
<p id="a"></p>
<p id="a1"></p>
<p id="a2"></p>
<p id="b"></p>
<p id="b1"></p>
<p id="b2"></p>
Check the browser support (not supported in IE11 and older browsers) and consult accessibility and screen reader support before using in production.

Is it possible to use the ~ and + selector at the same time?

For demo purposes say I have html like:
<input type="checkbox" id='hi'>
<label for="hi"> hi </label>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
and corresponding CSS as
ul {
display:none;
}
input[type='checkbox']:checked ~ul{
display:inline-block;
background-color:red;
}
input[type='checkbox']:checked +label {
background-color:red;
}
The idea is, when the checkbox is checked, I want the label with text 'hi' to have a background color of red and also to display a ul with a background-color of red.
As shown above, I needed to duplicate code to have a ~ul and +label after each :checked
Am curious to know whether or not this can be combined i.e. only using :checked once in above instead of twice, in any manner?
No, when you need to apply different properties to different selectors, there’s no way to do it in one rule in plain CSS. This is why people sometimes choose to use languages that compile to CSS, like Sass or Less.
input[type='checkbox']:checked {
& ~ ul, & + label {
background-color: red;
}
& ~ ul {
display: inline-block;
}
}
The main good alternative is to change your HTML structure so the selectors are more natural.

How does css checkbox hack work?

I just came across the switch toggle button which is created only using css. It known as the checkbox hack.
For those who doesn't know what a checkbox css hack is, Please read it here
https://css-tricks.com/the-checkbox-hack/
I tried it out and it was working perfectly fine. But I didn't understand how this is working because we are not clicking on the checkbox.
So I have 2 questions
How is this working ?
Instead of absolute positioning I tried it with display: none;
It still worked. Does this method have any drawbacks?
The way it works is by using the <label> element. Any input element can (and usually should) have a label. You can tell the browser which label belongs to which label by using a for attribute, referring to the input's name:
<input name="myName" />
<label for="myName">Label</label>
Whenever you click the label, it focuses the input (or in case of checkboxes, toggles it).
The label and checkbox don't have to be near each other. You could add a few hidden checkboxes at the start or end of a document and place the labels anywhere on the page, and they'd still focus the input.
Hiding the checkbox through display: none could cause buggy behavior on certain browsers. Just hiding it from view by a position: absolute is safer.
You can bind labels to checkboxes/radios using the for= attribute. When this is set, clicking on the label toggles the checkbox. This is a standard HTML attribute.
You can hide the checkbox using display: none, but do test it to make sure that its value is still submitted with the form.
CSS is aware of the current checked state of a checkbox input
This awareness, in combination of siblings selectors such as + (immediate next sibling) and ~ (next sibling somewhere) allows styling different styles, for checked/unchecked states, to anything that comes after the input element. The key here is the word "after".
Basic example:
/* styles when checkbox is unchecked */
div{ border:2px solid blue; margin:10px }
div h3{ color:red; }
/* when checkbox is checked */
input:checked ~ div{ background:blue; }
input:checked ~ div h3{ color:gold; }
<input type=checkbox>
<div><h3>very<h3></div>
<div><h3>cool<h3></div>
As others have said (but is not a must) - HTML label element allows to interact with input elements, and in checkbox/radio types' case - it allows to toggle their checked state by clicking the label itself, which is "linked" to a specific input element by the for attribute:
<label for='x`>click</label>
and the id attribute no the linked input:
<input type='checkbox' id='x'>
For the method to work, the input element must to be placed before whatever element(s) it is intended to control via CSS.
In real-word use cases, one would often want to use the CSS-toggling features of a checkbox over next siblings, but to obscure the fact there is a checkbox involved. The best way is by applying the hidden attribute on the input, which only toggles off the rendering of the input, nothing else.
The example below showcase such use case for a simple accordion component:
Practical example: Accordion
.accordion{ width: 300px; border: 1px solid silver; }
.accordion label{ display:block; padding:1em; cursor:pointer; }
.accordion label:hover{ color:red; }
.accordion > div:not(:last-child){ border-bottom:1px solid silver; }
.accordion .more{ max-height:0; transition:.5s; color:green; padding:0 1em; overflow: hidden; }
/* checked toggled */
.accordion input:checked + .content{ background:#EEE; }
.accordion input:checked + .content .more{ max-height:200px; }
<div class='accordion'>
<div>
<input type='checkbox' id='checkbox_item_1' hidden>
<div class='content'>
<label for='checkbox_item_1'>Title 1</label>
<div class='more'>
<p>This is cool<p>
<p>Yes it is</p>
</div>
</div>
</div>
<div>
<input type='checkbox' id='checkbox_item_2' hidden>
<div class='content'>
<label for='checkbox_item_2'>Title 2</label>
<div class='more'>
<p>This is also cool</p>
<p>So much fun</p>
</div>
</div>
</div>
</div>
You can hide the checkbox with visibility: hidden; or opacity: 0; besides display: none; but i'm not sure which one is better.

Change checkbox label css property with checkbox checked

I have the following html:
<label>
<input type="checkbox" value="cb_val" name="cb_name">
my checkbox text
</label>
With CSS I added a background-color to the <label> tag.
label { background-color:#333; color:#FFF; }
Now I'd liked to change the background color of the label when the checkbox is checked.
I know how to do it with javascript, but is there a way to to it just using CSS?
I have seen some solutions, but they use the adjacent sibling selector and only work when the label appears after the checkbox.
I still hope to fix this without javascript, does anyone have a clue?
UPDATE:
As I was afraid of, it cannot be done this way, so i must do it with JS, or achieve the same visual effect with a different HTML structure.
I want to set the background color of the label and the textbox in one go, so I can go with a solution where the checkbox is placed absolute on top of the label. Good point PlantTheldea!
Or I can apply the background color to the label and the checkbox both.
Thanks everyone!
You can achieve this with pure css like so,
<input type="checkbox" id="cb_1" value="cb_val" name="cb_name">
<label for="cb_1">
my checkbox text
</label>
With this css,
label { background-color:#333; color:#FFF; }
input[type="checkbox"]:checked + label {
background: brown;
}
JSFIDDLE
Keep in mind
The label has to be after the checkbox so you will need to style it around more to keep the same look you had.
Here is an option of styling it more to have the same appearance as you wanted, New fiddle. THIS DOES NOT involve positioning anything absolute, just some trickery.
You can't style the label itself directly via only CSS when the label is checked, but you can style a sibling of the checkbox.
http://jsfiddle.net/QdDpL/
HTML
<label>
<input class="check" type="checkbox" />
<span class="label-text">Checkbox</span>
</label>
CSS
label {
background: yellow;
}
label .label-text {
background: cyan;
}
label input.check:checked + .label-text {
background: lime;
}
You may also be able to fiddle with floats and padding to make the checkbox appear as if it was inside the .label-text span.
See the following links for browser support on the sibling selector:
http://caniuse.com/css-sel2
Alternately as another answer said, you can style the label if it is a sibling of the checkbox - but then just like my answer still would not contain the checkbox in the label.

Chrome/webkit not rendering css display change on input:checked + element + element

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