1

I am working on a page, where the user may click a button and print some important information on the page.

Basic page structure is like:

<body>

    <div id="printContent"></div>

    <button>Print</button>

</body>

And the desired behavior is: when the page is being printed, only the contents inside "printContent" should be printed.

Before I used js code to do it by temporarily replacing the body with whatever is inside printContent, but this seems to slow down the page a bit when user gets out of the printing options pop-up. (The temporary content will occupy the whole page for a few seconds or some of the buttons and links become non-responsive for a few seconds.) So after referring to the second answer here:How do I print part of a rendered HTML page in JavaScript?

I used something like this:

@media print {
  body * {
    display:none;
  }

  body #printContent {
    display:block;
  }
}

But when printing, the printContent part is still invisible. Did I do anything wrong here? Thanks.

EDIT: My bad, it is not the second answer from the link, the second "Highest upvoted answer", namely the one with 15 upvotes.

Community
  • 1
  • 1
Rui Chen
  • 41
  • 1
  • 10
  • Not sure that it matters here, but you don't need body in front of that id, as the id must be unique so this can only possibly everything down – Cody Braun Aug 13 '15 at 22:31
  • 1
    `display:none` makes an element and all its content disappear – you can not have descendants become visible again. You’d need to be more selective in what elements you are hiding. – CBroe Aug 13 '15 at 22:32
  • @CodyBraun Thanks, I have tried removing the "body" though, it did not make a difference. – Rui Chen Aug 13 '15 at 22:35
  • @CBroe that is what I suspected, but wouldn't later styles override the earlier ones in CSS? – Rui Chen Aug 13 '15 at 22:36
  • `display:none` makes an element behave as if it was actually removed from the DOM – and you can’t “override” that for children and descendant elements, whose common ancestor is not even “there” any more. – CBroe Aug 13 '15 at 23:09
  • Setting `display: block` on a descendant of a `display: none` element will not make the element visible. The ancestor is still hidden, so the children/descendants are too. – Kevin Boucher Aug 13 '15 at 23:13
  • @CBroe thank you! That sure explains a lot, so I assume in this case there is no way to print children components of the body using css only? – Rui Chen Aug 14 '15 at 16:16

1 Answers1

1

Okay, might be a lot of sub elements getting affected too. Try this:

@media print {
  body * {
    display:none;
  }

  body #printContent {
    display:block;
  }

  body #printContent * {
    display:initial;
  }
}

Technically, you are resetting the display for the inner contents too. Do you understand? When you give the global selector body *, it also hides the inner components. So just unhiding the parent #printContent will not be sufficient to unhide the children of it. To avoid all these hassles, you can do something like this if the #printContent is a direct descendant of body:

@media print {
  body > * {
    display:none;
  }

  body > #printContent {
    display:block;
  }
}
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
  • I understand the concept, but applying what you suggested did not work. Not sure why. I was wondering if whether the page is html/xhtml will matter? Because this page is currently in xhtml. – Rui Chen Aug 13 '15 at 23:00
  • @RuiChen No. I guess other CSS might affect it. I have been using Print CSS in Enterprise apps for about an year long. No issues from my side. Post the full code so we can have a look. What say? – Praveen Kumar Purushothaman Aug 13 '15 at 23:05
  • The actual page is several hundred lines long, putting it up here will make it hard to read. – Rui Chen Aug 14 '15 at 16:11
  • @RuiChen I agree, will see what we can do if you can host the one single page somewhere to be accessible. – Praveen Kumar Purushothaman Aug 14 '15 at 20:40