Css :checked showing containers that shold be hidden - html

I am trying to do simple Tabs on my page, so I have 3 tabs and 3 sections for them. Problem is that in first section i can see all sections containers, in second 2 last and in this last. And it should be simple one section for one tab.
What am i missing?
My html and code https://codepen.io/wojsza/pen/XWMOXXm :
.display__tabs {
display: flex;
flex-wrap: wrap; }
.display__tabs--tab {
display: none; }
.display__tabs--tab:checked ~ .display__tabs--label ~ .display__tabs--content {
display: block; }
.display__tabs--label {
cursor: pointer;
padding: 25px;
color: #2e2e2e; }
.display__tabs--label:hover {
color: #aeaeae;
background-color: #2e2e2e;
font-weight: bold;
text-decoration: underline; }
.display__tabs--content {
width: 100%;
padding: 20px;
order: 1;
display: none; }
and html:
<div class="display__tabs">
<input type="radio" class="display__tabs--tab" id="display-module-info" name="module" checked="checked" />
<label class="display__tabs--label" for="display-module-info">Info</label>
<div class="display__tabs--content">
<p>Module</p>
</div>
<input type="radio" class="display__tabs--tab" id="display-module-wsu" name="module" />
<label for="display-module-wsu" class="display__tabs--label">Wsu</label>
<div class="display__tabs--content">
<p>
WSU
</p>
</div>
<input type="radio" class="display__tabs--tab" id="display-module-sections" name="module" />
<label for="display-module-sections" class="display__tabs--label">Sections</label>
<div class="display__tabs--content">
<p>
SECTION
</p>
</div>
</div>

You nearly there! Just need to change the "~" into "+".
You wanna change your css on this part :
From
.display__tabs--tab:checked ~ .display__tabs--label ~ .display__tabs--content {
display: block;
}
To
.display__tabs--tab:checked + .display__tabs--label + .display__tabs--content {
display: block;
}
This caused by the css selector of ~ which select the general sibling, and you wanted to use +, because the radio element that being set to hidden and block, is adjacent sibling. Reference https://levelup.gitconnected.com/understanding-use-of-the-and-symbols-in-css-selectors-95552eb436f5

You can just add a second class to radio inputs, and display__tabs--content. Then, you can just add CSS for each one of them.
.display__tabs {
display: flex;
flex-wrap: wrap;
}
.display__tabs--tab {
display: none;
}
.tab1:checked ~ .display__tabs--label ~ .display__tabs--content.content1 {
display: block;
}
.tab2:checked ~ .display__tabs--label ~ .display__tabs--content.content2 {
display: block;
}
.tab3:checked ~ .display__tabs--label ~ .display__tabs--content.content3 {
display: block;
}
.display__tabs--label {
cursor: pointer;
padding: 25px;
color: #2e2e2e;
}
.display__tabs--label:hover {
color: #aeaeae;
background-color: #2e2e2e;
font-weight: bold;
text-decoration: underline;
}
.display__tabs--content {
width: 100%;
padding: 20px;
order: 1;
display: none;
}
<div class="display__tabs">
<input type="radio" class="display__tabs--tab tab1" id="display-module-info" name="module" checked="checked" />
<label class="display__tabs--label" for="display-module-info">Info</label>
<div class="display__tabs--content content1">
<p>Module</p>
</div>
<input type="radio" class="display__tabs--tab tab2" id="display-module-wsu" name="module" />
<label for="display-module-wsu" class="display__tabs--label">Wsu</label>
<div class="display__tabs--content content2">
<p>
WSU
</p>
</div>
<input type="radio" class="display__tabs--tab tab3" id="display-module-sections" name="module" />
<label for="display-module-sections" class="display__tabs--label">Sections</label>
<div class="display__tabs--content content3">
<p>
SECTION
</p>
</div>
</div>

Related

How to include Vertical menu for tabs in HTML

I need to have vertical menu whenever I click each of my tab and show some items...When one item is clicked I need to see the content under each item. Here is the output I need..
So I have used below code but I have no idea about the menu items under each item.
body {
background: #ccc;
font-family: 'Roboto', sans-serif;
}
.mytabs {
display: flex;
flex-wrap: wrap;
max-width: 600px;
margin: 50px auto;
padding: 25px;
}
.mytabs input[type="radio"] {
display: none;
}
.mytabs label {
padding: 25px;
background: #e2e2e2;
font-weight: bold;
}
.mytabs .tab {
width: 100%;
padding: 20px;
background: #fff;
order: 1;
display: none;
}
.mytabs .tab h2 {
font-size: 3em;
}
.mytabs input[type='radio']:checked + label + .tab {
display: block;
}
.mytabs input[type="radio"]:checked + label {
background: #fff;
}
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght#400;700&display=swap" rel="stylesheet">
<body>
<div class="mytabs">
<input type="radio" id="tab1" name="mytabs" checked="checked">
<label for="tab1">Free</label>
<div class="tab">
<h2>tab1</h2>
</div>
<input type="radio" id="tab2" name="mytabs">
<label for="tab2">Silver</label>
<div class="tab">
<h2>tab2</h2>
</div>
<input type="radio" id="tab3" name="mytabs">
<label for="tab3">Gold</label>
<div class="tab">
<h2>tab3</h2>
</div>
</div>
</body>
At the moment I could get the tabbed layout without items menu. Can someone show me how to improve my code?

Menu toggle with options inside using only CSS

I'm trying to create a menu with options inside. I'm using only CSS with checkbox and radio inputs.
By changing one of the options, I also want the menu to close. I tried this using label inside label, but it doesn't work.
My prototype code:
input {
display: none;
}
label {
cursor: pointer;
}
label span:hover {
font-weight: 600;
}
.opener .menu {
background-color: #f3f3f3;
display: flex;
flex-direction: column;
color: #4d4d4d;
padding: 12px 4px;
width: 270px;
}
#menu:checked~.opener .menu {
display: none;
}
#menu~.opener>span:nth-of-type(1) {
display: none;
}
#menu:~.opener>span:nth-of-type(2) {
display: block;
}
#menu:checked~.opener>span:nth-of-type(1) {
display: block;
}
#menu:checked~.opener>span:nth-of-type(2) {
display: none;
}
.box {
height: 50px;
width: 50px;
margin: 20px 0;
}
#red:checked~.box {
background-color: red;
}
#blue:checked~.box {
background-color: blue;
}
#green:checked~.box {
background-color: green;
}
<input id="menu" type="checkbox"></input>
<input id="red" type="radio" name="opcoes" checked></input>
<input id="blue" type="radio" name="opcoes"></input>
<input id="green" type="radio" name="opcoes"></input>
<label class="opener" for="menu"><span>Open</span><span>Close</span>
<div class="menu">
<label for="red"><span>red</span></label>
<label for="blue"><span>blue</span></label>
<label for="green"><span>green</span></label>
</div>
</label>
<div class="box"></div>
Or you can check here: https://codepen.io/anon/pen/JxzPKR
Is there a way to close the menu when you click on one of the options without JavaScript?
Sometimes, contrary to popular opinion, it's just more dev friendly to use Javascript.
There is too much conditional logic for this to be a pure CSS solution. There are ~3 if-then-else conditions you would have to satisfy, while keeping the styles cascading. I think the most arduous task to satisfy is that you have a toggle header, in addition to other controls toggling it.
This will inherently get more complex and convoluted the more components you add. But here is an example using :target. This is a work-around and provides a solution to the question at hand. You won't be able to 'toggle' the menu this way so I had to add the header under the elements so it can be accessed via some kind of sibling selector:
.menu {
position: relative;
width: 45%;
}
input[type="radio"] {
position: absolute;
opacity: 0;
height: 0;
width: 0;
}
a:any-link {
all: unset;
}
.menu-header {
position: absolute;
top: 0;
padding: 5px 10px;
color: white;
width: 100%;
background-color: cornflowerblue;
}
.menu-header a {
font-weight: bold;
cursor: pointer;
color: white;
font-size: 22px;
}
.menu-header .close {
display: none;
}
#menu-body {
display: none;
flex-flow: column nowrap;
position: absolute;
top: 34px;
background-color: rgba(220,220,220,1);
height: 100px;
color: black;
width: 100%;
padding: 10px;
}
.menu-header a,
#menu-body label {
cursor: pointer;
}
#menu-body:not(:target) {
display: none;
}
#menu-body:not(:target) + .menu-header > a:not(.close) {
display: inline-block;
}
#menu-body:target {
display: flex;
}
#menu-body:target + .menu-header > a {
display: none;
}
#menu-body:target + .menu-header > a.close {
display: inline-block;
}
<div class="menu">
<div id="menu-body">
<input id="red" type="radio" name="opcoes" checked/>
<label for="red">Red</label>
<input id="blue" type="radio" name="opcoes"/>
<label for="blue">Blue</label>
<input id="green" type="radio" name="opcoes"/>
<label for="green">Green</label>
</div>
<div class="menu-header">≡ Open≡ Close</div>
</div>
You should consider accessability using this method, or at minimum, how this effects site navigation.
Edit: A demo in regards to discussion in comments:
.menu {
position: relative;
width: 45%;
}
input[type="radio"] {
position: absolute;
opacity: 0;
height: 0;
width: 0;
}
a:any-link {
all: unset;
}
#menu-header {
position: absolute;
top: 0;
padding: 5px 10px;
color: white;
width: 100%;
background-color: cornflowerblue;
}
#menu-header a {
font-weight: bold;
cursor: pointer;
color: white;
font-size: 22px;
}
#menu-header .close {
display: none;
}
#menu-body {
display: none;
flex-flow: column nowrap;
position: absolute;
top: 34px;
background-color: rgba(220,220,220,1);
height: 100px;
color: black;
width: 100%;
padding: 10px;
}
.menu-header a,
#menu-body label {
cursor: pointer;
}
#menu-body:not(:target) {
display: none;
}
#menu-body:not(:target) ~ .menu-header > a:not(.close) {
display: inline-block;
}
#menu-body:target {
display: flex;
}
#menu-body:target ~ #menu-header > a {
display: none;
}
#menu-body:target ~ #menu-header > a.close {
display: inline-block;
}
#red:target ~ .box {
background-color: red;
}
#blue:target ~ .box {
background-color: blue;
}
#green:target ~ .box {
background-color: green;
}
.box {
background-color: black;
width: 75px; height : 75px;
}
<div class="menu">
<input id="red" type="radio" name="opcoes" checked/>
<input id="blue" type="radio" name="opcoes"/>
<input id="green" type="radio" name="opcoes"/>
<div id="menu-body">
Red
Blue
Green
</div>
<div class="box"></div>
<div id="menu-header">
≡ Open
≡ Close
</div>
</div>

Checkbox-Trick not working

I want to use the checkbox-trick to show my mobile navbar. Somehow the h1 isn't showin up even when the invisible checkbox is checked. What have I done wrong?
#label {
margin-left: auto;
margin-right: auto;
color: #000000;
font-size: 35px;
cursor: pointer;
width: 47px;
}
h1 {
display: none
}
#toggle {
display: none;
}
#toggle:checked + h1 {
display: block;
}
<div id="hamburgermenu">
<label id="label" for="toggle">☰</label>
<input id="toggle" type="checkbox">
</div>
<h1>DEMO ELEMENT</h1>
You're using "+" which is a sibling CSS selector, but <h1> isn't a sibling of your checkbox. It's a sibling of the checkbox's parent container. You can have 3 ways to go about it.
First way: Make it the sibling of the input by placing it inside
#label {
margin-left: auto;
margin-right: auto;
color: #000000;
font-size: 35px;
cursor: pointer;
width: 47px;
}
h1 {
display: none
}
#toggle {
display: none;
}
#toggle:checked+h1 {
display: block;
}
<div id="hamburgermenu">
<label id="label" for="toggle">☰</label>
<input id="toggle" type="checkbox">
<h1>DEMO ELEMENT</h1>
</div>
Second way: Make it the sibling of the input by taking the input out of the container
#label {
margin-left: auto;
margin-right: auto;
color: #000000;
font-size: 35px;
cursor: pointer;
width: 47px;
}
h1 {
display: none
}
#toggle {
display: none;
}
#toggle:checked + h1 {
display: block;
}
<div id="hamburgermenu">
<label id="label" for="toggle">☰</label>
</div>
<input id="toggle" type="checkbox">
<h1>DEMO ELEMENT</h1>
Third way: Make use of javascript.

Pure CSS change styling of div element with checkbox

I'm trying to toggle the CSS of a sibling by using the checked state of a sibling checkbox.
Is it possible to target elements anywhere on the page from the checked pseudo class from a checkbox?
I'm trying to avoid using any javascript.
https://codepen.io/dyk3r5/pen/WOmxpV?editors=1111
html,
body {
height: 100%;
}
.container {
height: 100%;
display: flex;
justify-content: center;
}
label {
color: #000;
font-weight: 600;
height: 25px;
padding: 5px 10px;
border-bottom: 2px solid lightgrey;
margin: 5px 1px;
}
input[type="radio"] {
display: none;
}
input[type="radio"]:checked + label {
border-bottom: 2px solid red;
}
input[type="radio"]:checked > div p {
display: none;
}
<div class="container">
<div id="new-account">
<input type="radio" id="opt1" name="radiolist" checked>
<label for='opt1'>New Account</label>
<div class="content">
<p>Lorem Ipsum</p>
</div>
</div>
<div id="existing-account">
<input type="radio" id="opt2" name="radiolist">
<label for='opt2'>Existing Account</label>
<div class="content">
<p>Lorem Ipsum 2</p>
</div>
</div>
</div>
Your mistake is in this line:
input[type="radio"]:checked > div p
your div element is not a "direct children" of input element. What you need here is "general sibling selector" to address any following div sibling.
So it should be:
input[type="radio"]:checked ~ div p
Use css like
input[type="radio"]:checked + label + .content p {
display: none;
}

Tab system with pure CSS, anchor avoids the propagation to label

I'm making a tab system only with CSS using :target and :checked pseudoclasses, but I have an anchor inside the label, and the label doesn't trigger the :checked.
If you click in the anchor, the :checked doesn't trigger because the click is in the <a> tag, but is inside a <label> that must trigger the radio button. If you click on the border of the tab, you'll see how it triggers the :checked, but not the anchor, so the :target can't be triggered.
Here you are my code, more understandable than the words:
a {
text-decoration: none;
}
.tabs {
position: relative;
}
input {
display: none;
}
.tabs .tab label {
text-decoration: none;
border: 1px solid black;
padding: 2px;
display: inline-block;
top: 2px;
position: relative;
cursor: pointer;
}
.tabs .tab input:checked + label {
background-color: white;
border-bottom: 0;
padding: 4px 2px;
top: 1px;
}
.contents {
border: 1px solid black;
background-color: white;
}
.contents .content {
display: none;
padding: 20px;
}
.contents .content:target {
display: block;
}
<div class="tabs">
<span class="tab">
<input type="radio" name="ch" id="check1">
<label for="check1">
Tab 1
</label>
</span>
<span class="tab">
<input type="radio" name="ch" id="check2">
<label for="check2">
Tab 2
</label>
</span>
<span class="tab">
<input type="radio" name="ch" id="check3">
<label for="check3">
Tab 3
</label>
</span>
</div>
<div class="contents">
<div class="content" id="tab1">Contenido 1</div>
<div class="content" id="tab2"><strong>Contenido 2</strong></div>
<div class="content" id="tab3"><em>Contenido 3</em></div>
</div>
Is there a way to combine :checked and :target pseudoclasses to achieve a complete tab system only with CSS?
Thank you.
EDIT
Here you are the snippet without anchor. Obviously the :target will not be triggered:
a {
text-decoration: none;
}
.tabs {
position: relative;
}
input {
display: none;
}
.tabs .tab label {
text-decoration: none;
border: 1px solid black;
padding: 2px;
display: inline-block;
top: 2px;
position: relative;
cursor: pointer;
}
.tabs .tab input:checked + label {
background-color: white;
border-bottom: 0;
padding: 4px 2px;
top: 1px;
}
.contents {
border: 1px solid black;
background-color: white;
}
.contents .content {
display: none;
padding: 20px;
}
.contents .content:target {
display: block;
}
<div class="tabs">
<span class="tab">
<input type="radio" name="ch" id="check1">
<label for="check1">
Tab 1
</label>
</span>
<span class="tab">
<input type="radio" name="ch" id="check2">
<label for="check2">
Tab 2
</label>
</span>
<span class="tab">
<input type="radio" name="ch" id="check3">
<label for="check3">
Tab 3
</label>
</span>
</div>
<div class="contents">
<div class="content" id="tab1">Contenido 1</div>
<div class="content" id="tab2"><strong>Contenido 2</strong></div>
<div class="content" id="tab3"><em>Contenido 3</em></div>
</div>
When you use input:checked, :target is not efficient cause this event is not triggered at all.
You need to put your input ahead in the flow so you can use the selector ~ to select any sibblings and their children following in the flow of the document:
example
a {
text-decoration: none;
}
.tabs {
position: relative;
}
input {
display: none;
}
.tabs .tab label {
text-decoration: none;
border: 1px solid black;
padding: 2px;
display: inline-block;
top: 2px;
position: relative;
cursor: pointer;
}
#check1:checked ~ .tabs label[for="check1"],
#check2:checked ~ .tabs label[for="check2"],
#check3:checked ~ .tabs label[for="check3"] {
background-color: white;
border-bottom: 0;
padding: 4px 2px;
top: 1px;
}
.contents {
border: 1px solid black;
background-color: white;
}
.contents .content {
display: none;
padding: 20px;
}
#check1:checked ~ .contents #tab1,
#check2:checked ~ .contents #tab2,
#check3:checked ~ .contents #tab3 {
display: block;
}
<!-- begin hidden inputs for CSS tabs purpose -->
<input type="radio" name="ch" id="check1">
<input type="radio" name="ch" id="check2">
<input type="radio" name="ch" id="check3">
<!-- End hidden inputs for CSS tabs purpose -->
<div class="tabs">
<span class="tab">
<label for="check1">
Tab 1
</label>
</span>
<span class="tab">
<label for="check2">
Tab 2
</label>
</span>
<span class="tab">
<label for="check3">
Tab 3
</label>
</span>
</div>
<div class="contents">
<div class="content" id="tab1">Contenido 1</div>
<div class="content" id="tab2"><strong>Contenido 2</strong>
</div>
<div class="content" id="tab3"><em>Contenido 3</em>
</div>
</div>
This behavior is specified in HTML5 (emphasis mine):
The activation behavior of a label element for events
targeted at interactive content descendants of a label
element, and any descendants of those interactive content
descendants, must be to do nothing.
Since the link is interactive content, clicking on it won't check the labeled radio input.