12

Suppose my web page has a struture like this:

<body>
    <div id="fee">
        <div id="fi">

            <div id="actual_content">

                <p>Content</p>
                <div id="some_important_stuff">Blah</div>
                <p>More content</p>
                <span class="and_another_thing">Meh</span>

                ...
            </div>

            <div id="fo>
                ...
            </div>

            ...
        </div>

        <div id="fum">
            ...
        </div>

        ...
    </div>

    <div id="fazz">
        ...
    </div>

    ...
</body>

I want to create a print CSS style that hides everything except for the contents of actual_content.

My first attempt was like this:

body * {
    display: none; /* Hide everything first */
}

/* Show content div and all of its ancestors */

body > #fee {
    display: block;
}

body > #fee > #fi {
    display: block;
}

body > #fee > #fi > #actual_content {
    display: block;
}

/* Unhide contents of #actual_content */

#actual_content * {
    display: block; /* Not ideal */
}

However, since there's no "display: auto" or "display: default", I mess up the styles of actual_content's items when I try to unhide them. I also don't like hard coding the path to actual_content since it might change.

MacDonald
  • 133
  • 1
  • 1
  • 6
  • How do you "mess up the styles of actual_content's items when I try to unhide them". Div is by default a block level element and when you set it back to display: block; it should not have any problems. (position: absolute; visibility: hidden; has the same effect as display:none;) – Jawad Sep 13 '11 at 19:38
  • What do you mean when you say you'd rather not hard code the #actual_content? You could select the first child of the last parent div if the ID is likely to change, for example: div#fi + div would select the first div immediately after #fi. – lowe_22 Sep 13 '11 at 21:12
  • @Jawad - I have more than just divs inside the content div. Objects that display as inlines by default like spans and ems are getting set to display as blocks as well. – MacDonald Sep 14 '11 at 12:01
  • @lowe_22 - When I said hard-coding, I meant the path to **actual_content** (_body > #fee > #fi > #actual_content_). I was hoping that if I removed the **fi** div and put **actual_content** under the **fee** div in the future, the CSS could still handle it. – MacDonald Sep 14 '11 at 12:25
  • 1
    How about you do something like this. "" - And in the "print.css", you can have - body * {position: absolute; visibility: hidden; } - div#actual_content * {position: static; visibility: visible;} – Jawad Sep 16 '11 at 15:54
  • http://www.alistapart.com/articles/goingtoprint/ – Jawad Sep 16 '11 at 15:57

4 Answers4

4

on the top level div set visibility:hidden, then on the div you want set visibility:visible

xlecoustillier
  • 16,183
  • 14
  • 60
  • 85
Robert Wagstaff
  • 2,664
  • 1
  • 27
  • 40
4

You probably want to use the visibility property. W3Schools describes the difference between the display and visibility properties: the visibility property affects the visibility of an element without affecting its structure, i.e. the space it would normally occupy on the page.

Anson
  • 2,654
  • 21
  • 18
2

You'll need to go in and target everything that you don't want to show up individually by setting display:none. If you can change class names, etc, you should un-nest the actual_content <div>, then add classes like hide_div to the other <div>s so they're easy to turn off.

Nightfirecat
  • 11,432
  • 6
  • 35
  • 51
Fred
  • 222
  • 1
  • 6
  • 11
1

I know your tags show you want a CSS solution, but the PrintArea jQuery plugin is perfect for your needs:

PrintArea sends a specified dom element to the printer, maintaining the original css styles applied to the element being printed.

http://plugins.jquery.com/project/PrintArea

Jason Gennaro
  • 34,535
  • 8
  • 65
  • 86