Jedda
Jedda

Reputation: 1017

How can I toggle a div to reveal content with CSS

So I've got a div that should expand to reveal a list when toggled. The before and after states can be seen here http://reversl.net/box/ but what do I need to add to my styling to make this happen? I'd like to use css transitions for added effect. I'm not worried about browser compatibility because it's just for learning purposes. Any tips?

<div class="box"><img src="http://www.placehold.it/250x300" alt="" />
        <div class="section progress">
            <h4>
                <a href="#">Div Before</a>
            </h4>
            <div class="metrics">
                <div class="meter">
                    <span style="width: 75%"></span>
                </div><!--.meter-->
            </div><!--.metrics-->
        </div><!--.section-progress-->
</div><!--.box-->

<div class="box"><img src="http://www.placehold.it/250x300" alt="" />
        <div class="section progress">
            <h4>
                <a href="#">Div After</a>
            </h4>
            <div class="metrics">
                <div class="meter">
                    <span style="width: 75%"></span>
                </div><!--.meter-->
            </div><!--.metrics-->
        </div><!--.section-progress-->
        <div class="sub_section">
            <ul class="list">
                <li>Item 1</li>
                <li class="last">Item 2</li>
            </ul>
        </div><!--.sub_section-->
</div><!--.box-->

.boxes {
width: 100%;
padding: 1%;
}

.box {
width: 20%;
padding: 1%;
background: #fff;
-moz-box-shadow: 2px 3px 4px 0px #e9e9e9;
-webkit-box-shadow: 2px 3px 4px 0px #e9e9e9;
box-shadow: 2px 3px 3px 0px #e9e9e9;
display: inline-block;
margin-top: 1em;
}

.box img {
margin-bottom: 1%;
}

.progress a {
margin: 0;
padding: 0;
color: #999;
text-decoration: none;
}

.metrics {
margin: -1em 0 0 0;
padding: 0;
background: #c0c0c0;

}
.accordion .progress .meter {
background: #555;
width: 100%;
position: relative;
}

.meter > span {
height: 10px;
display: block;
background-color: #777;
position: relative;
overflow: hidden;
}

.sub_section {
margin-top: 1em;
border-bottom: none;
}

.list {
padding: 0;
margin: 0;
}

.list li {
background: #dcdcdc url('http://placehold.it/40x40') no-repeat;
font-size: 11px;
color: #999;
list-style: none;
padding: 1.3em 1em 1.3em 4.5em;
margin-bottom: 5px;
}

.list .last {
border-bottom: none;
}

Upvotes: 3

Views: 27575

Answers (5)

David Thomas
David Thomas

Reputation: 253318

I'm afraid I couldn't work out, in your sample code and image, what you wanted to click on and what you wanted to show. However, the following works with an onclick-like event with pure CSS:

<div id="wrapper">
    <ul id="top">
        <li><a href="#one">One</a></li>
        <li><a href="#two">Two</a></li>
    </ul>
    <div class="box" id="one">
        <p>One</p>
        <span><a href="#top">Close</a></span>
    </div>
    <div class="box" id="two">
        <p>Two</p>
        <span><a href="#top">Close</a></span>
    </div>
</div>

CSS:

.box {
    position: absolute;
    top: 20%;
    left: 50%;
    width: 50%;
    margin-left: -25%;
    border: 4px solid #000;
    background-color: #f90;
    /* the CSS, above, is all for aesthetic purposes, what matters is the following */
    opacity: 0;
    -webkit-transition: all 1s linear;
    -ms-transition: all 1s linear;
    -moz-transition: all 1s linear;
    -0-transition: all 1s linear;
    transition: all 1s linear;
}

.box:target {
    opacity: 1;
    -webkit-transition: all 1s linear;
    -ms-transition: all 1s linear;
    -moz-transition: all 1s linear;
    -0-transition: all 1s linear;
    transition: all 1s linear;
}

JS Fiddle demo.

Unfortunately it seems (in Chromium 17/Ubuntu 11.04) impossible to animate from display: none; to display: block; Similarly a transition from height: 0 to height: auto also fails (trying either results in a sudden appearance rather than a transition. So the content in the demo is always 'there,' but simply hidden (with opacity) and then shown once the relevant link is clicked.

However for a slide-toggle like effect:

.box {
    /* aesthetic stuff excised for brevity */
    opacity: 0;
    height: 0;
    overflow: hidden;
    -webkit-transition: all 1s linear;
    -ms-transition: all 1s linear;
    -moz-transition: all 1s linear;
    -0-transition: all 1s linear;
    transition: all 1s linear;
}

.box:target {
    opacity: 1;
    height: 3em;
    -webkit-transition: all 1s linear;
    -ms-transition: all 1s linear;
    -moz-transition: all 1s linear;
    -0-transition: all 1s linear;
    transition: all 1s linear;
}

JS Fiddle demo.

Upvotes: 5

Alex Morales
Alex Morales

Reputation: 1191

You're gonna need to use javascript to listen for the event that fires the transition, unless you want it to apply on hover. so, you can start with something like this:

$('.box').click(function(){
    $(this).toggleClass('show');
});

Then in the css, you need to have the class with the new size and the transition applied:

.show
{
height: 300px;
-webkit-transition: height .25s ease-in-out;
transition: height .25s linear;
}

If you want a purely CSS solution, then you'll have to handle this using the ':hover' pseudo-class like redlena said. The only difference I would make is that you don't need an additional div (.trans) and you don't need to specify the child selector in your CSS either (.box > .trans).

Upvotes: 1

HMartch
HMartch

Reputation: 728

Making these modifications of your code will give you a CSS transition.

Inside your <div class="box">, add a container <div class="trans"> around the contents, like so:

<div class="box">
  <div class="trans">
    <img src="http://www.placehold.it/250x300" alt="" />
        <div class="section progress">
            <h4>
                <a href="#">Div After</a>
            </h4>
            <div class="metrics">
                <div class="meter">
                    <span style="width: 75%"></span>
                </div><!--.meter-->
            </div><!--.metrics-->
        </div><!--.section-progress-->
        <div class="sub_section">
            <ul class="list">
                <li>Item 1</li>
                <li class="last">Item 2</li>
            </ul>
        </div><!--.sub_section-->
    </div><!--.trans-->
</div><!--.box-->

Then, in your css, add:

.box > .trans {
    height:365px;
    overflow:hidden;
    }

.box > .trans:hover{
    height: 500px;
    -webkit-transition: height .25s linear;
    transition: height .25s linear;
    }

This will give you a mouseenter/mouseleave type effect. I don't think you'd be able to do an "onclick" type effect that would hold it open with just CSS.

Upvotes: 2

jacktheripper
jacktheripper

Reputation: 14219

This cannot be achieved with pure CSS, trying using JavaScript or jQuery

This example gets you close, but it does not stay active once clicked.

Upvotes: -1

kingjeffrey
kingjeffrey

Reputation: 15270

You can use the "Checkbox Hack": http://css-tricks.com/the-checkbox-hack/

Upvotes: 3

Related Questions