show no-parent div on click on another div, pure css possible? - html

I want to split my site in two vertical sections. If you click on a left button (width:50%), the content for this button should appear below with width:100% and if you click on the right button the same but of course with content 2.
Is it even possible with pure css? Because I don't know java :/ and I think it's a quite simple problem, isn't it?
#content_button_left,
content_button_right {
display: none
}
#button_left:active~#content_button_left {
display: inherit
}
#button_right:active~#content_button_right {
display: inherit
}
<div>
<div style="display:flex">
<div id="button_left" style="flex:1">Menu left</div>
<div id="button_right" style="flex:1">Menu right</div>
</div>
<div id="content_button_left" style="width:100%">
blabla 1
</div>
<div id="content_button_right" style="width:100%">
blabla 2
</div>
</div>

You can use :target CSS selector to fake the click event but for that you have to convert your div to anchor tag, below is CSS
#content_button_left, #content_button_right{
display:none
}
#content_button_left:target {
display:block;
}
#content_button_right:target{
display:block;
}
Updated HTML
<div style="display:flex">
<a id="button_left" href="#content_button_left" style="flex:1">Menu left</a>
<a id="button_right" href="#content_button_right" style="flex:1">Menu right</a>
</div>
<div id="content_button_left" style="width:100%">
blabla 1
</div>
<div id="content_button_right" style="width:100%">
blabla 2
</div>

I would use radio buttons next to the content and labels for your button targeting the radios. This way you can use the adjacent sibling selector to only show the content next to a checked radio:
/* hide radio and content */
.radio,
.content {
display: none;
}
/* show content if it directly follows a checked radio */
.radio:checked + .content {
display: block;
}
<div>
<div style="display:flex">
<label id="button_left" style="flex:1" for="left-input">Menu left</label>
<label id="button_right" style="flex:1" for="right-input">Menu right</label>
</div>
<input type="radio" name="show-content-radio" id="left-input" class="radio">
<div id="content_button_left" style="width:100%" class="content">
blabla 1
</div>
<input type="radio" name="show-content-radio" id="right-input" class="radio">
<div id="content_button_right" style="width:100%" class="content">
blabla 2
</div>
</div>

Related

Can I make this checkbox hide/show an element in the same section but under a different class?

complete coding newbie with no formal HTML/CSS education here. I am experimenting with a project and wanted to try and make a list of paragraph elements hidden and expandable.
It is important to note that my ways of modifying the site in question are rather limited. I can only directly modify the CSS of the page and the HTML -in- the <h2 class="label"> (not the class itself).
I have included the pieces of HTML and CSS below. The first toggle correctly hides the "Control me"-text. I was wondering if I could do the same for the div class "value" or the paragraph elements under it. The second piece of CSS is, evidently, not working. I assume this has to do with the placement/relationship of the elements. So, my question is: is this, at all, possible? If so, how?
I am aware that this "checkbox hack" is not recommended. With the limitiations I described above, I at least want to try it. Consequently, I would appreciate all help on this topic, if only for the sake of experimentation/knowledge.
My apologies if this is a silly question. Thanks in advance!
#toggle:checked ~ .control-me{
display: none; /*this works*/
}
#toggle:checked ~ .value{
display: none; /*this does not work*/
}
<section class="item references">
<h2 class="label">
<label for="toggle">References</label>
<input type="checkbox" id="toggle" class="visually-hidden">
<div class="control-me">Control me</div>
</h2>
<div class="value">
<p>Originally lots of different paragraph elements here</p>
</div>
</section>
#toggle:checked ~ .control-me{
display: none; /*this works*/
}
#toggle:checked ~ .value{
display: none; /*this does not work*/
}
<section class="item references">
<label for="toggle">References</label>
<input type="checkbox" id="toggle" class="visually-hidden">
<div class="control-me">Control me</div>
<div class="value">
<p>Originally lots of different paragraph elements here</p>
</div>
The '~' selector requires that both elements have the same parent and element 1 comes before element 2.
In your first example #toggle:checked comes before .control-me and the elements are both children of the same parent.
Where as in your second example: #toggle:check does come before .value but they are not from the same parent
https://www.w3schools.com/cssref/sel_gen_sibling.asp
EDIT: I have added a snippet with the h2 tag removed, to show that if they shared a parent, the desired effect would be achieved.
The main problem is that you have wrapped the control-me class inside a <h2> tag. Where as the .value class is outside the h2 tag so it changes only elements inside <label>.
Solution No 1:
Put the outside h2 tag.It works
<section class="item references">
<h2>
<label for="toggle">References</label>
</h2>
<input type="checkbox" id="toggle" class="visually-hidden" />
<div class="control-me">Control me</div>
<div class="value">
<p>Originally lots of different paragraph elements here</p>
</div>
</section>
Solution No 2:
Wrap the things you want to hide inside h2 tag
<section class="item references">
<h2>
<label for="toggle">References</label>
<input type="checkbox" id="toggle" class="visually-hidden" />
<div class="control-me">Control me</div>
<div class="value">
<p>Originally lots of different paragraph elements here</p>
</div>
</h2>
</section>
Here is a JavaScript answer (because you mentioned in a comment that you can use JS)-
Add a class d-none in CSS and toggle the class via JavaScript on each click.
Here is a working example-
document.getElementById("toggle").addEventListener("click", function(){
document.getElementsByClassName("value")[0].classList.toggle("d-none");
});
#toggle:checked ~ .control-me{
display: none; /*this works*/
}
.d-none{
display: none;
}
<section class="item references">
<h2 class="label">
<label for="toggle">References</label>
<input type="checkbox" id="toggle" class="visually-hidden">
<div class="control-me">Control me</div>
</h2>
<div class="value">
<p>Originally lots of different paragraph elements here</p>
</div>
</section>
Edit : Here is the snippet with script tag in the case there is some problem with inserting scripts externally.
#toggle:checked ~ .control-me{
display: none; /*this works*/
}
.d-none{
display: none;
}
<section class="item references">
<h2 class="label">
<label for="toggle">References</label>
<input type="checkbox" id="toggle" class="visually-hidden" onclick="hide()"/>
<div class="control-me">Control me</div>
</h2>
<div class="value">
<p>Originally lots of different paragraph elements here</p>
</div>
</section>
<script>
function hide(){
document.getElementsByClassName("value")[0].classList.toggle("d-none");
}
</script>

How to hide all elements except a grandchild with a specific class with CSS? [duplicate]

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 5 years ago.
I'm not sure if this can be done entirely with CSS (imperative), but it's halfway working at the moment. I have this current HTML setup:
<div class="content">
<div>
<div class="image"></div>
</div>
<div class="text"></div>
<div class="text"></div>
<div>
<div class="button"></div>
</div>
<div>
<div class="image"></div>
</div>
</div>
My current CSS hides all of the child elements of ".content" that don't have a class.
.content > *:not([class]):first-child {
display:block;
}
Of the remaining 3 visible class child elements of ".content", I need to hide them all except the first child element that has the grandchild element with the ".image" class. This is the CSS I have, but it's not working:
.content > *:not([class]):not(.image):first-child {
display:block;
}
It's imposible on CSS. You tryed not show parent element by attribute of child. CSS so does not work. But you can small js for this:
document.querySelector(".image").parentNode.style.display = "block";
.content>div {
display: none;
}
<div class="content">
<div>
<div class="image">1</div>
</div>
<div class="text">2</div>
<div class="text">3</div>
<div>
<div class="button">4</div>
</div>
<div>
<div class="image">5</div>
</div>
</div>
Andrey’s answer is good, however if you don’t want to use JS I think you will need to have a class on the intermediary children as well since the entire tree to the element you want must be visible. That is, if any parent of the element you want to show is hidden then the children will be too. Something like this might do:
<div class="content">
<div>
<div class="image"></div>
</div>
<div class="text"></div>
<div class="text"></div>
<div>
<div class="button"></div>
</div>
<div class="visible">
<div class="image"></div>
</div>
</div>
.content > * {
display: none;
}
.content > .visible {
display: block;
}

Pure css toggle with no sibling

Using a checkbox for a css toggle, this code works... The div disappears when you click the checkbox...
input:checked ~ #test{display:none}
<div id="main">
<input type="checkbox">Click Me
<div id="test">This is a test</div>
</div>
But here, it doesn't work, because the TEST div is not a sibling, right? It's outside of the main div...
input:checked ~ #test{display:none}
<div id="main">
<input type="checkbox">Click Me
</div>
<div id="test">This is a test</div>
Is there a way to make this work with just css? I thought if I remove the ~ then any div with an ID = TEST would disappear no matter where it is, but that's not the case.
well this kind of works
the trigger is inside your main but the actual checkbox must be on the same level as "test"
#main {white-space:nowrap;}
#check {
display:none;
}
p {display:inline-block;}
.fake{
display:inline-block;
width: 10px;
height: 10px;
background:lightgray;
}
#check[type=checkbox]:checked + #main + #test {
display:none;
}
#check[type=checkbox]:checked + #main > label {
background: gray;
}
<input id="check" type="checkbox">
<div id="main">
<label class="fake" for="check"></label>
<p>Click Me</p>
</div>
<div id="test">This is a test</div>

Effect on div sibling

I have two siblings div where there are more divs contained inside, like this:
<div class="btn_lists">
<div class="btn green_btn">
<img src="<?= asset_url() ?>images/escolar_07__1.png" />
</div>
</div>
<div class="btn-desc-container">
<div class="btn-desc_1">
<p>Description</p>
</div>
</div>
By default I have btn-desc_1 with display: none;
I want that hovering green_btn applies display: inline-block; on btn-desc_1
How could I do this efficiently?
There is no way to achieve this via CSS. Use jquery piece of code:
$('.green_btn').hover(function(){
$('.btn-desc_1').toggleClass('display-inline');
})
like the demo: http://jsfiddle.net/nidzix/sWQr9/3/
Horroristic almost-answer. Probably very unreliable. It is only for demonstration, don't use it. Instead of hovering it works with clicking on the images:
:checked is supported only with IE9+: https://developer.mozilla.org/en-US/docs/Web/CSS/:checked
Live example, click the kittens: http://jsfiddle.net/bzH7S/2/
<body>
<input type="radio" name="btn" value="1" id="radio1">
<input type="radio" name="btn" value="2" id="radio2">
<div id="wrap">
<div class="btn_lists">
<label for="radio1" class="btn btn1"><img src="1"></label>
<label for="radio2" class="btn btn2"><img src="2"></label>
</div>
<div class="btn-desc-container">
<div class="btn-desc_1"><p>Kitten One</p></div>
<div class="btn-desc_2"><p>Kitten Second</p></div>
</div>
</div>
</body>
CSS:
body > input {
display: none;
}
.btn-desc-container > div {
display: none;
}
#radio1:checked ~ #wrap .btn-desc_1,
#radio2:checked ~ #wrap .btn-desc_2 {
display: block;
}
There's no way to do this unless btn_desc1 is a child of green_btn, in which this would work:
.green_btn:hover > .btn-desc_1
{
display:inline-block;
}
with this HTML:
<div class="btn_lists">
<div class="btn green_btn">
<img width='400px' heigh='400px' src="http://www.pieisgood.org/images/slice.jpg" />
<div class="btn-desc_1">
<p>Description</p>
</div>
</div>
in your CSS. However, you could use JQuery for this to reach your goal, like nidzik says:
$('.green_btn').hover(function(){
$('.btn-desc_1').toggleClass('display-inline');
})
Here's the demo

Align instructions div tag under textbox

All,
I have the following code:
http://jsfiddle.net/k2AMG/7/
I am trying to avoid fixed widths in the CSS and align the divs in this fashion, but am not able to do so:
Your name Textbox
Please check the name
Work email Textbox
Email should have a valid format
Job title Textbox
Job title should have only alphabets
Any help is appreciated. Thanks
Try it like this:
http://jsfiddle.net/andresilich/k2AMG/11/
::Edit:: fixed demo
::Edit 2:: added CSS and HTML to post for future reference
CSS
.data_item{
margin-bottom: 20px;
display: block;
}
label
{
width: 100px;
display:inline-block;
}
.left {
display:inline-block;
margin-right:5px;
}
.right {
display:inline-block;
vertical-align:top;
}
.right span span {
display:list-item;
list-style-type:none;
}
Clarification: created two classes to separate the two sides, .left and .right, and added a style to the span of the .instructions div to display as a list-item (so they can displace like a regular html list would, why? Because it is a clean, responsive drop that displaces naturally without the need to add margin or padding that might displace with any other element around and thus less maintenance.).
HTML
<div class="data_item">
<div class="left">
<label> Your name </label>
</div>
<div class="right">
<span>
<input type="text" />
<span class="instructions">Please check the name</span>
</span>
</div>
</div>
<div class="data_item">
<div class="left">
<label> Work email </label>
</div>
<div class="right">
<span class="item">
<input type="text" />
<span class="instructions">Email should have a valid format</span>
</span>
</div>
</div>
<div class="data_item">
<div class="left">
<label> Job title </label>
</div>
<div class="right">
<span class="item">
<input type="text" />
<span class="instructions">Job title should have only alphabets</span>
</span>
</div>
</div>
Try this: http://jsfiddle.net/k2AMG/9/