Margin and padding issue when doing window.print - javascript

I am trying with Javascript window.print to print a content inside the div container. The div container is managed by angular js.
CSS file
#media print
{
body, html, #wrapper {
width: 100%;
margin:0px;
padding:0px;
border: 1px solid red;
}
.no-print, .no-print * {
display: none !important;
}
.col-sm-12 {
width: 100%;
}
}
HTML containing the DIV
<div ng-show="views.invoice">
<div class="row col-sm-12" style="margin:0px; padding:0px; width:100%">
test
</div>
<div class="row no-print">
<div class="col-12">
<button class="btn btn-success btn-default" onclick="window.print();"><i class="fa fa-print"></i> {{phrase.Print}}</button>
</div>
</div>
</div>
This is how it is shown in the browser
When I do the print it is printing to PDF as below
I see a big margin around the text 'test'. How can I print without any margin or padding?

The Problem
It's most likely because you've set the visibility your drawer and your navbar (the left-side navigation and the top-side navigation) to hidden. When something's visibility is set to hidden, it is still in the layout and preserves its height, width, margin, and padding. This is why you're seeing the space of your drawer and navbar, respectively causing the space on the left side and the top side.
You can run and try printing the below screen. You'll see the problem I mentioned (the space caused by the preserved sizes [height, width, padding, margin]).
#media print {
body,
html,
#wrapper {
width: 100%;
margin: 0px;
padding: 0px;
border: 1px solid red;
}
#drawer {
visibility: hidden;
}
#navbar {
visibility: hidden;
}
.no-print {
display: none;
}
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
position: relative;
width: 100%;
height: 100%;
}
#wrapper {
display: flex;
flex-direction: row;
height: 100%;
width: 100%;
}
#navbar {
width: 100%;
background: blue;
color: white;
padding: 20px;
}
#section--right {
flex-grow: 1;
}
#drawer {
height: 100%;
width: 100px;
background: red;
color: white;
padding: 20px;
}
#navbar .text {
display: inline-block;
height: 50px;
background: #121212;
}
<div id="wrapper">
<div id="drawer">Some drawer</div>
<div id="section--right">
<div id="navbar"><span class="text">Some navbar</span></div>
<div id="print__section">
test
</div>
<button id="print__button" class="no-print" onclick="window.print()">Print now</button>
</div>
</div>
Solution
My suggestion is to set a special id or class to the printable region. Then, set all the other elements' visibility inside body that have no such special id or class to hidden. Furthermore, because setting visibility to hidden still allows the elements to preserve their dimensions, set their sizes (height, width, margin, and padding) to 0 too. Note that you can't use display: none because your printable region will also not be displayed.
Here's a working example that will solve your problem.
#media print {
body,
html,
#wrapper {
width: 100%;
margin: 0px;
padding: 0px;
border: 1px solid red;
}
/* Makes all divs that are not inside the print region invisible */
/* Then, set the size to 0 by setting everything (height, width, margin, and padding) to 0 */
body *:not(#print__section) {
visibility: hidden;
height: 0;
width: 0;
margin: 0;
padding: 0;
}
/* Parents' visibility cascade to children's visibility */
/* Make the print region visible again to override parent's visibility */
#print__section {
visibility: visible;
}
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
position: relative;
width: 100%;
height: 100%;
}
#wrapper {
display: flex;
flex-direction: row;
height: 100%;
width: 100%;
}
#navbar {
width: 100%;
background: blue;
color: white;
padding: 20px;
}
#section--right {
flex-grow: 1;
}
#drawer {
height: 100%;
width: 100px;
background: red;
color: white;
padding: 20px;
}
#navbar .text {
display: inline-block;
height: 50px;
background: #121212;
}
<div id="wrapper">
<div id="drawer">Some drawer</div>
<div id="section--right">
<div id="navbar"><span class="text">Some navbar</span></div>
<div id="print__section">
test
</div>
<button id="print__button" class="no-print" onclick="window.print()">Print now</button>
</div>
</div>

Related

Modal height resizes to content, but at max-height of modal content becomes scrollable

I have a modal that contains tabs that potentially will have long content.
What I'm trying to do is get the modal to resize on content height but when the content exceeds the modals max-height of 80% the content section should become scrollable.
currently, it works that content scrolls when it gets too large. but the problem is now the modal__content container stays 100% height regardless of the content. if I remove the height from modal__content then the content scroll no longer works.
Hope this makes sense
<div class="modal">
<div class="modal__container">
<div class="modal__content">
<div class="modal__left"></div>
<div class="modal__right>lorem 200 </div>
</div>
</div>
<div>
<div class="modal-overlay"></div>
CSS
html, body {
height: 100%;
}
*, ::after, ::before {
box-sizing: border-box;
}
.modal {
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
position: fixed;
left: 0;
top: 0;
}
.modal__container {
width: 1076px;
display: flex;
align-items: center;
height: calc(100% - 3.5rem);
margin:1.75rem auto;
}
.modal__content {
background: white;
display: flex;
height: 100%;
}
.modal__left {
width: 400px;
background: #f6f6f6;
}
.modal__right {
flex: 1;
display: flex;
align-items: center;
}
.modal__inner {
padding: 2.5rem;
}
.modal__body {
padding: 0 2.5rem;
height: calc(100% - 5rem);
overflow-y: scroll;
}
Try adding
overflow-y: scroll;
to .modal__content
You could also try switching the heights from
height: calc(100% - 3.5rem);
to
height: 100vh;

ScrollIntoView breaks the overflow scroll

I have a nested child container and when I'm trying to scrollIntoView it breaks the parent container. I'm not able to understand why it's acting like this. Please help me out in this.
Please have a look at the code below or on jsfiddle
function moveToTop() {
console.log('MOVE TO TOP::');
const child = document.getElementById('child');
child.scrollIntoView({
behavior: "smooth"
});
}
#parent {
background-color: blue;
padding: 10px;
height: 500px;
overflow: hidden;
display: flex;
flex-direction: column;
}
#scroller {
overflow: auto;
padding: 10px;
background-color: red;
flex-grow: 1;
}
#child {
height: 10000px;
background-color: green;
}
body {
overflow: hidden;
color: #fff;
font-weight: bold;
}
button {
position: fixed;
bottom: 20px;
width: 140px;
left: 20%;
right: 0;
}
<div id="parent">
PARENT
<div id="something">Something</div>
<div id="scroller">
CHILD
<div id="child">
GRAND CHILD
<button onclick="moveToTop()">Top</button>
</div>
</div>
</div>
The whole problem is that scrollIntoView() is moving the window. But since the #parent overflow is hidden, when the window is moved, this element itself breaks. I could suggest setting a position: fixed for the #parent, which will solve your problem, but it can harm the layout in general.
Use the scroll() method. The scrolling mechanism itself is:
scroller.scroll(0, child.offsetTop - 55);
child.offsetTop - top element;
55 - distance from the top of the #parent to the top #scroller.
The transition animation must be set to css, in selector #scroller. Like that:
#scroller {
...
scroll-behavior: smooth;
}
function moveToTop() {
console.log('MOVE TO TOP::');
const child = document.getElementById('child');
const scroller = document.getElementById('scroller');
scroller.scroll(0, child.offsetTop - 55);
}
#parent {
background-color: blue;
padding: 10px;
height: 500px;
overflow: hidden;
display: flex;
flex-direction: column;
}
#scroller {
overflow: auto;
padding: 10px;
background-color: red;
flex-grow: 1;
scroll-behavior: smooth;
}
#child {
height: 10000px;
background-color: green;
}
body {
overflow: hidden;
color: #fff;
font-weight: bold;
}
button {
position: fixed;
bottom: 20px;
width: 140px;
left: 20%;
right: 0;
}
<div id="parent">
PARENT
<div id="something">Something</div>
<div id="scroller">
CHILD
<div id="child">
GRAND CHILD
<button onclick="moveToTop()">Top</button>
</div>
</div>
</div>

Set height of div to 100% of remaining space under header

I have 2 divs:
A header div at the top of the page with a set height of 150px.
A container div sitting under the header div.
What I would like is for the container div to be dynamic and resize to 100% of the remaining space underneath the header div.
I have tried putting in height: 100% but this makes the page need to scroll. I presume it is making the div 100% of the browser height rather than 100% of the remaining body's height.
How can I make it so that the container div simply resizes its height to the remaining body space?
Please find the relevant code below:
body,
html {
margin: 0;
height: 100%;
}
#header {
width: 100%;
height: 150px;
background-color: #999999;
}
#container {
width: 760px;
height: 100%;
background-color: #CCCCCC;
margin: 0 auto;
}
<div id="header"></div>
<div id="container"></div>
You can simply do that by using some math with the calc() CSS function. Subtract 150px (the header size) from 100%. This is dynamically calculated.
body,
html {
margin: 0;
height: 100%;
}
#header {
width: 100%;
height: 150px;
background-color: #999999;
}
#container {
width: 760px;
height: calc(100% - 150px);
background-color: #CCCCCC;
margin: 0 auto;
}
Compatibility: calc() is supported in most modern browsers and IE 9 +
Example fiddle and snippet below:
body,
html {
margin: 0;
height: 100%;
}
#header {
width: 100%;
height: 150px;
background-color: #999999;
}
#container {
width: 760px;
height: calc(100% - 150px);
background-color: #CCCCCC;
margin: 0 auto;
}
<div id="header"></div>
<div id="container"></div>
I think the correct modern way to acomplish this without css hacks is with FlexBox, which as of the writting of this post is supported by all modern browsers. (you can check browser compatibility here)
It also gives you more flexibility. If you later decide to add new rows (or even side columns) is very easy to acomplish without any calculations.
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#container {
display: flex; /* Activates FlexBox Model */
flex-direction: column; /* Divs are spanned vertically */
width: 100%;
height: 100%;
}
#header {
background-color: #ccc;
height: 150px;
}
#content {
background-color: #888;
flex-grow: 1;
}
<div id="container">
<div id="header">My header with some stuff</div>
<div id="content">My content</div>
</div>
The outer container has to have position: relative and the div that you want to stretch to the bottom has to have position: absolute. This solution is pure css with no calls to calc().
body, html {
margin: 0;
height: 100%;
}
#container {
position: relative;
width: 100%;
height: 100%;
}
#header {
height: 150px;
width: 100%;
background-color: #999999;
}
#mainContent {
width: 760px;
top: 150px;
bottom: 0;
right: 0;
left: 0;
background-color: #CCCCCC;
margin: 0 auto;
position: absolute;
}
JSFiddle: http://jsfiddle.net/wt0k73bz/

Issues creating 100% height divs using display: table-cell in Firefox

I am trying to create a two-column, full-screen magazine viewer, with a fixed width banner on the left. The right column will be responsive.
Utilising the display:table; method I have created the following:
http://jsfiddle.net/pouncebounce/pTeBP/2/
HTML
<div class="tbl_con">
<div class="tbl_row">
<div class="tbl_cell" id="banner">
</div>
<div class="tbl_cell" id="publication">
</div>
</div>
</div>
<script>
var viewer = new com.zmags.api.Viewer();
viewer.setPublicationID("b129d2b8");
viewer.setParentElementID("publication");
viewer.show();
</script>
CSS
* {
margin: 0;
padding: 0;
border: none;
}
html, body {
height: 100%;
width: 100%;
overflow: hidden;
}
.tbl_con {
display: table;
width: 100%;
min-height: 100%;
*height: 100%;
}
.tbl_row {
display: table-row;
width: 100%;
min-height: 100%;
*height: 100%;
}
.tbl_cell {
display: table-cell;
min-height: 100%;
*height: 100%;
}
#banner {
width: 200px;
background-color: #1E90FF;
border-right: solid 3px #fff;
}
#publication {
width: *;
background-color: #FFAB1E;
}
This displays correctly in the latest version of IE and Chrome, but not in Firefox, where the 100% heights, or the actual magazine, do not appear at all. Any reason why?
Change *height to height and remove min-height.
Make sure you test in IE7, but it should work.

How to set div scrollable when content more than size of the page?

I have the next page:
<div id = "menu">
Menu on the left side
</div>
<div id = "header">
Header content of the page
</div>
<div id = "body">
Data Data Data Data Data Data Data
</div>
<div id = "footer">
Additional Information
</div>
Whith Next layout: Menu should be on the left side:
#menu{
background: #244a7c;
padding: 7px 23px 0 7px;
width: 299px;
height: 1000px;
overflow: inherit;
margin-left: 0px;
display: block;
float: left;
}
#header{
display: inline-block;
width: 400px;
border-bottom: 1px solid rgb(238, 238, 238);
}
Body can have different data inside. My problem is:
When content of the body more than user page I want to fix all div except body. Menu should be on the left side, Header should be on the top of the page and footer on the bottom and ONLY body should be scrollable.
Any help, please.
Thanks!
Here's 2 Pure CSS solution
Without fixing any height (header/footer) or width (left column).
I actually prefer the second solution. (even tho he has less browser support)
1 - using CSS tricks
this is a totally responsive design and work well with all browsers (IE10, FF, Chrome, Safari, Opera, mobile browsers)
Working Fiddle
HTML:
<div class="Container">
<div class="Header">
</div>
<div class="HeightTaker">
<div class="Wrapper Container Inverse">
<div>
<div class="Footer">
</div>
</div>
<div class="HeightTaker">
<div class="Wrapper">
<div class="LeftMenu">
</div>
<div class="Content">
</div>
</div>
</div>
</div>
</div>
</div>
CSS:
*
{
margin: 0;
padding: 0;
}
html, body, .Container
{
height: 100%;
}
.Container:before
{
content: '';
height: 100%;
float: left;
}
.HeightTaker
{
position: relative;
z-index: 1;
}
.HeightTaker:after
{
content: '';
clear: both;
display: block;
}
.Wrapper
{
position: absolute;
width: 100%;
height: 100%;
}
.Inverse, .Inverse > *
{
-moz-transform: rotateX(180deg);
-ms-transform: rotateX(180deg);
-o-transform: rotate(180deg);
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
.LeftMenu
{
height: 100%;
float: left;
}
.Content
{
overflow: auto;
height: 100%;
}
/*For demonstration only*/
p
{
font-size: 1.3em;
}
.Important
{
font-weight: bolder;
color: white;
}
body > .Container
{
text-align: center;
}
.Header
{
background-color: #bf5b5b;
}
.LeftMenu
{
background-color: #bdbe4c;
}
.Content
{
background-color: #90adc1;
}
.Footer
{
background-color: #b5a8b7;
}
2 - using Flex
This layout can also be achieved using flex, but the current browser support is pure.
Here's a Working Fiddle only FF,Chrome,IE10.
HTML: (simpler)
<header>
</header>
<section class="Middle">
<div class="LeftMenu">
</div>
<div class="Content">
</div>
</section>
<footer>
</footer>
CSS:
*
{
margin: 0;
padding: 0;
}
html, body
{
height: 100%;
text-align: center;
}
body
{
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.Middle
{
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 0;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
overflow: hidden;
}
.Content
{
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 0 0;
overflow: auto;
}
/*For demonstration only*/
p
{
font-size: 1.3em;
}
.Important
{
font-weight: bolder;
color: white;
}
header
{
background-color: #bf5b5b;
}
.LeftMenu
{
background-color: #bdbe4c;
}
.Content
{
background-color: #90adc1;
}
footer
{
background-color: #b5a8b7;
}
If you set the header, footer & menu position as fixed & leave the body as it is, it should work. Only the body will be scrollable.
#header {
position: fixed;
top: 0;
display: inline-block;
width: 400px;
border-bottom: 1px solid rgb(238, 238, 238);
}
#footer {
position: fixed;
bottom: 0;
}
#menu {
position: fixed;
left: 0;
background: #244a7c;
padding: 7px 23px 0 7px;
width: 299px;
height: 1000px;
}
#body {
margin-left: 300px;
margin-top: <header-height>;
margin-bottom: <footer-height>;
}

Categories

Resources