4

In my React Application (using semanticUI), I have several components rendered in a view, but when users want to print the page (e.g. by pressing Ctrl+P on the browser) I want only one part to be printable

for instance, if this is a screenshot of what user sees, the green area should be shown on print overview when the browser print is triggered.

So far I have in the SCSS file

@media print{    
  .no-print, .no-print *{ display: none !important; }
}

which adding to unwanted components makes them disappear but yet got blank space in print area and the green part is not filling the page, also if this green part is scrollable and should fit into several pages I just see one page (one A4 paper containing what I see on screen)

having

@media print {
  .print-content {
    display: block;
    width: 100%;
    height: 100%;
    page-break-after: always;
    overflow: visible;
  }
}

did not work yet get the same printable view

enter image description here this is the code for this screenshot

import React from 'react'
import { Grid, Image } from 'semantic-ui-react'

const GridExampleCelled = () => (
  <Grid celled>
    {/*another Grid.Row*/}

    <Grid.Row>
      <Grid.Column width={3}>
        <Image src='/images/wireframe/image.png' />
      </Grid.Column>
      <Grid.Column width={10}> /* This should be the component to print */
        <p> EveryThing Wrapped in this Grid should be printed </p>
      </Grid.Column>
      <Grid.Column width={3}> 
        <Image src='/images/wireframe/image.png' />
      </Grid.Column>
    </Grid.Row>
  </Grid>
)

export default GridExampleCelled
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Amir-Mousavi
  • 4,273
  • 12
  • 70
  • 123
  • check [this](https://stackoverflow.com/questions/3463796/how-to-only-show-certain-parts-with-css-for-print) – Vencovsky Jan 30 '19 at 16:47
  • I think one of two approaches: 1. In the `print` case stretch the div you want printed to 100% vw/vh, with position fixed, white background etc. 2. Open a new page in a popup that you create just for printing (useful if print/display pages are diverging from one another). – Tommos Feb 05 '19 at 16:44
  • Did you use the class-names `.no-print` or `.print-content` anywhere? Your custom styling (inside `@media print { ... }`) only affects elements with those class-names. – ArneHugo Feb 05 '19 at 21:47
  • Are you looking for a css solution only? Cause you could also utilise the "onbeforeprint" and "onafterprint" events to manipulate the visibility of your components via JS. Also it is important how the outer styles of your app are defined. Is your body or html tag using "overflow: hidden"? – larrydahooster Feb 08 '19 at 09:51
  • @larrydahooster Good point yes catching the print command with JS is also a good option (I think is better than only CSS) but reading the docs in MDN did not really get how to use it – Amir-Mousavi Feb 08 '19 at 09:53
  • @Amir-Mousavi I edited my answer and added a question regarding the outer layout styles. Is it a Single Page application with scrollable body? I think all these styles need to be reverted then as well. – larrydahooster Feb 08 '19 at 09:58
  • @larrydahooster Actually I do not see any answer !? and yes the app is React and SPA there is not much CSS as UI library is used. as it was not basically my project and recently started working on it, I just realized inside there and `ìFrame` is used :( which I think will change the whole approach – Amir-Mousavi Feb 08 '19 at 11:00
  • @Amir-Mousavi Sorry, I meant comment instead of answer. Without the knowledge about the whole page setup I'm afraid I can't give an answer. But try to reset all "overflow: hidden" and fixed heights of outer containers. Iframe shouldn't be a problem. This can also set to a auto height to fully wrap it's content – larrydahooster Feb 08 '19 at 11:10

1 Answers1

8

Don't take this as the ultimate solution that covers all your use cases. But you can try this snippet idea to see if it solves your problem enough. I had a similar task in my recent project and this approach worked as needed.

@media print {
  @page {
    size: landscape;
  }
  body * {
    visibility: hidden;
  }
  .section-to-print, .section-to-print * {
    visibility: visible;
  }
  .section-to-print {
    position: absolute;
    left: 0;
    top: 0;
  }
}

It will hide all the content on the page. Then add .section-to-print class to the area you want to print. Unless you have some overwriting css on it, it should work the way you want it to.

Important point to mention, if you have this CSS in global scope, it will hide all the content which doesn't have the .section-to-print and the print page will be blank. So, it might be wise to inject it into the stylesheet only when needed.

Let me know if this helps.

Sam Uherek
  • 293
  • 1
  • 5
  • Just as note the reason this works over the OP's code is the positioning that gets applied for printing. you might want to note that while this is a very good answer in terms of code and explanation it does not directly answer the OPs question of why his method does not work – Barkermn01 Feb 10 '19 at 15:20