Futurebox, lightbox without the javascript and target pseudo-class

So I recently released a revised version of Futurebox which added a lot of functionality. But one thing was nagging me, the fact that it utilised the target pseudo-class to hijack in page anchors which has a few side effects that can create some major drawbacks to the technique. One being that if you click multiple futurebox links and then click the browser back button it will go through all the previous overlays that were activated due to the natural behaviour of in page anchors. The other drawback, clicking an in page anchor can cause the page to abruptly jump as it tries to bring the anchor location to the top of the page.

But you’re thinking I’m mad, there can’t possibly be any other way to trigger a pure CSS overlay.

Radio buttons?!

Yep this technique uses radio inputs along with the checked CSS3 pseudo-class, which I described in my custom checkbox/radio inputs article, to show/hide the futurebox modals.

<ul>
    <li>
        <label for="futurebox01">
            <img src="image.gif" width="100" height="102" alt="The CSS Ninja" />
        </label>
        <input type="radio" id="futurebox01" name="gallery" />
        <div class="overlay">
            <label for="close" title="Close futurebox">
                <img src="image.png" alt="The Css Ninja" width="469" height="500" />
            </label>
        </div>
    </li>
</ul>

The mark-up differs from the original futurebox. The overlay now needs to appear directly below the image, the images are wrapped in a label as well as the overlay, we set the “for” attribute on the label so we can check the radio without having to actually click the radio. We also use that to our advantage so we can actually close the modal once it’s been opened by having the large image wrapped in a label with a “for” attribute to a hidden radio button.

Having the same name value on all the inputs makes sure only one of the radio buttons can be checked at any one time.

ul li input { display: none; }
ul li input:checked + .overlay { display: table; }

Since we don’t actually want or need to see the radio button we hide it. As mentioned before the “for” attribute controls the checking and unchecking of the input.

Unfortunately due to a bug in IE (you’ll need to login to view it, or just change your UA string to googlebot ;)) only labels with text trigger the input. Since IE9 is the first IE to support the checked pseudo-class if this bug is fixed this technique will work, until then it won’t. Let’s hope a fix makes it into IE9 final release.

The second line uses the checked pseudo-class to apply display: table to the inputs direct sibling with a class of overlay.

.overlay
{
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    display: none;
    z-index: 999;
    background: rgb(0,0,0);
    background: rgba(0,0,0,0.7);
}
    .overlay label
    {
        display: table-cell;
        vertical-align: middle;
        text-align: center;
    }

The overlay styles don’t differ at all to the original demo, except that instead of an anchor tag wrapping the image it’s now a label. When the input is checked the overlay sibling of that input becomes visible, by setting it to display: table, as shown in the previous CSS block. The label has display: table-cell applied to it so it’ll act like a table cell and naturally fill all height and width available to it. Applying vertical-align: middle will make the image vertically center and to horizontally center the image we take advantage of the fact that images are inline elements and just set the label to have text-align: center.

Not just for images

Since futurebox was only ever originally meant for loading images I thought I would extend this new version to also load static and dynamic content (iframes). In the demo the second listing shows 2 examples of static content and 2 examples of loading an iframe.

Static content

In order to show static content within a futurebox overlay the mark-up differs slightly.

<ul>
    <li>
        <label for="futurebox01">
            <img src="image.gif" width="100" height="102" alt="The CSS Ninja" />
        </label>
        <input type="radio" id="futurebox01" name="gallery" />
        <div class="overlay">
            <label for="close" title="Close futurebox">
                <span class="content01">
                    <span class="inner_content">
                        // content goes here
                    </span>
                </span>
            </label>
        </div>
    </li>
</ul>

Rather than have the image we have 2 spans, although 1 is fine I used 2 to make the scrolling look nicer.

.content01
{
        display: block;
        width: 460px;
        padding: 20px;
        background: #fff;
        color: #000;
        margin: 0 auto;
        text-align: left;
        cursor: auto;
        -webkit-border-radius: 10px;
        -moz-border-radius: 10px;
        border-radius: 10px;
}
    .content01 .inner_content
    {
        display: block;
        height: 500px;
        overflow-y: auto;
    }

The content span I apply a base width and some padding along with applying some CSS3 to give the modal some nice rounded corners.

The inner content span I set a fixed height and apply overflow-y to auto so any content that extends further will show a vertical scrollbar otherwise if the content fits it will hide the scrollbar.

The reason I use spans and not divs is because a label is a inline element and putting divs inside it is not only invalid but will also cause render issues in some browsers. So using a span and setting it to display: block handles that dilemma.

Change the height of individual modals

Since the base height of the static content container is quite high putting in a small amount of content will create alot of empty white space. You can get around it by targeting specific futurebox modals and set the height to something else.

#futurebox07 + .overlay .inner_content { height: 265px; }

Each input has their own id so the “for” attribute will work on the labels, we can then use that id to target specific modals and change their height.

It’s an iframe

Loading static content has a lot of great uses but sometimes only an iframe can handle some situations such as submitting a form within a modal or loading an external resource.

The first iframe example loads up my contact page, feel free contact me, so you can submit a form without affecting the modal or causing a post back on the parent page.

The second iframe loads a Google search for futurebox.

Since iframes are naturally inline placing it inside a label isn’t invalid and won’t cause any browser issues.

.overlay iframe
{
    background: #ffffff;
    border: none;
    padding: 10px;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
}

To give the iframe the same padding and rounded corners as the images and static content modals, we add a few styles to reset the iframes border, add some padding, set the background and apply some border-radius values to give it rounded corners.

Close buttons

I’ve also added close buttons on the static and iframe modals, these are purely for show and don’t technically close the modal since clicking anywhere on the overlay will close the modal. It’s purely there to give the user the feeling they are actually closing something by clicking a button, rather than the background.

<label for="close" title="Close futurebox">
    <span class="content01 content02">
        <strong class="closebutton" title="Close futurebox">X</strong>
        // content
    </span>
</label>

To add the close button I’ve added a strong tag within the content container. I’ve just added an X inside to represent the close action and added a title attribute so it makes sense.

.closebutton
{
    background: #606061;
    color: #FFFFFF;
    cursor: pointer;
    height: 24px;
    line-height: 24px;
    overflow: hidden;
    position: absolute;
    right: -12px;
    text-align: center;
    top: -12px;
    width: 24px;
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
    -moz-box-shadow: 1px 1px 3px #000;
    -webkit-box-shadow: 1px 1px 3px #000;
    box-shadow: 1px 1px 3px #000;
}

Since we have fixed width content it makes it possible to position it correctly while still keeping the futurebox horizontally centred, that’s the reason there is no close on the image based modals as the width can vary from image to image. To sit the button to the right of the futurebox I absolutely position it and set top and right to -12px so it will sit slightly offset from the container.

To create the circle effect I set the width and height to 24px and apply a border-radius of 12px for either side which will create our circle.

.closebutton:hover
{
        background: #318DF2;
        text-shadow: 1px 1px 1px #ccc;
}

When the user hovers over the close button I change the background-color and give the X a light drop shadow.

Mix it up

We can mix up the styles of the futurebox by adding a class to the parent ul, in the last list example I’ve added a class to do just that.

.theme01 .overlay
{
    background: none;
}
    .theme01 .overlay label > img,
    .theme01 .overlay iframe,
    theme01 .content01
    {
        border: 1px solid #ccc;
        -moz-box-shadow: 5px 5px 10px #000, -5px -5px 10px #000;
        -webkit-box-shadow: 5px 5px 10px #000, -5px -5px 10px #000;
        box-shadow: 5px 5px 10px #000, -5px -5px 10px #000;
    }

Instead of a semi transparent rgba background, I’ve reset the background to none and applied a dual box shadow to the overlay items.

Love it, hate it?

Think it’s awesome, think it’s an abomination? Let me know what you think or if you have any suggestions on how you think it could work better make sure to leave a comment.

Short URL: http://cssn.in/ja/025

 

Post filed under: css.

Skip to comment form.

  1. Rob says:

    @Ryan, thanks for your quick response.

    I was adding that to my choice, but it wasn’t working. Then I discovered that simply refreshing the page won’t bring it up. I had to close the page and re-open it, which is basically what I want any way.

    Thanks again. This is a great feature.

  2. Rob says:

    @Ryan, thanks for helping us out. It’s incredibly generous of you.

    So…yes, I thought that was what was needed, but it wasn’t working for me. Then I discovered that a simple refresh was the problem. I had to close the page and re-open it to get it to work.

    Again, this all-CSS option is just awesome. Thanks for your efforts.

  3. BigBonsai says:

    Nice!!!
    Am wondering whether there is a way to make the box fade in and out?

  4. Ryan Seddon says:

    @BigBonsai – You might wanna checkout this project I did. http://labs.thecssninja.com/bootleg/

  5. Rodney says:

    Hello,
    I have the futurebox working really well to submit a form. It works everywhere, submits the form well, closes etc. Except on an ipad. It is not possible to close the iframe regardless where you click on the page. It does work on an iphone. Any ideas how I can fix this?
    Thanks

  6. Ryan Seddon says:

    @Rodney – Can you put together a test case to show what’s happening?

  7. Rodney says:

    Thanks for your reply.
    The easiest way to demonstrate is on the webpage itself. If you are able to visit the page on an ipad and click on the request an appointment button. The futurebox will open but it then doesn’t close. On a desktop it works without a hitch.

  8. Ryan Seddon says:

    @Rodney – How are you closing the form though do you add some JavaScript to close the modal once the form has submitted?

  9. Rodney says:

    Problem solved. I added an onclick function to the overlay div () and the following script:

    $(document).ready(function(){
      $('#overlay').bind('click', function(event){
        if (event.target == $('#overlay').get(0))
          overlay(); 
      });
    });
    

    Now the window closes on ipads as well. Great CSS script though. Thanks for your help.

  10. Charles says:

    I love the example. However I have tried to implement this to one of my own designs and I cannot get the modal to close. It displays fine on click, but know matter what I do I cannot get this to go back to display:none. I am not using lists though, and trying this with divs. Anyway I can email you the code and have you glance at it? My markup is as follows:

    Awesome DIV Layer Technique

    Content Goes Here
    Content Goes Here
    Content Goes Here
    Content Goes Here
    Content Goes Here
    Content Goes Here
    Content Goes Here
    Content Goes Here
    Content Goes Here

    I can send you my modifications in my css file if you want. Let me know. Thanks.

  11. Charles says:

    Well the markup didn’t show. But I am willing to email it to you.

  12. Charles says:

    Nevermind. Figured it out. My two incidents of the input tag (display and close) did not have the same ‘name’ field. Something so simple had me wasting hours of time trying to figure this out. Works great now. Implemented great into my project. I have to say this works way better than the :target attribute because using a #close id doesn’t work in IE. See this example in IE10: http://www.htmlstack.com/lighterbox/#close. I tried this first and if you use IE10 and click the links multiple times, it will eventually get hung up on the grey overlay without any content centered in the middle and no way to ‘close’ it. Once I realized that the :target selector wasn’t going to work in IE I had to find another alternative. Thank you much for this!

  13. José Luis says:

    Hello! Thank you for this work.

    I have a problem. I’m using your futurebox with iframes and the problem is that when I click on the iframe the modal window closes or desappears.

    Could you help me?

  14. Mat says:

    How do you get the background of the Web page to shade out when you click on the box to open and when you click the button to close, the shade of the Web page will be removed?

  15. Mat says:

    Also, how do you get it to refresh the Iframe Web page?

Leave a comment