I'm currently struggling with making my webpage effective for printing. While it should not be an issue in and of it self, when I'm using the css
page-break-before: always;
it seems to create a massive gap between my elements that does not exist normally (as if a high amount of margin is applied). This makes it so that the element that is broken off to the next page for printing suddenly has massive whitespace above it. would any of you know what's causing this? I already tried setting the margins and paddings to 0 to no avail. See the screenshot below for the issue.
when using Safari, it's adding a massive gap and then it still cuts through the element for some reason.
for those interested, the css (tailwind) applied to the div is:
<div className='h-auto pb-8 mt-4 mb-4 border-gray-200 print:border-0 pagebreak'>
and the classname pagebreak:
#media print {
.pagebreak {
page-break-before: always;
margin: 0%;
padding: 0%;
}
}
Thanks in advance for any help!
Related
I have a simple page with a nested div containing content and button below it, that seems look fine on Safari and Firefox but was having issues on Chrome with the vertical alignment - two elements superimpose on each other due to the min-h-inherit not working(i.e inheriting) as expected.
HTML:
<div id="cont" class="flex flex-col min-h-inherit">
<div>
...
</div>
</div>
CSS:
body {
min-height: -webkit-fill-available;
}
#cont{
position: relative;
}
A workaround was to specifically include h-screen in the cont div but this seems to break the functionality on Safari, by adding a scroll bar to the page and increasing the relative height between the div's.
However, this issue seemed to resolve a bit when adding display: flex to the body, however this seems to break in certain screen sizes:
body {
min-height: -webkit-fill-available;
display: flex;
}
Spent a lot of time trying to get the inheritance to work as expected by referring to existing answers regarding this webkit bug/functionality. Don't understand what the best way to resolve this is.
New to CSS so would really appreciate if someone could shed some light on this. Thanks!
How to reduce the gap between two video tag, I have tried with margin and padding its not worked any help are appreciated
DEMO
My HTML
<div class="videoTest">
<video controls="controls"></video>
<video controls="controls"></video>
<video controls="controls"></video>
<video controls="controls"></video>
</div>
My CSS
.videoTest > video{
border:1px solid red;
margin:0;
padding:0;
}
The <video> element is an inline element by default. That's why there are gaps between them representing the whitespaces and/or line-breaks in your markup.
.videoTest > video {
display: inline-block;
border:1px solid red;
margin:0;
padding:0;
}
.videoTest {
font-size: 0;
}
By using font-size: 0, the line-breaks and whitespaces are being kind of ignored and you get rid of the gaps. Their size is set to 0.
Updated Fiddle
This is a common workaround when working with inline-blocks and is in some situations superior to floats when it comes to centering for example.
try this
http://jsfiddle.net/Ng6XU/5/
.videoTest > video{
border:1px solid red;
margin:0px;
padding:0;
float:left;
}
TRY THIS CSS :
.videoTest > video{
border:1px solid red;
margin:0;
padding:0;
float:left;
}
I have found the link which gives various method to solve this issue, may be helpful to some one Reference : http://css-tricks.com
Published April 21, 2012 by Chris Coyier
Here's the deal: a series of inline-block elements formatted like you normally format HTML will have spaces in between them.
In other words:
<nav>
One
Two
Three
</nav>
nav a {
display: inline-block;
padding: 5px;
background: red;
}
Will result in:
Often highly undesirable (check the link for the output)
We often want the elements to butt up against each other. In the case of navigation, that means it avoids the awkward little unclickable gaps.
This isn't a "bug" (I don't think). It's just the way setting elements on a line works. You want spaces between words that you type to be spaces right? The spaces between these blocks are just like spaces between words. That's not to say the spec couldn't be updated to say that spaces between inline-block elements should be nothing, but I'm fairly certain that is a huge can of worms that is unlikely to ever happen.
Here's some ways to fight the gap and get inline-block elements sitting directly next to each other.
Remove the spaces
The reason you get the spaces is because, well, you have spaces between the elements (a line break and a few tabs counts as a space, just to be clear). Minimized HTML will solve this problem, or one of these tricks:
<ul>
<li>
one</li><li>
two</li><li>
three</li>
</ul>
or
<ul>
<li>one</li
><li>two</li
><li>three</li>
</ul>
or with comments...
<ul>
<li>one</li><!--
--><li>two</li><!--
--><li>three</li>
</ul>
They're all pretty funky, but it does the trick.
Negative margin
You can scoot the elements back into place with negative 4px of margin (may need to be adjusted based on font size of parent). Apparently this is problematic in older IE (6 & 7), but if you don't care about those browsers at least you can keep the code formatting clean.
nav a {
display: inline-block;
margin-right: -4px;
}
Skip the closing tag
HTML5 doesn't care anyway. Although you gotta admit, it feels weird.
<ul>
<li>one
<li>two
<li>three
</ul>
Set the font size to zero
A space that has zero font-size is... zero width.
nav {
font-size: 0;
}
nav a {
font-size: 16px;
}
Matt Stow reports that the font-size: 0; technique has some problems on Android. Quote: "Pre-Jellybean does not remove the space at all, and Jellybean has a bug whereby the last element randomly has a tiny bit of space." See research.
Also note, if you're sizing fonts in ems, this zero font size thing can be an issue, since ems cascade the children would also have zero font size. Rems would be of help here, otherwise any other non-cascading font-size to bump it back up.
Another weirdness! Doug Stewart showed me that if you use #font-face with this technique, the fonts will lose anti-aliasing in Safari 5.0.x. (test case) (screenshot).
Just float them instead
Maybe they don't need to be inline-block at all, maybe they can just be floated one way or another. That allows you to set their width and height and padding and stuff. You just can't center them like you can by text-align: center; the parent of inline-block elements. Well... you kinda can but it's weird.
Just use flexbox instead
If the browser support is acceptable to you and what you need out of inline-block is centering, you could use flexbox. They aren't exactly interchangeable layout models or anything, but you might get what you need out of it.
Since the video tag defaults as an inline-block element, simply make the video tag a block element in CSS. Bob's your uncle.
video {display: block;}
In my case, I was using 640x480 for the video size. I changed it to 640x360 and that removed the white space above the video.
I would say that in my case setting this css helped:
height:auto;
Roughly speaking, attempting to build a four-column layout, I've got this HTML:
<div>
<div>A column</div>
<div>A column</div>
<div>A column</div>
<div>A column</div>
</div>
And I've got this CSS:
div {
background: #ccc;
}
div div {
background: #eee;
display: inline-block;
width: 25%;
}
-> Fiddle me this <-
When rendered in the browser (Currently, I have been testing with Chrome only) the whitespace between the nested div elements (in this example the whitespace is caused by line breaks) is rendered, thus throwing my layout out.
Clearly, I can float my nested divs...
div {
background: #ccc;
}
div div {
background: #eee;
width: 25%;
float: left;
}
-> Fiddle me that <-
But then my container div collapses and I don't want to have to have to use CSS clearfix hacks or extra HTML to open it back up.
Alternatively I can modify my HTML such that the whitespace is removed...
<div><div>A column</div><div>A column</div><div>A column</div><div>A column</div></div>
but that makes it hard to work with. The alternative of breaking the tags so that it becomes more readable somehow leaves me feeling dirty...
<div>
<div>A column</
div><div>A column</
div><div>A column</
div><div>A column</div>
</div>
I've found a resource or two (I failed to find anything on SO) but I don't really like any of the solutions - they are all workarounds, which I will entertain if I must but surely there's an alternative?
So my question(s)... is there a cross-browser, w3c-compliant, non-javascript, hack-free, tidy HTML, bombproof way of preventing HTML whitespace from being rendered in the browser whilst using display:inline-block? Or is there an alternative to inline-block that can be used that has no unpleasant side effects?
EDIT
Assuming that this is genuinely impossible, the best solution would be something that required no addition HTML markup and 'flexible' CSS. In other words, a webmaster could edit the HTML as normal without consideration of breaking the layout, and the CSS (hacked or otherwise) will accommodate the webmaster's amends without having to be amended itself.
MY "WORKAROUND"
Well, it looks like something's got to give. In my situation it is more important to have HTML that doesn't require extra markup so the best solution is to work in a CSS hack that "just works" invisibly. The solution is to float the nested divs and add a hack...
div div {
float: left;
}
div::before,
div::after {
content: "";
display: table;
}
div::after {
clear: both;
}
div {
*zoom: 1;
}
...which is a derivation of a fix I've been using for some time and was hoping to avoid. This succint version of the fix was found on this site.
So now every single div in the markup has got the clearfix hack applied to it whether it needs it or not. I'm yet to learn if this has any bad side-effects by being applied to all divs - I look forward to debugging and fixing when any problems surface ;-)
You provided nearly all possible solutions to this big layout question. I just want to point out my preferred solution.
Set font-size to the parent to 0 and resetting it again with REM's.
You'll have no trouble with your code and layout if there is no additional text inside the parent div (not the child divs).
REM's (Relative EM's) are not relative to the font-size of the parent elements (like normal EM's are), but relative to the root element of your document – the html element.
HTML:
<div class="parent">
<div class="child">column 1</div>
<div class="child">column 2</div>
<div class="child">column 3</div>
<div class="child">column 4</div>
</div>
CSS:
html {
font-size: 1em;
}
.parent {
font-size: 0;
}
.child {
display: inline-block;
font-size: 16px; /* Add pixel-based font-size to support IE8 and below */
font-size: 1rem; /* Don't use rem along with the font-shorthand to avoid problems in IE9/10 - see note below */
width: 25%;
}
No Browser support:
IE8 and below: Add pixel-based font-size to make it work.
IE9/10: not working with font-shorthand; use font-size instead!
(Opera Mini & iOS 3.2)
is there a ... way of preventing HTML whitespace from being rendered in the browser whilst using display:inline-block?
Yes, there are several ways. None of them really meet your criteria of 'hack-free' and 'tidy', but they do work.
Reformat ('minify') your code so that it doesn't have any white space between the elements.
This is probably the most hack-free and cross-browser solution. It isn't necessarily tidy though, and it means you're fixing your layout by adjusting the HTML rather than the CSS, which isn't ideal. But it does work well. If you want to keep your code readable, you could use HTML comments so you can keep the gaps but without them being in the DOM:
<div>block 1</div><!--
--><div>block 2</div><!--
--><div>block 3</div>
Still not ideal, but more readable than a massive single line of code.
Set the font-size to zero for the container, and back to full size again for the blocks.
This works really well. It's a pure CSS solution and easy to do. The down side is that it can be difficult to work with if you've got relative font sizes (ie setting back to 14px is fine, but setting to 1em won't work because 1em of the previous font size of zero is still zero).
Set a 1em negative margin to close the gap.
This also works pretty well, but can be imprecise.
Or is there an alternative to inline-block that can be used that has no unpleasant side effects?
There's always float:left. But that's got a whole range of different issues of its own. If you're using inline-block, the odds are good it's because you don't want to use floats.
Use position:absolute and do the layout manually.
You can use the float method you described in your question, but you didn't clear your floats, which is why the container collapses.
A good method is to use an ::after pseudo element attache to the container element to "auto-clear" itself:
div:after {
content: "";
display: table;
clear: both;
}
http://jsfiddle.net/s2rJW/3/
When i saw your "workaround" i was thinking: Why don't you use a <table>?
And then i figured this out:
div {
background: #ccc;
display: table;
width: 100%;
}
div div {
background: #eee;
display: table-cell;
width: 25%
}
<div>
<div>A column</div>
<div>A column</div>
<div>A column</div>
<div>A column</div>
</div>
I have several DIV's displayed as inline-blocks; and they seem to be getting spacing automatically applied in between them from the browser. They have margin/padding set to 0. Is there a way to correct this without using negative margins?
Sam, that space you're seeing is actually whitespace. That's why removing the paddings and margins does nothing. Let me explain. When you have this:
HTML
<div>
a
a
a
a
</div>
this is how it's rendered:
a a a a
...right?
So, if you have this:
<div>
<div style="display:inline-block"></div>
<div style="display:inline-block"></div>
<div style="display:inline-block"></div>
</div>
...you'll get the same thing:
block [space] block [space] block
Now... there are many different solutions to this problem. I believe the most common is commenting out the whitespace in the html:
<div>
<div style="display:inline-block"></div><!--
--><div style="display:inline-block"></div><!--
--><div style="display:inline-block"></div>
</div>
I don't like it though - I prefer keeping the html as clean as possible. My preferred way is to set the parent's font-size to 0, and then set back the desired font-size on the inline-blocks themselves. Like so:
div {
font-size: 0; /* removes the whitespace */
}
div div {
display: inline-block;
font-size: 14px;
}
You don't need to use negative margins to offset the original margins.
Instead you can override them with the following:
* { margin:0; }
or:
.div { margin:0; }
if it's element specific.
EDIT:
It appears the problem may be a result of unintended whitespace. For instance:
<div style="display:inline-block">
...
</div>
<div style="display:inline-block">
...
</div>
There exists white space between the two dividers and the browser will print the white space as a result. To fix this, you'll need to change it to:
<div style="display:inline-block">
...
</div><div style="display:inline-block">
...
</div>
Enjoy and good luck!
You can use both display: inline-block and float: left to remove that space.
Here goes plunkr: https://plnkr.co/edit/Sn3NG77asiXO8UrrpxWD?p=preview
Inline-block is originally a IE6 hack
This is what its used for:
To fix the IE6 double-margin bug on floated elements
To place multiple block-like elements on the same horizontal line
without floating them(if you can't float 'exceptional cases)
To allow an inline element to have width and/or height while still
remaining inline
To allow an inline element to have padding or margins
So if you wanna have multiple divs beside eachother please use float, its gonna solve many of your css problems that inline-block can cause, especially cross browser issues
More about inline-block here arcticle 9.2.4
Best regards
SP
please comment if disagree
Another way I have found the method altering the word-spacing on the parent container works for me https://jsfiddle.net/1ex5gpo3/2/
.parent {
word-spacing: -1em;
}
.child {
word-spacing: normal;
display: inline-block;
}
I'm having trouble getting this working in most browsers, except for IE (it even works correctly in IE6) and Opera.
Firefox separates the divs correctly but only prints the first page.
Chrome and Safari only applies the page break to the last div.
How can I get this working across all browsers correctly?
The HTML:
<div id="leftNav">
<ul>
<!--links etc-->
</ul>
</div>
<div id="mainBody">
<div id="container">
<div class="pageBreak">
<!--content-->
</div>
<div class="pageBreak">
<!--content-->
</div>
<div class="pageBreak">
<!--content-->
</div>
</div>
</div>
The divs with the IDs #leftNav and #mainBody are are set to float:left, so they display nicely.
I only want to print the .pageBreak classes, hiding the #leftNav and the rest of the #mainBody with CSS.
The CSS:
#media print
{
#leftNav
{
display:none;
}
#mainBody
{
border:none;
margin:none;
padding:none;
}
}
Parent elements can not have float on them.
Setting float:none on all parent elements makes page-break-before:always work correctly.
Other things that can break page-break are:
using page-break inside tables
floating elements
inline-block elements
block elements with borders
For the sake of completion, and for the benefit of others who are having the same problem, I just want to add that I also had to add overflow: visible to the body tag in order for FireFox to obey the page breaks and even to print more than just the first page.
I've found that Twitter Bootstrap classes add a bunch of stuff to the page which has made it difficult to get page-breaks working. Firefox worked right away, but I've had to follow various suggestions to get it to work in Chrome and, finally, IE (11).
I followed the suggestions here and elsewhere. The only property I "discovered" that I haven't seen yet mentioned is "box-sizing". Bootstrap can set this property to "box-sizing: border-box", which broke IE. An IE-friendly setting is "box-sizing: content-box". I was led to this by the caveat about "block elements with borders" made by Richard Parnaby-King https://stackoverflow.com/a/5314590/3397752.
It looks like it's a bit of an arms race to discover the next property that might break page-breaks.
This is the setting that worked for me (Chrome, FF, IE 11). Basically, it tries to override all the problematic settings on all divs on the printed page. Of course, this might also break your formatting, and that would mean that you'll have to find another way to set up the page.
#media print {
div { float: none !important; position: static !important; display: inline;
box-sizing: content-box !important;
}
}
There is a solution if the parent has float . For the element to which you applied the page-break, make the element overflow:hidden. Thats all. It worked for me.
<div style='float:left'>
<p style='overflow:hidden;page-break-before:always;'></p>
</div>
Although this is not prominently documented, it should be noted that the page-break properties cannot be applied to table elements. If you have any elements that have a display: table; or display:table-cell; applied to them (common in many templates under the clearfix class) then contained elements will ignore the page-break rules. Just cancel out the the rule in your print stylesheet and you should be OK (after the floats have also been removed, of course).
Here is an example of how to do this for the popular clearfix problem.
.clearfix:before, .clearfix:after{
display: block!important;
}
The other place I have run into this is when the template declared the entire page (usually called main or main wrapper) with display:inline-block;
If the section is inside of an inline-block, it will not work so keep your eyes open for those as well. Changing or overwriting display:inline-block; with display:block should work.
I had a position: absolute; in the div printing that caused this not to work.
Make sure the parent element has display:block; rather than display: flex;. This helped me fix the issue
"Firefox versions up to and including 3.5 don’t support the avoid, left, or right values."
IE support is also partial
you can achieve what needed by :page-break-before:always; which is supported in all browsers
"but only print the first page" : I don't think it is css related , I suppose it's sth on print window of browser :)
what's your code?
like this?:
<style>
#media print
{
table {page-break-after:always}
}
#media print
{
table {page-break-before:always}
}
</style>