How to change a CSS checkbox label icon when checked WITHOUT JAVASCRIPT - html

I have a hamburger menu with no javascript (I can't use it, that's the assignment) using a label icon from FontAwesome and I want the icon to change to another one when the checkbox is checked, I just have no idea how to do that. I've checked online and apparently it's not possible without JS but I rather ask just in case.
The icon is directly inside the label using class and I know i can add as many labels as I want and they're just gonna stack up, but I don't know how to hide/show one of them depending on the status of the checkbox or if there's another way:
<div id="hamburger">
<img src="thelogo.png" alt="logo">
<input type="checkbox" id="button">
<label for="button" class="fas fa-bars"></label>
<ul class="items">
<li>EPISODES</li>
<li>INTERVIEWS</li>
<li>ABOUT US</li>
</ul>
</div>

You could use multiple icons and show/hide whichever you want.
<input type="checkbox" id="button">
<label for="button" class="fas fa-bars"></label>
<label for="button" class="fas arrow-circle-up"></label>
#button:checked ~ .fa-bars {
display: none;
}
#button:checked ~ .arrow-circle-up {
display: inline-block;
}
Or a more elegant way would be to update the content of the icon code.
#button ~ label::before {
content: '\f0c9'; // bars code
}
#button:checked ~ label::before {
content: '\f0aa'; // arrow up code
}
Heres a cheatsheet of all the icon codes

To change the label icon when the checkbox is checked, use :before pseudo element.
Example
JsFiddle
html
<input type="checkbox" id="button">
<label for="button" class="fas"></label>
css
#button {
display: none;
}
#button + label:before {
content: "\f0c9";
}
#button:checked + label:before {
content: "\f0aa";
}

Use the pseudo class :checked : https://css-tricks.com/almanac/selectors/c/checked/
Example :
#button:checked + label {
background : red;
}
#button:checked + label {
background : blue;
}
That will change the background of your label when the checkbox is checked or not

If you are using React you can simply do this:
<span>
<Input type="checkbox" id="button" checked={isChecked} onChange={handleChange}/>
{isChecked ? <FontAwesomeIcon icon={faCheckSquare} /> : <FontAwesomeIcon icon={faSquare} /> }
{value}
</span>

Related

Icon color not changing when focusing on input

I have been trying a couple of methods here to make my font-awesome icon colored white as I focus on my input... but nothing seems to work.
My code looks like this:
HTML
<div id="container">
<form id="form">
<input type="password" placeholder="Code" required id="input">
<div class="icon"><i class="fas fa-user-secret"></i></div>
<hr>
<br>
<center>
<button id="submit" type="submit">Submit</button>
</center>
</form>
</div>
I've tried doing:
input:focus + .fas-fa-user-secret {
color: #fff;
}
input:focus + .fas {
color: #fff;
}
input:focus + .i {
color: #fff;
}
But none of the above CSS code works. Not even the text in the input is white, but whenever I remove the + and the rest it does work for input.
Any help on this is appreciated, looked at every thread about making icons a different color when focusing on input.
Thanks.
You need to use input:focus+.icon since you have your icon inside the .icon div.
input:focus+.icon {
color: #ff0000;
}
input:focus {
color: red;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div id="container">
<form id="form">
<input type="password" placeholder="Code" required id="input">
<div class="icon"><i class="fas fa-user-secret"></i></div>
<hr>
<br>
<center>
<button id="submit" type="submit">Submit</button>
</center>
</form>
</div>
The problem is that you are using general sibling combinator, which select its siblings right after it, which is a <div>, not the icon.
input:focus + .fas-fa-user-secret {
color: #fff;
}
What you may want to do is set color: inherit to the icon, and then set desiring color for the div via this CSS selector and it will be fine
input:focus + div {
//your style
}

How to disable submit button & links on-click in pure CSS?

I have challenged myself to create a visually dynamic and interactive experience in HTML and CSS only (No Javascript). So far, I haven't come across any feature I needed that I couldn't do in pure CSS and HTML. This one is perhaps a bit more difficult.
I need to prevent the user from double-clicking<a>, <input type="submit"> and <button> tags. This is to prevent them double-submitting a form or accidentally making 2 GET requests to a URL. How can this be done in pure CSS? Even if we can't set disabled without JS, there should be some masking technique or combination of styles that can handle it here in 2020.
Here is a simple example of an attempt:
.clicky:focus{
display: none;
pointer-events: none;
}
test
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p id="down">target</p>
Unfortunately, this disables it before the actual click event is fired for some reason. Maybe anchors aren't the best way to test? I will continue to make further attempts.
One idea is to have a layer that come on the top of the element after the first click to avoid the second one.
Here is a basic idea where I will consider a duration of 1s between two clicks that you can decrease. Try to click the button/link and you will notice that you can click again only after 1s.
I am adding a small overlay to better see the trick
.button {
position:relative;
display:inline-block;
}
.button span{
position:absolute;
top:0;
left:0;
right:0;
bottom:100%;
z-index:-1;
animation:overlay 1s 0s; /* Update this value to adjust the duration */
transition:0s 2s; /* not this one! this one need to be at least equal to the above or bigger*/
}
.button *:active + span {
animation:none;
bottom:0;
transition:0s 0s;
}
#keyframes overlay {
0%,100% {
z-index:999;
background:rgba(255,0,0,0.2); /* To illustrate */
}
}
<div class="button">
<button>Click me</button>
<span></span>
</div>
<div class="button">
Click me
<span></span>
</div>
The first solution
The idea is to use radio button state by :checked to make modifications. We hide radio circle and when :checked for <a> make pointer-events: none; and for buttons with different types we hide them and show disabled ones.
div {
margin: 10px;
}
#radio0, .my-checkbox {
position: absolute;
height: 0;
width: 0;
opacity: 0;
}
#radio0 + a label {
cursor: pointer;
}
#radio0:checked+a {
pointer-events: none;
}
.btn-one,
.btn-two {
padding: 0;
}
.btn-one>label,
.btn-two>label {
padding: 1px 6px;
}
.my-checkbox:checked+.btn-one {
display: none;
}
.btn-two {
display: none;
}
.my-checkbox:checked+.btn-one+.btn-two {
display: inline-block;
}
<div>
<input id="radio0" type="radio" onclick="console.log('radio0 clicked!')">
<a href="#">
<label for="radio0">
Click the link!
</label>
</a>
</div>
<div>
<input type="radio" id="radio1" class="my-checkbox">
<button type="button" class="btn-one" onclick="console.log('radio1 clicked!')">
<label for="radio1">Click the button!</label>
</button>
<button type="button" class="btn-two" onclick="console.log('radio1 NOT clicked!')" disabled>
<label for="radio1">Click the button!</label>
</button>
</div>
<div>
<input type="radio" id="radio2" class="my-checkbox">
<button type="submit" class="btn-one" onclick="console.log('radio2 clicked!')">
<label for="radio2">Submit!</label>
</button>
<button type="submit" class="btn-two" onclick="console.log('radio2 NOT clicked!')" disabled>
<label for="radio2">Submit!</label>
</button>
</div>
The second solution
This one suits for links. The idea is to use :target. Targe element is hidden firstly. Then when is targeted use :target to pointer-events: none; of <a>.
#anchor {
display: none;
}
#anchor:target {
display: block;
}
#anchor:target+a {
pointer-events: none;
}
<div>
<span id="anchor"></span>
Click the link!
</div>

How to create a drop-down menu in HTML

The assignment I'm working on asks to create a dropdown menu such as the one in the link. How would i do this?
You could use details and summary HTML5 elements (if IE and Opera Mini are not a big concern; for those the below example will fallback gracefully)
<details>
<summary>Please fill out our optional survey</summary>
<p>What year are you in college?</p>
<label><input type="radio" name="clg" value="0"> Not yet there</label>
<label><input type="radio" name="clg" value="1"> Junior</label>
<label><input type="radio" name="clg" value="2"> Senior</label>
</details>
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary
http://html5doctor.com/the-details-and-summary-elements/
Find also other ways to Toggle an element
To recreate the above in JavaScript here's a ES6 example:
[...document.querySelectorAll('[data-details]')].forEach( el =>
el.addEventListener('click', () => {
document.querySelector(el.getAttribute('data-details')).classList.toggle('hide');
el.classList.toggle('open');
el.setAttribute('aria-expanded', el.classList.contains('open'));
})
);
[data-details] {
display: block;
width: 100%;
-webkit-appearance: none;
background: none;
border: none;
text-align: left;
font: inherit;
}
[data-details]:before { content: "\25ba"; speak: none; }
[data-details].open:before { content: "\25bc"; speak: none; }
.hide{ display: none; }
<button type="button" data-details="#d1" aria-describedby="d1" aria-expanded="false" >Summary 1</button>
<div id="d1" class="hide">CONTENT ONE</div>
<button type="button" data-details="#d2" aria-describedby="d2" aria-expanded="false">Summary 2</button>
<div id="d2" class="hide">CONTENT TWO</div>
As another answer pointed out, you can use the details and summary elements, but they are poorly supported, only usable in Chrome and Firefox, if you need a solution that works in IE, Edge, and Safari, you need to use javascript, thankfully, this is very simple.
<div id="summary" onclick="toggle();">Summary</div>
<div id="togglable" style="display:none;">Toggleable text</div>
<script>
var i=0;//Counter
function toggle(){//Function called when Summary is clicked
if(i%2===0){//Even number
document.getElementById("toggle").style.display="initial";//Make it visible
}else{//Odd number
document.getElementById("toggle").style.display="none";//Visible
}
i++;
if(i===2){
i=0;//Reset i to ensure it doesn't get too big
}
}
</script>

CSS Radio-Boxes do nothing

I´ve got a problem with my Web-Design: I want content box to open when a specific radio button is activated with
input#topic1:checked ~ #content1{
color:yellow;
}
but nothing happens. Rest of code is in this jsfiddle. I bet the answer is really easy but I tried a lot and didn´t found any question which answeres this.
Thanks for any effords
Tim
The problem is that the ~ selector works with siblings that share the same parent, in your case the parent is body but the content divs are inside label, so you should target it like this:
input#topic1:checked ~ label #content1 {
color: yellow;
}
input#topic2:checked ~ label #content2 {
color: yellow;
}
input#topic3:checked ~ label #content3 {
color: yellow;
}
See jsFiddle fork: https://jsfiddle.net/azizn/k8gxzq56/
First you don't have to close input tags as sais #Aziz
Then, I use javascript to do this.
See this fiddle
$(function(){
$("input[type=radio]").on('click', function(){
$('.contentbox').removeClass('yellow');
// get the target link
target = $(this).data('href');
$("#"+target).addClass('yellow');
});
});
Rearranged your code to make it work with CSS only.
.contentbox{
width:100vw;
height:10vw;
}
#content1{
background:#0000FF;
}
#content2{
background:#FF0000;
}
#content3{
background:#00FF00;
}
input#topic1:checked + .content1{
color:yellow;
}
input#topic2:checked + .content2{
color:yellow;
}
input#topic3:checked + .content3{
color:yellow;
}
<input type="radio" name="topic" class="topic_selection, topic1" id="topic1">
<label for="topic1" class="content1">
<div class="contentbox" id="content1">
<h1>Text 1</h1>
</div>
</label>
<input type="radio" name="topic" class="topic_selection" id="topic2">
<label for="topic2" class="content2">
<div class="contentbox" id="content2">
<h1>Text2</h1>
</div>
</label>
<input type="radio" name="topic" class="topic_selection" id="topic3">
<label for="topic3" class="content3">
<div class="contentbox" id="content3">
<h1>Text3</h1>
</div>
</label>

Overlay a div inside a list item

I'm trying to implement auto-complete inside a form item, where as the user types it creates a dropdown menu with a list of suggestions, which are clickable. This is done inside the Ionic Framework.
I've made a codepen to demonstrate what I want. (look at the auto-complete field, and the grey hidden box below it)
http://codepen.io/pbernasconi/pen/Cgobi
My dropdown:
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">License #</span>
<input type="text" placeholder="AUTO COMPLETE FIELD">
<div class="input-dropdown">
<ul class="input-dropdown-menu">
<li>...</li>
</ul>
</div>
</label>
</div>
My CSS:
.input-dropdown {
position: absolute;
background: grey;
border: solid 1px #000;
z-index: 1001;
overflow: visible;
}
.input-dropdown-menu {
}
This issue is that position: absolute doesn't allow me to overlay over the list item below the auto-complete field, as you can see in the codepen.
Here's an example of a solution, which for some reason doesn't work for me.
Does anyone know how to implement this dropdown to overlay over it's parent's?
The label item overflow is hidden and the dropdown list is inside it, so you can't see it.
// jquery code
$(document).ready(function() {
$("#test").focus(function(){
$(".input-dropdown-menu").show();
});
$("#test").mouseleave(function(){
$(".input-dropdown-menu").hide();
});
});
//use css
input-dropdown {
position: absolute;
background: grey;
border: solid 1px #000;
z-index: 1001;
overflow: visible;
margin-left:65px;
}
.input-dropdown-menu {
display:none;
}
//use html
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">License #</span>
<input type="text" placeholder="AUTO COMPLETE FIELD" id ="test">
<div class="input-dropdown">
<ul class="input-dropdown-menu">
<li>111</li>
<li>111</li>
<li>111</li>
</ul>
</div>