Unhide div when checkbox is checked - html

I am trying to create a responsive navbar, so when you click a hidden checkbox the content unhides.
The problem is, I can't get the "checked" css to actually pick up and do anything.
Example to run here: http://codepen.io/anon/pen/KNvvZy
CSS:
#nav-hidden{background: red; display: none;}
#navigation-mobile{display:none;}
/* DESKTOP */
#media only screen and (max-width: 1200px) {
#navigation-mobile {display: block;}
#menu-toggle:checked ~ #nav-hidden {
opacity: 1;
height: 100vh;
visibility: visible;
}
.label-toggle {
cursor: pointer;
display: block;
float: right;
}
}
HTML:
<div id="navigation-mobile">
<input type="checkbox" id="menu-toggle">
<label for="menu-toggle" class="label-toggle"></label>
</input>
<div id="nav-hidden">
<ul>
<li>test</li>
<li>test</li>
</ul>
</div>
</div>

In your example, on the original state you have:
#nav-hidden{display:none;}
So, you'll need to reset it on :checked state:
#menu-toggle:checked ~ #nav-hidden {display:block;}
Also want to point out that, you can animate height, opacity, visibility etc., but you can't animate display property.
The <input> element is a self-closing tag, you can do <input> or <input />, but you can't do <input></input>.
#nav-hidden {
display: none;
}
#menu-toggle:checked ~ #nav-hidden {
display: block;
}
<div id="navigation-mobile">
<input type="checkbox" id="menu-toggle">
<label for="menu-toggle" class="label-toggle"></label>
<div id="nav-hidden">
<ul>
<li>test</li>
<li>test</li>
</ul>
</div>
</div>

Related

HTML,CSS How do i prevent the expand/show from hiding/collapsing

hello how do i prevent the content from collapsing/hiding when i click on Content 1 or 2
.details,
.show,
.hide:target {
display: none;
color: black;
}
.hide:target+.show,
.hide:target~.details {
display: block;
color: black;
}
<a id="hide1" href="#hide1" class="hide">+ Content</a>
<a id="show1" href="#show1" class="show">- Content</a>
<div class="details">
<ul>
<li>Content1</li>
<li>Content2</li>
</ul>
</div>
.hide {
cursor: pointer;
}
.hide::before {
content: '+ Content';
display: block;
}
.hide::after {
content: '- Content';
display: none;
}
.details {
display: none;
transition:all 0.4s linear;
}
input:checked ~ .details,
input:checked + .hide::after {
display: block;
}
input:checked + .hide::before {
display: none;
}
<input id="toggle" type="checkbox" style="visibility:hidden">
<label for="toggle" class="hide"></label>
<div class="details">
<ul>
<li>Content1</li>
<li>Content2</li>
</ul>
</div>
Anchor tags reload the pages and thus the main div is collapsing.
You can either use this.
<li>Content1</li>
<li>Content2</li>
Or if you still want to use href then return false on click which will prevent it from reloading the page.
<li>Content1</li>
<li>Content2</li>
The problem with target is that it disappears from the content +/- when the user clicks on something else.
To remember whether the content + or - has been clicked you can use a checkbox.
If you make the +/- content into labels instead of divs then they can be associated with the checkbox (using for=) and you can hide the actual checkbox.
#showhide {
position: absolute;
opacity: 0;
}
#showhide~#show {
display: block;
}
#showhide:checked~#show {
display: none;
}
#showhide~#hide {
display: none;
}
#showhide:checked~#hide {
display: block;
}
#showhide~.details {
display: none;
}
#showhide:checked~.details {
display: block;
}
<input id="showhide" type="checkbox">
<label for="showhide" id="show">+ Content</label>
<label for="showhide" id="hide">- Content</label>
<div class="details">
<ul>
<li>Content1</li>
<li>Content2</li>
</ul>
</div>

Changing the Style of a specific element by Checkbox:Checked

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>

Responsive design: getting content in middle to flow

I have a layout where there is a button either side of the screeen.
The content is between the buttons.
How can I make the content display between the buttons when the view is large enough, but drop down and fill remaining space when the content starts to overlap the space between the buttons.
The buttons are a fixed size
nav ul li:first-child {
float: left;
}
nav ul li:last-child {
float: right;
}
nav ul li:first-child,
nav ul li:last-child {
display: table-cell;
}
<nav role="navigation">
<ul>
<li>
<input type="submit" value="Back">
</li>
<li>
<button>next</button>
</li>
</ul>
</nav>
<div id="content">
<input type="text" />
<input type="text" />
<input type="text" />
</div>
<p>"#content" should extract itself from between buttons to next 'line' when page gets smaller, then when that is too small as well, it can start blocking up the inputs.</p>
Fiddle here: https://jsfiddle.net/8g25hjw5/
By doing something like this:
<nav role="navigation">
<ul>
<li>
<input type="submit" value="Back">
</li>
<li>
<button>next</button>
</li>
</ul>
</nav>
<div id="content">
<div>
<input type="text" />
<input type="text" />
<input type="text" />
</div>
</div>
ul {
list-style: none;
}
nav ul li:first-child {
float: left;
}
nav ul li:last-child {
float: right;
}
#content {
display: table;
}
#content div {
display: table-row;
}
#content input {
display: table-cell;
}
#media screen and (max-width: 700px) {
#content {
clear: both;
}
}

show content when hover

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

marker image with constant height and width of container

I have got a menu list:
<ul>
<li class="marked">First item</li>
<li>Second much longer than first item</li>
</ul>
I would like to have an image marker on top of item.marked which width will be 100% of text width. The image must stretch so it will be completely visible. Height is constant.
Can this be done with CSS and IE compatibility?
<style type="text/css">
.selected {
background:url("example.png") no-repeat 0 100%;
}
</style>
Solutions for changing background of list item (can be adapted to change an image):
1. CSS-only, persistent, works for current versions of browsers (doesn't work for IE8 and older) - DEMO.
HTML:
<ul>
<li>
<input type="radio" name="s" id="o1" checked>
<label for="o1">First item</label>
</li>
<li>
<input type="radio" name="s" id="o2">
<label for="o2">Second much longer than first item</label>
</li>
</ul>
Relevant CSS:
ul input[type=radio] {
display: none;
}
input[type=radio]:checked + label {
background: lightblue;
}
If you want to have an image (with img tag) above the selected items, then you can adapt it like in this demo.
HTML:
<ul>
<li>
<input type="radio" name="s" id="o1" checked>
<label for="o1">First item
<img src="http://upload.wikimedia.org/wikipedia/commons/5/5b/Supernumerary_rainbow_03_contrast.jpg">
</label>
</li>
<li>
<input type="radio" name="s" id="o2">
<label for="o2">Second much longer than first item
<img src="http://upload.wikimedia.org/wikipedia/commons/5/5b/Supernumerary_rainbow_03_contrast.jpg">
</label>
</li>
</ul>
And add the following CSS:
label img {
top: 0;
width: 100%;
height: 100%;
display: none;
position: absolute;
}
input[type=radio]:checked + label img {
display: block;
}
If you don't want to do it with an img tag, then you can use a background-image on a pseudo-element and set the background-size to 100% 100%, like in this demo. The HTML is the same as in the first demo and you need to also have this in the CSS:
label {
position: relative;
}
input[type=radio]:checked + label:after {
top: 0;
right: 0;
bottom: 0;
left: 0;
position: absolute;
background: url(http://upload.wikimedia.org/wikipedia/commons/5/5b/Supernumerary_rainbow_03_contrast.jpg);
background-size: 100% 100%;
content: '';
}
2. CSS-only, not persistent (list item does not stay selected when you click somewhere else on the page), works for IE8 (and also IE7, but you have to hover off the text to see the change) - DEMO.
HTML:
<ul>
<li>First item</li>
<li>Second much longer than first item</li>
</ul>
Relevant CSS:
a:active, a:focus {
outline: none;
background: lightblue;
}