Collapse without javascript - css

I know how to collapse (display / hide) a div:
$('#nav').click(function() { $('#hello').toggleClass('hidden'); });
.hidden { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nav">NAV</div>
<div id="hello" class="hidden">Hello</div>
Is it possible to do this without Javascript / jQuery?
I've tried the main answer from this question, but it is not working, as detailed here.

Nobody has mentioned the 'details' element, which seems perfect for this job.
<details>
<summary>Click to toggle</summary>
<span>Oh, hello</span>
</details>

You may use :checked selector.
#hidden {
display: none;
height: 100px;
background: red;
}
:checked + #hidden {
display: block;
}
<input type="checkbox" id="my_checkbox" style="display:none;">
<div id="hidden"></div>
<label for="my_checkbox">Show/hide</label>
Example fiddle

Well yes, it is, but it's not neat. It involves the :target selector, where you can apply styles to active elements / id's. If we wrap your nav content in a link, we can apply a hashtag which invokes the active rule in our CSS.
Downside, this jumps the page to the location unless prevented by... JavaScript.
a {
color: #000;
text-decoration: none;
}
#hidden {
display: none;
}
#hidden:target {
display: block;
}
<div id="nav">NAV</div>
<div id="hidden">Hello</div>

Related

is it possible to activate a div when clicked without javascript?

Just wondering if a div can be called without using javascript.
such as
my_div:hover{ add new layout}
is there a version for click eg
my_div:click{add new layout}
Thanks
Yes, if you add tabindex="0" to your div, you make it clickable and can then use the :focus pseudo-class to apply styles.
<div class="clickable" tabindex="0"></div>
.clickable {
height: 100px;
background: blue;
}
.clickable:focus {
background: red;
}
Codepen example. Clicking the div should give it focus and apply the :focus CSS to it. Clicking away from it will unfocus (blur) it and reset the default styles.
Not directly, but you can fake it using checkboxes:
input[type=checkbox] {
display: none;
}
.content {
display: none;
padding: 20px;
background-color: #dadada;
}
input[type=checkbox]:checked+label+.content {
display: block;
}
<input type="checkbox" id="check">
<label for="check">Click me</label>
<div class="content">
<h3>Content</h3>
<p>lorem20</p>
</div>

How to change CSS class to ascendent

I can't figure out how to do this, and don't know if it's even possible:
<div class="container">
<div class="text"></div>
View more
<div>
How can I add a class to the div .text if I click on the link .view with only CSS?
I can't use javascript as I'm building a page with its css for AMP
If you can give a fragment to the anchor instead of 'javascript:;' then you can utilize the :target state of anchor.
#view-more {
display: none;
}
#view-more:target {
display: block;
}
<div class="container">
View more
<div class="text" id="view-more">text</div>
<div>
https://jsfiddle.net/karthick6891/g89fdagu/
But the best alternative is to use checkbox so you will have the :checked attribute, which is more robust
The only thing close to it I could think of would be to use the sibling styling
https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors
.text + a {
border: 2px solid #fc0;
}
So it is the next sibling item that is style and if you could order your structure as follows:
<div class="container">
View more
<div class="text">
</div>
Then maybe you could have
.text {
display: none;
}
a:active + text {
display: block;
}
You could then maybe use table row styling like the following to reorder them
setting the "a" as:
display: table-footer-group
setting the "text" as:
display: table-header-group
All without Javascript, but obviously the minute you haven't got the link active the text box disappears :-D
Soooooooooo you could have a checkbox instead..? when it is active the Adjacent sibling can be styled:
https://css-tricks.com/almanac/selectors/c/checked/
input[type=checkbox] + .text {
display: none;
}
input[type=checkbox]:checked + .text {
display: block;
}
Another possible solution
HTML
<div class="container">
<label for="textView">Button Style Me</label>
<input type="checkbox" name="textView" class="view">
<div class="text">Some Text</div>
</div>
STYLING
input[type=checkbox] + .text {
display: none;
}
input[type=checkbox]:checked + .text {
display: block;
}
CSS cannot do that, CSS is only styling. You can however do it with javascript.
<div class="container">
<div class="text"></div>
View more
<div>
<script>
function myFunction() {
var elements = document.getElementsByClassName("text");
for(var index = 0; index < elements.length; index++) {
var element = elements[index];
element.className += "otherclass";
}
}
</script>

Pinterest image button getting in the way of my :hover css

I have some pseudo code like this:
<div class="container">
<div class="hiddenatfirst">
<img>
<img>
<img>
</div>
</div>
and css like so:
.hiddenatfirst{
display:none;
}
.container:hover .hiddenatfirst{
display:block;
}
.hiddenatfirst:hover{
display:block;
}
The problem is - I have a design website and a lot of visitors have the pinterst extension installed. When someone hovers over the pin-it button that gets added to the images inside the .hiddenatfirst div the div gets hidden again.
I don't want to remove the pin-it buttons from the images but I don't want them to get in the way of the :hover events.
Any ideas?
Apologies for the pseudo-code, the real code is pretty messy and in staging! Hopefully this explains what I need.
Thanks
PS - if you look at the .third-level-menu in the navigation here you'll see it in action (note you'll need the pinterest chrome extension installed)
http://smith-hoyt.myshopify.com/?preview_theme_id=12397927
PPS - this is a crappy GIF but I think shows what's happening too:
http://recordit.co/anNtu8W1Vo
PPPS - you can see the pin-it button that pinterest adds to each image in this image: https://twitter.com/tomcritchlow/status/573920066124836864/photo/1
Most probably the problem is that 'Pin it' button is absolutely positioned on top of the image, but it's not the container's child, so hover on it hides the image like on the following sample:
.container {
display: block;
width: 500px;
height: 315px;
background-color: gray;
}
.hiddenatfirst {
display: none;
}
#pinit {
position: absolute;
top: 32px;
left: 32px;
}
.container:hover .hiddenatfirst {
display: block;
}
.hiddenatfirst:hover {
display: block;
}
<div class="container">
<div class="hiddenatfirst">
<img src='https://dq1eylutsoz4u.cloudfront.net/2014/10/sf-cat.jpg' />
</div>
</div>
<img id='pinit' src='http://www.brandaiddesignco.com/insights/PinIt.png' />
What you can do is using JavaScript or jQuery find all the 'Pin it' buttons and move them to the appropriate containers with the positions recalculation, so the result HTML will be like the following:
.container {
display: block;
width: 500px;
height: 315px;
background-color: gray;
}
.hiddenatfirst {
display: none;
}
#pinit {
position: absolute;
top: 32px;
left: 32px;
}
.container:hover .hiddenatfirst {
display: block;
}
.hiddenatfirst:hover {
display: block;
}
<div class="container">
<div class="hiddenatfirst">
<img src='https://dq1eylutsoz4u.cloudfront.net/2014/10/sf-cat.jpg' />
<img id='pinit' src='http://www.brandaiddesignco.com/insights/PinIt.png' />
</div>
</div>
Rather than use the javascript solution above, since these images are small and in the navigation I found a way to remove the pin-it button, simply add to each image:
nopin="nopin"
As per the documentation here:
https://developers.pinterest.com/on_hover_pin_it_buttons/

whats the CSS selector for a label that does not have a sibling input type=checkbox||radio?

I need to set it with CSS, not jquery.
The selector is for
all labels which do not have a sibling that is a checkbox or radio component.
a sample is:
<span>
<input id="item" type="checkbox">
<label for="item">Data</label>
</span>
This is because i have CSS which sets label to 12px, BUT it affects asp:checkboxes and asp:radio..., but i do not want them to be affected.
There isn't a CSS selector for an element that doesn't have a sibling of a certain kind.
But if you can guarantee that your structure is always an input followed by a label, then you could use the next-sibling combinator with :not() like so to match the label:
input:not([type="checkbox"]):not([type="radio"]) + label
Otherwise you're going to have to add classes to those labels, or use jQuery.
Try adjacent sibling selector:
input[type='text'] + label ​{ // your styles }​​
You need to apply it to all predecessors you need namely. But there are not many possibilities to use label for besides checkbox and radios you don't want ;)
DEMO
You can select elements based on what kinds of siblings they have, IF the siblings precede your target elements. You can do however much type/selector checking you want on preceding siblings of your target.
You can kind of go backwards using nth-last-of-type and nth-last-child, but you can't do any selector checking on elements which follow your target, and the only kind of type checking you can do on following elements is counting how many there are of the same type.
So in your case you could use:
label {
/* your styling here */
}
input[type="checkbox"] + label, input[type="radio"] + label {
/* remove the styling for labels preceded by a checkbox or radio button */
}
Use ~ instead of + if you expect other elements between your inputs and labels.
Depending on what other elements might be inside the spans that you're working with, any of the 'nth' pseudoclasses may be useful to you.
This would also work for your example, if all you care about is that the labels don't have a preceding sibling:
label:first-child {
/* awesome styles */
}
I submitted an answer to a question that I feel is extremely valuable and along the lines to what you're asking for in this question. Here is the permalink to that question/answer.
https://stackoverflow.com/a/43132408/6167697
The key thing that is missing that may not work for your case is I propose keeping the inputs a child only to what they need to be so that other content can be selector'd using generic sibling selectors. Hypothetically you could still keep them in the span, and then use the labels in various elements inside the span, and that would still allow you treat those labels separate from any others I would think. I'll copy in a code snippet for a working example that demonstrates label elements that are not siblings to their inputs that can still be styled.
* {
padding: 0;
margin: 0;
background-color: #262626;
color: white;
}
.radio-button {
display: none;
}
#filter {
padding: 5% 0;
display: flex;
justify-content: center;
}
.filter-label {
display: inline-block;
border: 4px solid green;
padding: 10px 20px;
font-size: 1.4em;
text-align: center;
cursor: pointer;
}
main {
clear: left;
}
.content {
padding: 3% 10%;
display: none;
}
h1 {
font-size: 2em;
}
.date {
padding: 5px 30px;
font-style: italic;
}
.filter-label:hover {
background-color: #505050;
}
#featured-radio:checked~#filter .featured,
#personal-radio:checked~#filter .personal,
#tech-radio:checked~#filter .tech {
background-color: green;
}
#featured-radio:checked~main .featured {
display: block;
}
#personal-radio:checked~main .personal {
display: block;
}
#tech-radio:checked~main .tech {
display: block;
}
<input type="radio" id="featured-radio" class="radio-button" name="content-filter" checked="checked">
<input type="radio" id="personal-radio" class="radio-button" name="content-filter" value="Personal">
<input type="radio" id="tech-radio" class="radio-button" name="content-filter" value="Tech">
<header id="filter">
<label for="featured-radio" class="filter-label featured" id="feature-label">Featured</label>
<label for="personal-radio" class="filter-label personal" id="personal-label">Personal</label>
<label for="tech-radio" class="filter-label tech" id="tech-label">Tech</label>
</header>
<main>
<article class="content featured tech">
<header>
<h1>Cool Stuff</h1>
<h3 class="date">Today</h3>
</header>
<p>
I'm showing cool stuff in this article!
</p>
</article>
<article class="content personal">
<header>
<h1>Not As Cool</h1>
<h3 class="date">Tuesday</h3>
</header>
<p>
This stuff isn't nearly as cool for some reason :(;
</p>
</article>
<article class="content tech">
<header>
<h1>Cool Tech Article</h1>
<h3 class="date">Last Monday</h3>
</header>
<p>
This article has awesome stuff all over it!
</p>
</article>
<article class="content featured personal">
<header>
<h1>Cool Personal Article</h1>
<h3 class="date">Two Fridays Ago</h3>
</header>
<p>
This article talks about how I got a job at a cool startup because I rock!
</p>
</article>
</main>
That has the added benefit of being pure CSS too! And as per the other post, here's the JSFIDDLE so you can play around with it yourselves.

How to keep :active css style after clicking an element

I use anchor as my site navigation.
<div id='nav'>
<a href='#abouts'>
<div class='navitem about'>
about
</div>
</a>
<a href='#workss'>
<div class='navitem works'>
works
</div>
</a>
</div>
The CSS
#nav {
margin-left: 50px;
margin-top: 50px;
text-transform: uppercase;
}
.navitem {
background: #333;
color: white;
width: 230px;
height: 50px;
font-size: 25px;
line-height: 50px;
padding-left: 20px;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
margin-top: 10px;
}
.about:hover {
background: #cc00ff;
}
.about:active {
background: #ff00ff;
color: #000;
width: 250px;
}
.works:hover {
background: #0066FF;
}
.works:active {
background: #0099cc;
color: #000;
width: 250px;
}
I'm wondering how to keep the div element style keep in the :active state once after the click until I hit another nav bar item, so how to do it?
Combine JS & CSS :
button{
/* 1st state */
}
button:hover{
/* hover state */
}
button:active{
/* click state */
}
button.active{
/* after click state */
}
jQuery('button').click(function(){
jQuery(this).toggleClass('active');
});
The :target-pseudo selector is made for these type of situations: http://reference.sitepoint.com/css/pseudoclass-target
It is supported by all modern browsers. To get some IE versions to understand it you can use something like Selectivizr
Here is a tab example with :target-pseudo selector.
I FIGURED IT OUT. SIMPLE, EFFECTIVE NO jQUERY
We're going to to be using a hidden checkbox.
This example includes one "on click - off click 'hover / active' state"
--
To make content itself clickable:
#activate-div{display:none}
.my-div{background-color:#FFF}
#activate-div:checked ~ label
.my-div{background-color:#000}
<input type="checkbox" id="activate-div">
<label for="activate-div">
<div class="my-div">
//MY DIV CONTENT
</div>
</label>
To make button change content:
#activate-div{display:none}
.my-div{background-color:#FFF}
#activate-div:checked +
.my-div{background-color:#000}
<input type="checkbox" id="activate-div">
<div class="my-div">
//MY DIV CONTENT
</div>
<label for="activate-div">
//MY BUTTON STUFF
</label>
Hope it helps!!
You can use a little bit of Javascript to add and remove CSS classes of your navitems. For starters, create a CSS class that you're going to apply to the active element, name it ie: ".activeItem". Then, put a javascript function to each of your navigation buttons' onclick event which is going to add "activeItem" class to the one activated, and remove from the others...
It should look something like this: (untested!)
/*In your stylesheet*/
.activeItem{
background-color:#999; /*make some difference for the active item here */
}
/*In your javascript*/
var prevItem = null;
function activateItem(t){
if(prevItem != null){
prevItem.className = prevItem.className.replace(/{\b}?activeItem/, "");
}
t.className += " activeItem";
prevItem = t;
}
<!-- And then your markup -->
<div id='nav'>
<a href='#abouts' onClick="activateItem(this)">
<div class='navitem about'>
about
</div>
</a>
<a href='#workss' onClick="activateItem(this)">
<div class='navitem works'>
works
</div>
</a>
</div>
If you want to keep your links to look like they are :active class, you should define :visited class same as :active so if you have a links in .example then you do something like this:
a.example:active, a.example:visited {
/* Put your active state style code here */ }
The Link visited Pseudo Class is used to select visited links as says the name.

Resources