Toggle in pure CSS, with a child element - css

I am trying to do a toggle in pure CSS using :focus pseudo-selector.
My problem is I try to do the focus on parent element and change both child elements and adjacent selector.
<p class="collapser" tabindex="0">FILTERS
<span class="dblArrow right">
<i class="icon icon-double-chevron-right" tabindex="0">>></i>
<i class="icon icon-double-chevron-left" tabindex="0"><<</i>
</span>
</p>
<ul class="filters">.....
On the click on collapser (or the arrows in <i>), I want to display the <ul> or hide it, and changing the arrows.
You can view a demo of what I achieved until now : http://jsfiddle.net/TmzC7/9/
It has drawbacks : when you click anywhere outside the collapser the filters are hidden. To hide the filters, you have to click on the arrows.
If there is a solution so that either the arrows or the whole collapser (better) can handle the toggle and switch arrows, it would be great, but I reckon you have to use JavaScript for this...
I tried to do things like :
.collapser:focus .icon-double-chevron-right:focus + .icon-double-chevron-left {
opacity:1;
text-indent:0;
}
to detect click on the arrows, but it did not work. I assume focus does not bubble.
Is there a trick (like playing on tabindex or something) to achieve this without JavaScript?

using the examples here http://ghinda.net/css-toggle-switches/
i was able to do this http://jsfiddle.net/DbXQs/
it seems like the catch is to use the :checked selector.
hope it helps.

You could use the :target selector, like this :
.icon-double-chevron-right,
.icon-double-chevron-left,
.filters {
padding: 10px;
margin: 0;
list-style: none;
display:block;
border: 1px solid #000;
}
.filters,
.icon-double-chevron-left,
.icon-double-chevron-right:target {
display: none;
}
.icon-double-chevron-right:target + .icon-double-chevron-left,
.icon-double-chevron-right:target ~ .filters {
display:block;
}
a {
color: #333;
text-decoration: none;
}
<div>
>>
<<
<ul id="drop" class="filters">
<li>
FILTER 1
</li>
<li>
FILTER 2
</li>
</ul>
</div>
(see also this Fiddle)

Related

Trying to use CSS Multiple Checkbox Hack on Same Page

I'm trying to utilize the CSS checkbox hack to toggle Display:None and Display:Block for multiple sections of one page. I have image gallery sets split by year and starting hidden, and would like to be able to click the year to toggle that specific gallery's display. The point I'm stuck at is whenever I click one of the labels, everything below it toggles, not just the section contained within the tag I'm trying to specifically toggle.
Here is what I have so far.
CSS Code
.hide {
display:none;
}
input[type=checkbox] {
position: absolute;
top: -9999px;
left: -9999px;
}
input[type=checkbox]:checked ~ .hide {
display:block;
}
label {
display: block;
background: white;
padding: 5px;
border: 0px solid rgba(0,0,0,.1);
border-radius: 2px;
color: black;
font-weight: bold;
}
And the HTML
<input type="checkbox" id="toggle_2012">
<label for="toggle_2012">2012</label><br>
<div class="hide">
<a class="fancybox" rel="2012" href="imgs/fb/3_b.jpg"><img src="imgs/fb/3_s.jpg" alt="Image 3"/></a>
<a class="fancybox" rel="2012" href="imgs/fb/4_b.jpg"><img src="imgs/fb/4_s.jpg" alt="Image 4"/></a>
</div>
<input type="checkbox" id="toggle_2013">
<label for="toggle_2013">2013</label><br>
<div class="hide">
<a class="fancybox" rel="2013" href="imgs/fb/1_b.jpg"><img src="imgs/fb/1_s.jpg" alt="Image 1"/></a>
<a class="fancybox" rel="2013" href="imgs/fb/2_b.jpg"><img src="imgs/fb/2_s.jpg" alt="Image 2"/></a>
</div>
(Jquery/Fancybox is being used to display the images, which is why they are classed for Fancybox)
Any help would be greatly appreciated. This is my first time working with the checkbox hack, but to my understanding having unique ID's for the input/label should work. Not sure what I'm missing here.
Thanks in advance.
Your css selector ~ affects every following element with that class. try:
input[type=checkbox]:checked + label + .hide
you may have to remove the <br> for this to work.
This is a few months on, and possibly you found your solution by now, but for the benefit of anyone finding this thread, here's my solution. Firstly, You were correct in giving the checkbox an ID (CLASS would also work in some situations), however you must actually reference that ID in your CSS.
Instead of:
input[type=checkbox]:checked ~ .hide {
display:block;
}
Try this:
#toggle_2013:checked ~ .hide {
display:block;
}
Without specifically identifying the checkbox in your CSS aswell as in the HTML, the first suitable checkbox in the DOM will be activated rather than the one you want.
Hope this helps.

CSS onhover Popup

I have created CSS onHover popup as given here. but problem is, User should be able to click the Register link in the example. here, Popup disappears as I move the mouse aware form the link.
Can anyone tell how it could be achieved ?
HTML:
<div class="how f-left">
<h7>How does this work?</h7>
<div class="how-works bubble-outer">
<div class="navigation-up-arrow"></div>
<div class="body">
<h4>How It Works</h4>
<ol class="bubble-inner">
<li>Tell Us What's Wrong </li>
<li class=""> Register to Get Quotes from Local Shopshere </li>
<li class=" bold-txt ">Call Shop / Get Vehicle Serviced </li>
<li>Get Cash Back </li>
</ol>
</div>
</div>
</div>
Below CSS is used for onHover PopUp:
.how h7:hover + .how-works {
display: block;
}
You can make it display on hovering the parent (.how), not just its preceding sibling. Hovering the parent happens when you are hovering any of its descendants (the link, .how-works, any of the children of .how-works).
To do this, change:
.how h7:hover + .how-works {
display: block;
}
to:
.how:hover .how-works {
display: block;
}
DEMO
Also, if you want to make it work for touchscreens (no hover there), you could adjust a bit your HTML. Change
<h7>How does this work?</h7>
to
<a class="how-it-works" href="#" tabindex="1"><h7>How does this work?</h7></a>
and add this to the CSS as well:
.how-it-works:focus + .how-works {
display: block;
}
DEMO
Add this to your CSS:
.how-works:hover {
display: block;
}
Modified version of your demo: little link.
Here is a working example link.
Put
.how:hover .how-works {
display: block;
}
instead of
.how h7:hover + .how-works {
display: block;
}
and add position: relative; top: 0px; css properties to .how .how-works.bubble-outer{ ... }

Is there a CSS selector to locate the 2nd/3rd child or descendant (of a given class/id) under an element (with a given class/id)?

I have something along the lines of this
<div class="menu" style="background-color: transparent;">
<div class="button">
<div class="divider" style="background-color: transparent;"></div>
<a id="apple" class="unselect select" href="/apple">
<span class="apple1">Apple</span>
</a>
</div>
<div class="button">
<div class="divider"></div>
<a id="orange" class="unselect" href="/orange">
<span class="orange1">Orange</span>
</a>
</div>
....
this gives me the first divider
css=div.menu div.button div.divider
I am trying to access the 2nd divider. I have the need to access the buttons as well. I tried reading through the the nth child stuff and noticed that it is not compatible with IE.
Is there a CSS selector to locate the 2nd/3rd child or descendant (of a given class/id) under an element (with a given class/id)?
I am using xPaths now
//div[#class='menu']/descendant::div[contains(#class,'divider')][2]
it works but I want to migrate this to CSS.
The adjacent sibling selector + is able to do that and is compatible with IE7+
Fiddle demonstrating its use with 4 buttons: http://jsfiddle.net/AgNwu/
(no need for "div" if you rely already on id/class everywhere. If you call something "button", expect it to be a link, an input[type="submit|image|button|reset"] or button element ;) )
CSS
.menu > .button {
border: 1px solid darkblue;
padding: 10px;
margin: 5px 0;
}
.menu > .button + .button .divider {
background: Tan;
}
.menu > .button + .button .divider:after{
content: " (2nd or more)";
}
.menu > .button + .button + .button .divider {
background: yellow;
}
.menu > .button + .button + .button .divider:after{
content: " (3rd or more)";
}
edit: adjacent sibling, I thought this was sibling vs. general sibling
You can replace + by ~ (general sibling) if you have other type of nodes in-between your .button nodes/elements. This'd be the equivalent of :nth-of-type that would still work in IE7+
You can write like this:
div.menu div.button + div.button div.divider{
color:red;
}

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.

CSS - why doesn't :hover parent hide child elements

I have a navigation bar with images, like so:
<ul>
<li class="me">
<span class="cont"><img src="dummy.png" /></span>
</li>
<li class="me">
<span class="cont"><img src="dummy.png" /></span>
</li>
</ul>
On hovering over a list item I want to change the background color to cover the span and image like so:
.me {background-color: none;}
.me:hover {background-color: rgba(150,150,150,0.5);}
Problem is, the image does not get covered... Is this because the background is in fact... a "background" on which child elements are sitting? If so, how could I achieve this effect with plain CSS?
EDIT - solution
this worked with my original HTML structure:
<ul>
<li>
<a href="" class="ui-btn">
<span class="ui-btn-inner"> /* CONTAINS IMAGE AS BACKGROUND */
<span class="ui-btn-text">text</span> /* GETS BACKGROUND */
<span class="ui-icon"></span>
</span>
</a>
</li>
</ul>
"Negative logic": If I assign the background to list item, it sits behind all child elements, so I figured I needed to assign the background to an element that is a child of the element containing the img to have it appear above all items. span ui-btn-inner contains the image, so setting the :hover background on span ui-btn-text makes it appear above the image... weird, but works.
Yes, the background is just a background, and is placed behind any child elements.
To achieve what you're looking for, try using the css :after pseudo element to mask the image on hover:
.me {
position: relative;
}
.me:hover:after {
content: "";
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(150,150,150,0.5);
}
It's shiny, you get to use the image as a semantic image, and requires no extra HTML markup.
Yes, it's because the background is in fact a background. The best method to achieve this in raw css would be to continue using the background:
.me
{
background-color: none;
background-image: url(dummy.png);
background-repeat: no-repeat;
}
.me:hover
{
background-color: rgba(150,150,150,0.5);
background-image: ;
}
You could also achieve this effect with a bit of javascript as well.
<ul>
<li class="me">
<span class="cont"><img="dummy.png" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";'></span>
</li>
<li class="me">
<span class="cont"><img="dummy.png"" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";></span>
</li>
</ul>
Code not tested. It might require tweaking to get it just right.
Edit: Layering concept
None of this pseudo-code is test, but I've done it before so it may just take a bit of tweaking. I don't have a copy of the original I did on hand so I'll have to wing it. The first step is to create a relative container and 2 sub containers.
.meContainer
{
position: relative;
width: 100px;
height: 30px; /* I usually specify height/width for these things */
}
.meContainerLink
{
position: absolute;
top: 0;
left: 0; /* You need to use position to get them to overlap */
z-index: 1; /* Provide a layer */
}
.meContainerAlpha
{
position: absolute;
top: -30px; /* Move it UP 30px */
left: 0px;
z-index: 2; /* Place it on top of the other layer */
display: none; /* Hide it */
background-color: rgba(150,150,150,0.5);
}
.meContainerAlpha:hover
{
display: inline; /* Show it */
}
Then you'd need to place these in divs inside your <li>.
<ul>
<li class="me">
<div class="meContainer">
<div class="meContainerLink">
<img="dummy.png">
</div>
<div class="meContainerAlpha">
</div>
</div>
</li>
<li class="me">
<div class="meContainer">
<div class="meContainerLink">
<img="dummy.png">
</div>
<div class="meContainerAlpha">
</div>
</div>
</li>
</ul>
I don't recall ever trying this method inside embedded <li> tags, so it may behave oddly at first. You may have to abandon <li> and switch to a different <div> structure entirely.
another potential option that should be more cross browser than :after could be:
.me:hover span { display: hidden; }

Resources