This question already has answers here:
Can I have an onclick effect in CSS?
(14 answers)
Closed 3 years ago.
I tried many ways to change the color of the border of my image when the checkbox is checked and I didn't find a solution. I start wondering if it's possible.
.thumbs {
list-style:none;
margin:0;
padding:0.3em 0;
text-align:center;
color:#fff;
}
.thumbs li {
position:relative;
display:inline-block;
margin:0.2em;
border:0.30em solid #000000 ;
border-radius:0.3em;
}
.thumbs li:hover { border-color: #59b359; }
input[type=checkbox]:checked + .thumbs li { border-color: #ff0000; }
<form id="formdelete">
<ul class="thumbs">
<li class="img">
<label for="SNAP_CH01.jpg">
<img src="SNAP_CH01.jpg" title="CH1">
<input type="checkbox" name="todelete[]" value="SNAP_CH01" id="SNAP_CH01.jpg">
</li>
<li class="img">
<label for="SNAP_CH02.jpg">
<img src="SNAP_CH02.jpg" title="CH2">
</label>
<input type="checkbox" name="todelete[]" value="SNAP_CH02" id="SNAP_CH02.jpg">
</li>
<li class="img">
<label for="SNAP_CH03.jpg">
<img src="SNAP_CH03.jpg" title="CH3">
</label>
<input type="checkbox" name="todelete[]" value="SNAP_CH03" id="SNAP_CH03.jpg">
</li>
</form>
The border should be red when the checkbox is checked
EDIT :
I find a solution using the link :
I have to change the order of the checkbox but it's work fine :
<ul class="thumbs">
<li class="img">
<input type="checkbox" name="todelete[]" value="SNAP_CH01" id="SNAP_CH01.jpg">
<label for="SNAP_CH01.jpg">
<img src="SNAP_CH01.jpg" title="CH1">
</label>
</li>
label > img {
display: block;
border: 3px solid #000000 ;
}
input[type=checkbox]:checked + label > img { border: 3px #FF0000 solid ;}
So, the adjacent sibling selector + https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator will target the element immediately AFTER the element being referenced.
In your code, input[type=checkbox]:checked + .thumbs li it is looking for a class for thumbs immediately after the checkbox. In this case, .thumbs is the name of the (grand) parent UL item.
The most important letter in CSS is the C -- Cascading. The styles move down the DOM tree, you will need creative ways to affect something above.
Related
I have looked at the different questions regarding this issue, but couldn't find anything that works due to limitations in my markup.
My markup looks like so (unfortunately as this is generated by some backend, I am unable to change the markup).
<ul>
<li>
<input type="checkbox" value="1" name="test[]" id="myid1">
<label for="myid1">label1</label>
</li>
<li>
<input type="checkbox" value="2" name="test[]" id="myid2">
<label for="myid2">label1</label>
</li>
</ul>
I need the checkbox to be on the right and centered vertically in the <li>
Currently, this is styled as:
li input{
display: inline-block;
float: right;
margin-right: 10px;
}
I have tried using various values for vertical-align, but that doesn't seem to help. Also, in some cases the label can be very long and span multiple lines. The checkbox would still need to be able to vertically center itself when the height of the li is arbitrary.
How can I go about achieving this?
Vertical alignment only works on inline elements. If you float it, then I don't think it is treated as part of that stream of inline elements any more.
Make the label an inline-block, and use vertical alignment on both the label and the input to align their middles. Then, assuming it is okay to have a specific width on the labels and checkboxes, use relative positioning instead of floating to swap them (jsFiddle demo):
input {
width: 20px;
position: relative;
left: 200px;
vertical-align: middle;
}
label {
width: 200px;
position: relative;
left: -20px;
display: inline-block;
vertical-align: middle;
}
Its not a perfect solution, but a good workaround.
You need to assign your elements to behave as table with display: table-cell
Solution: Demo
HTML:
<ul>
<li>
<div><input type="checkbox" value="1" name="test[]" id="myid1"></div>
<div><label for="myid1">label1</label></div>
</li>
<li>
<div><input type="checkbox" value="2" name="test[]" id="myid2"></div>
<div><label for="myid2">label2</label></div>
</li>
</ul>
CSS:
li div { display: table-cell; vertical-align: middle; }
The most effective solution that I found is to define the parent element with display:flex and align-items:center
LIVE DEMO
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.myclass{
display:flex;
align-items:center;
background-color:grey;
color:#fff;
height:50px;
}
</style>
</head>
<body>
<div class="myclass">
<input type="checkbox">
<label>do you love Ananas?
</label>
</div>
</body>
</html>
OUTPUT:
<div>
<input type="checkbox">
<img src="/image.png" />
</div>
input[type="checkbox"]
{
margin-top: -50%;
vertical-align: middle;
}
This works reliably for me. Cell borders and height added for effect and clarity:
<table>
<tr>
<td style="text-align:right; border: thin solid; height:50px">Some label:</td>
<td style="border: thin solid;">
<input type="checkbox" checked="checked" id="chk1" style="cursor:pointer; "><label for="chk1" style="margin-top:auto; margin-left:5px; margin-bottom:auto; cursor:pointer;">Check Me</label>
</td>
</tr>
</table>
Add CSS:
li {
display: table-row;
}
li div {
display: table-cell;
vertical-align: middle;
}
.check{
width:20px;
}
ul{
list-style: none;
}
<ul>
<li>
<div><label for="myid1">Subject1</label></div>
<div class="check"><input type="checkbox" value="1"name="subject" class="subject-list" id="myid1"></div>
</li>
<li>
<div><label for="myid2">Subject2</label></div>
<div class="check" ><input type="checkbox" value="2" class="subject-list" name="subjct" id="myid2"></div>
</li>
</ul>
make input to block and float, Adjust margin top value.
HTML:
<div class="label">
<input type="checkbox" name="test" /> luke..
</div>
CSS:
/*
change margin-top, if your line-height is different.
*/
input[type=checkbox]{
height:18px;
width:18px;
padding:0;
margin-top:5px;
display:block;
float:left;
}
.label{
border:1px solid red;
}
Demo
I am using a checkbox as a way to modify the other element's style. Is it possible for a checkbox to affect other classes/elements of the website.
I have a sample html code below, instead of changing label element, is it possible to change the styling of the first div instead.
ul li {
display: inline-block;
}
ul li input[type="checkbox"]:checked+label {
border: 2px solid gray;
background-color: gray;
color: #fff;
transition: all .2s;
}
ul li {
padding: 20px;
margin: 20px;
}
ul li input[type="checkbox"] {
display: absolute;
}
ul li input[type="checkbox"] {
position: absolute;
opacity: 0;
}
ul li label {
padding: 20px;
cursor: pointer;
}
<div class="modify-box">
BOX TO CHANGED
</div>
<ul>
<li>
<input type="checkbox" id="vehicle1" name="vehicle1" value="Bike">
<label for="vehicle1"> Bike</label><br>
</li>
<li>
<input type="checkbox" id="vehicle2" name="vehicle2" value="Car">
<label for="vehicle2"> Car</label><br>
</li>
<li>
<input type="checkbox" id="vehicle3" name="vehicle3" value="Boat">
<label for="vehicle3"> Boat</label><br>
</li>
</ul>
There is a way to make this happen, but it's to use exactly the same "trick" with which you style the <label> elements, specifically by moving the <input> elements ahead of the element you wish to style.
With that in mind, if the <input> elements are preceding siblings of the <div>, then checking, and unchecking, the <input> can have an effect on the <div>, and also the original <label> elements as well.
As a crude example:
input[type="checkbox"][name^="vehicle"] {
display: absolute;
position: absolute;
opacity: 0;
}
/* styles the <div> based on the checked/unchecked state
of the <input> (this example assumes that the same
highlight colour should be used regardless of which
<input> is checked: */
input[type="checkbox"][name^="vehicle"]:checked ~ div {
background-color: #ccc;
}
/* this is where it becomes obvious that JavaScript (or,
ideally, a CSS selector that can refer to an attribute-
variable) makes more sense; though with a CSS
pre-processor this can be written effectively enough.
Here when the #vehicle1 element is checked the <label>
descendents with a "for" attribute equal to "vehicle1" of
later-sibling <ul> elements are selected and styled: */
#vehicle1:checked~ul label[for=vehicle1] {
background-color: gray;
}
/* as above, for the "vehicle2" id and for attributes: */
#vehicle2:checked~ul label[for=vehicle2] {
background-color: gray;
}
#vehicle3:checked~ul label[for=vehicle3] {
background-color: gray;
}
ul li {
display: inline-block;
padding: 20px;
margin: 20px;
}
ul li label {
padding: 20px;
cursor: pointer;
}
<input type="checkbox" id="vehicle1" name="vehicle1" value="Bike">
<input type="checkbox" id="vehicle2" name="vehicle2" value="Car">
<input type="checkbox" id="vehicle3" name="vehicle3" value="Boat">
<div class="modify-box">
BOX TO CHANGED
</div>
<ul>
<li>
<label for="vehicle1"> Bike</label><br>
</li>
<li>
<label for="vehicle2"> Car</label><br>
</li>
<li>
<label for="vehicle3"> Boat</label><br>
</li>
</ul>
With only CSS this won't be possible. You are restricted by the current selectors and there are no parent selectors in CSS. You can use a bit of JS to target the element you want.
What would you like to happen in the box surrounding the checkboxes? Maybe there would be another solution with a :before or :after on the label?
I think you need JavaScript for that. You could listen for the change event and style if no checkbox is checked.
First you need to select the containing list element and attach an event listener to it:
document.querySelector('ul').addEventListener('change', function(e) {...});
In the handler function of the listener you have to check if there is a checked checkbox and depending on that check style your .modify.box (or toggle a class, for example .checked):
if (document.querySelector('input:checked')) {
modify_box.classList.add('checked');
}
else {
modify_box.classList.remove('checked');
}
If you decide to toggle a class you need to add that class to your CSS-definition. For example:
ul li input[type="checkbox"]:checked+label,
.checked {...}
Working example:
const modify_box = document.querySelector('.modify-box');
document.querySelector('ul').addEventListener('change', function(e) {
if (document.querySelector('input:checked')) {
modify_box.classList.add('checked');
}
else {
modify_box.classList.remove('checked');
}
});
ul li {
display: inline-block;
}
ul li input[type="checkbox"]:checked+label,
.checked {
border: 2px solid gray;
background-color: gray;
color: #fff;
transition: all .2s;
}
ul li {
padding: 20px;
margin: 20px;
}
ul li input[type="checkbox"] {
display: absolute;
}
ul li input[type="checkbox"] {
position: absolute;
opacity: 0;
}
ul li label {
padding: 20px;
cursor: pointer;
}
<div class="modify-box">
BOX TO CHANGED
</div>
<ul>
<li>
<input type="checkbox" id="vehicle1" name="vehicle1" value="Bike">
<label for="vehicle1"> Bike</label><br>
</li>
<li>
<input type="checkbox" id="vehicle2" name="vehicle2" value="Car">
<label for="vehicle2"> Car</label><br>
</li>
<li>
<input type="checkbox" id="vehicle3" name="vehicle3" value="Boat">
<label for="vehicle3"> Boat</label><br>
</li>
</ul>
I can make a label (checkbox) change the properties of a span class to display:block however, it only seems to work for the individual span class and not ALL spans that I have.
I would like to change the height of all li tags so, if the user clicks on just one "details" label, then it will change ALL of the li tags height. See below:
<div id="content">
<ul>
<li>
<p>#1 car is for sale</p>
<label class="details" for="_1">More details...</label>
<input id="_1" type="checkbox">
<span class="row">More elaborate details here</span>
</li>
<li>
<p>#2 car is for sale 2</p>
<label class="details" for="_2">More details...</label>
<input id="_2" type="checkbox">
<span class="row">More elaborate details here</span>
</li>
<li>
<p>#3 car is for sale</p>
<label class="details" for="_3">More details...</label>
<input id="_3" type="checkbox">
<span class="row">More elaborate details here</span>
</li>
</ul>
</div>
css:
#content {
width:100%;
margin:0 auto;
z-index:1;
text-align:left;
display:block;
}
#content ul{
width:auto;
display:inline-block;
list-style:none;
white-space: nowrap;
border:1px solid #00FF00;
}
.details{
display:inline;
width:auto;
color:blue;
}
.details + input{
display:none;
}
.details + input + *{
display:none;
}
.details+ input:checked + *{
display:block;
position:relative;
}
.details+ input:checked + #content ul li{
height:100px;
display:block;
position:relative;
}
Thanks in advance :)
You can use this:
input:checked + span.row {
display:block;
position:relative;
}
See it working:
http://jsfiddle.net/98y8whhu/
EDIT
You can see now the changes. I write a piece of javascript code to make all LI tags same height:
$('input[type="checkbox"]').on('change', function(e) {
var checked = $(this).prop('checked');
if(checked) {
var thisHeight = $(this).parents().find('li').height();
$('ul > li').height(thisHeight+"px");
} else {
$('ul > li').height('auto');
}
});
See it working: http://jsfiddle.net/98y8whhu/2/
I need to change style if i hover on media-body checkbox should show up
.media-body ul:hover input[type="checkbox"] {
display: block;
}
HTML:
<div class="media-body">
<ul>
<li><a style="float:left;">{{inventory.manufacturer}} {{inventory.model}}</a>
<li><input style="float:right; display: none;" type="checkbox" ng-model="inventory.checked" ng-checked="inventory.checked"></li><br/>
</ul>
</div>
Inline CSS has higher priority then outline, so you're changes are applied but are still overridden by your inline styles.
The simplest trick to make it work could be to set !important to your css.
.media-body ul:hover input[type="checkbox"] {
display: block !important;
}
JSFiddle: http://jsfiddle.net/WgQT5/
Anyway the right way would be to put inline styles outside of HTML.
Moreover your HTML is not valid. It should be
<div class="media-body">
<ul>
<li><a style="float:left;">{{inventory.manufacturer}} {{inventory.model}}</a></li> <!-- </li> missing -->
<li><input style="float:right; display: none;" type="checkbox" ng-model="inventory.checked" ng-checked="inventory.checked"/></li><!-- <br/> is invalid here and slash at the and of input was missing-->
</ul>
</div>
Your problem is that the inline style float: right; display: none; has higher priority than the style defined in CSS.
I would suggest to add a default style in CSS equivalent to the inline one and then override this one:
CSS:
.media-body ul input[type="checkbox"] {
float: right;
display: none;
}
.media-body ul:hover input[type="checkbox"] {
display: block;
}
HTML:
<div class="media-body">
<ul>
<li><a style="float:left;">{{inventory.manufacturer}} {{inventory.model}}</a></li>
<li><input type="checkbox" ng-model="inventory.checked" ng-checked="inventory.checked"></li>
</ul>
</div>
Only add !important and greater than selector
.media-body ul:hover > li input[type="checkbox"] {
display: block !important;
}
LIve code
What I'm trying to accomplish:
Removing the bottom border on the nested list-item element, but keeping the bottom border of its parent list-item element.
I'm trying to figure out if I can use a "universal selector", like ">*" to say: "For everything element that lives in this parent, make the border 0".
Question:
Is this possible?
See the fiddle: http://jsfiddle.net/VnLZH/
HTML:
<aside>
<b>What I'm trying to accomplish: </b><br>
1.) Removing the bottom border on the nested list-item element, but keeping the bottom border of its parent list-item element. <br>
2.) I'm trying to figure out if I can use a "universal selector", like ">*" to say: "For everything element that lives in this parent, make the border 0". <br><br>
<b>Question</b><br>
Is this possible?
</aside>
<h1>This works</h1>
<div class="option1">
<ul>
<li>Category</li>
<li>Category</li>
<li>Category</li>
<li>Category
<div>
<ul>
<li><input type="radio" name="radio" /> Option 1</li>
<li><input type="radio" name="radio" /> Option 2</li>
<li><input type="radio" name="radio" /> Option 3</li>
</ul>
</div>
</li>
<li>Category</li>
<li>Category</li>
</ul>
</div>
<h1>What I want to work</h1>
<div class="option2">
<ul>
<li>Category</li>
<li>Category</li>
<li>Category</li>
<li>Category
<div>
<ul>
<li><input type="radio" name="radio" /> Option 1</li>
<li><input type="radio" name="radio" /> Option 2</li>
<li><input type="radio" name="radio" /> Option 3</li>
</ul>
</div>
</li>
<li>Category</li>
<li>Category</li>
</ul>
</div>
CSS:
aside { background: #f2f2f2; margin: 1em 0; padding: .5em; }
h1 { margin: 1em 0 0; }
/* This works */
.option1 { }
.option1 ul { }
.option1 ul li { border-bottom: 1px solid black; }
.option1 ul li div ul li { border: none; }
/* What I want to work */
.option2 { }
.option2 ul { }
.option2 ul li { border-bottom: 1px solid black; }
.option2 ul li div >* { border: none; }
Your code (.option2 ul li div > *) doesn't work because the lists themselves have no borders, but the list items do. Thus, .option2 ul li div ul > * would work, but moreover, even specifying .option2 ul li * would target any element nested within a list item of the option2 list.
.option2 ul li { border-bottom: 1px solid black; }
.option2 ul li * { border: none; } //removes border on nested elements of any kind
I misunderstood
Just remove the ">" and you should be fine
http://jsfiddle.net/VnLZH/9/
.option2 ul li div * { border: none; }