I have a problem with CSS page-break-inside: avoid. I have some printing blocks which have this css attribute set, however Safari breaks any content just as the real page break occurs, while it works in all other major browsers (current versions) I've tested so far.
It doesn't seem to matter which type of content the printing block holds as I've seen this behavior with both a table and a canvas element being split up right in the middle.
As far as http://css-tricks.com/almanac/properties/p/page-break/ and https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html is concerned it should work. Couldn't find any additional and recent information on this matter with a quick search.
I'm on Windows 7 & Safari 5.1.7.
Try using display: inline-block; instead of page-break-inside: avoid;. You may also want to add vertical-align: top; and width: 100%; to make the elements behave like normal block elements instead of inline elements.
This technique has been working reliably since long before page-break-inside: avoid; was implemented in most browsers. It's still the most reliable cross-platform way to prevent page breaks in a block of content.
If you want to make a table unbreakable, you can set display: inline-table; on it. Or you can just put it in an inline-block div.
page-break-inside: avoid (or variations thereof) seems to fail on Safari occasionally b/c its use depends very much on the display of the containing element and its height.
Mine was broken b/c I had defined the original page layout of the containing element to have height: 100%, which looks benign on the browser but I would notice that my elements were broken across pages in the print preview.
My fix was just to explicitly set the height of my container back to the browser default:
#media print {
// Explicitly set height: auto
.page-container {
display: block;
height: auto;
}
section {
break-inside: avoid;
}
}
This on Safari v14.1.2
Related
A few other questions have already addressed how best to apply text-align: justify to get inline-block elements to spread out evenly… for example, How do I *really* justify a horizontal menu in HTML+CSS?
However, the 100% width element that "clears" the line of inline-block elements is given its own line by the browser. I can't figure out how to get rid of that empty vertical space without using line-height: 0; on the parent element.
For an example of the problem, see this fiddle
For my solution that uses line-height: 0;, see this fiddle
The solution I'm using requires that a new line-height be applied to the child elements, but any previously set line-height is lost. Is anyone aware of a better solution? I want to avoid tables so that the elements can wrap when necessary, and also flexbox because the browser support isn't there yet. I also want to avoid floats because the number of elements being spaced out will be arbitrary.
Updated the "Future" solution info below; still not yet fully supported.
Present Workaround (IE8+, FF, Chrome Tested)
See this fiddle.
Relevant CSS
.prevNext {
text-align: justify;
}
.prevNext a {
display: inline-block;
position: relative;
top: 1.2em; /* your line-height */
}
.prevNext:before{
content: '';
display: block;
width: 100%;
margin-bottom: -1.2em; /* your line-height */
}
.prevNext:after {
content: '';
display: inline-block;
width: 100%;
}
Explanation
The display: block on the :before element with the negative bottom margin pulls the lines of text up one line height which eliminates the extra line, but displaces the text. Then with the position: relative on the inline-block elements the displacement is counteracted, but without adding the additional line back.
Though css cannot directly access a line-height "unit" per se, the use of em in the margin-bottom and top settings easily accommodates any line-height given as one of the multiplier values. So 1.2, 120%, or 1.2em are all equal in calculation with respect to line-height, which makes the use of em a good choice here, as even if line-height: 1.2 is set, then 1.2em for margin-bottom and top will match. Good coding to normalize the look of a site means at some point line-height should be defined explicitly, so if any of the multiplier methods are used, then the equivalent em unit will give the same value as the line-height. And if line-height is set to a non-em length, such as px, that instead could be set.
Definitely having a variable or mixin using a css preprocessor such as LESS or SCSS could help keep these values matching the appropriate line-height, or javascript could be used to dynamically read such, but really, the line-height should be known in the context of where this is being used, and the appropriate settings here made.
UPDATE for minified text (no spaces) issue
Kubi's comment noted that a minification of the html that removes the spaces between the <a> elements causes the justification to fail. A pseudo-space within the <a> tag does not help (but that is expected, as the space is happening inside the inline-block element), a <wbr> added between the <a> tags does not help (probably because a break is not necessary to the next line), so if minification is desired, then the solution is a hard coded non-breaking space character --other space characters like thin space and en space did not work (surprisingly).
Nearing a Future Clean Solution
A solution in which webkit was behind the times (as of first writing this) was:
.prevNext {
text-align: justify;
-moz-text-align-last: justify;
-webkit-text-align-last: justify; /* not implemented yet, and will not be */
text-align-last: justify; /* IE */
}
It works in FF 12.0+ and IE8+ (buggy in IE7).
For Webkit, as of version 39 (at least, might have crept in earlier) it does support it without the -webkit- extension but only if the user has enabled the experimental features (which can be done at chrome://flags/#enable-experimental-web-platform-features). Rumor is that version 41 or 42 should see full support. Since it is not seamlessly supported by webkit yet, it is still only a partial solution. However, I thought I should post it as it can be useful for some.
Consider the following:
.prevNext {
display: table;
width: 100%
}
.prevNext a {
display: table-cell;
text-align: center
}
(Also see the edited fiddle.) Is that what you are looking for? The advantage of this technique is that you can add more items and they will all be centered automatically. Supported by all modern Web browsers.
First off, I like the approach of the pseudo-element in order to keep the markup semantic. I think you should stick with the overall approach. It's far better than resorting to tables, unnecessary markup, or over the top scripts to grab the positioning data.
For everyone stressed about text-align being hacky - c'mon! It's better that the html be semantic at the expense of the CSS than vice versa.
So, from my understanding, you're trying to achieve this justified inline-block effect without having to worry about resetting the line-height every time right? I contend that you simply add
.prevNext *{
line-height: 1.2; /* or normal */
}
Then you can go about coding as though nothing happened. Here's Paul Irish's quote about the * selector if you're worried about performance:
"...you are not allowed to care about the performance of * unless you concatenate all your javascript, have it at the bottom, minify your css and js, gzip all your assets, and losslessly compress all your images. If you aren't getting 90+ Page Speed scores, it's way too early to be thinking about selector optimization."
Hope this helps!
-J Cole Morrison
Attempting to text-align for this problem is pretty hackish. The text-align property is meant to align inline content of a block (specifically text) -- it is not meant to align html elements.
I understand that you are trying to avoid floats, but in my opinion floats are the best way to accomplish what you are trying to do.
In your example you have line-height:1.2, without a unit. This may cause issues. If you're not using borders you could give the parent and the children a line-height of 0.
The other options I can think of are:
Use display:table on the parent and display:table-cell on the children to simulate table like behaviour. And you align the first item left, and the last one right. See this fiddle.
Use javascript to do a count of the nav children and then give them a equally distributed width. eg. 4 children, 25% width each. And align the first and last items left and right respectively.
There is a way to evenly distribute the items but is a convoluted method that requires some non breaking spaces to be carefully placed in the html along with a negative margin and text-align:justify. You could try and adapt it the the nav element. See example here.
Your fiddle is awfully specific. It seems to me for your case this CSS would work well:
.prevNext {
border: 1px solid #ccc;
position: relative;
height: 1.5em;
}
.prevNext a {
display: block;
position: absolute;
top: 0;
}
.prevNext a:first-child {
left: 0;
text-align: left;
}
.prevNext a:last-child {
right: 0;
text-align: right;
}
As stated by #Scotts, the following has been implemented inside Chrome, without the -webkit part , which I really loved btw, specially since we need to get rid of the -browser-specific-shǐt real soon.
.prevNext {
text-align: justify;
-moz-text-align-last: justify;
-webkit-text-align-last: justify; /* not implemented yet, and will not be */
text-align-last: justify; /* IE + Chrome */
}
Note: Though still the Safari and Opera don't support it yet (08-SEPT-16).
I think the best way would be to create the clickable element with a specific class/id and then assign float:left or float:right accordingly. Hope that helps.
So I have a standard 960 width website where the content is, and I have boxes set up that are 300 width, and 10 margin on each side, so they will float 3 across. It looks fine in FF and Chrome, but why in IE does the 3rd box always jump down to the next line and throw off the positiong. It's like IE reads widths differently than any other browser. It is soooo annoying, is there any way to fix this?
You have to reset all elements before start (CSS reset)
Example : http://necolas.github.io/normalize.css/
Why ? : CSS reset - What exactly does it do?
As l2aelba says, you need to reset your elements. The problem is that each browser has its own set of default values for various elements. So IE might add padding that the others don't, making your elements too big to fit so they wrap around.
Resetting makes each browser display things as similarly as possible.
Without seeing your HTML and CSS there is no sure way to determine what your problem attribute is.
Solution:
Your problem is this line:
max-width: 68.571428571rem;
It is on ine 1967 of your css. It is overriding your 960 width, because that value is actually smaller than 960px, because it comes second. Not even sure why you have that in there...
After looking at your site, you have this style in your style sheet
.site {
margin: 0 auto;
max-width: 960px;
max-width: 68.571428571rem;
overflow: hidden;
}
beware of em as it's calculated differently in different browsers, in IE it calculates to around 955.4px, which is why you're getting the wrapping.
Change the style to
.site {
margin: 0 auto;
max-width: 960px;
overflow: hidden;
}
and you should be fine.
I had big trouble with printing from Firefox (any version, mine is 16.0.2, but even Aurora dev builds did the same).
When printing the page, Shrink to fit in the Print preview doesn't work. Only way, how to fit the page onto the paper is selecting Zoom 70% in the same dialog.
Other problem:
it prints only first page.
What to do?
I needed to adapt the CSS file for printing, so I've done one. It works flawlessly anywhere, but not in Firefox. What was the problem?
First I've tried specifying Width and height for BODY and HTML in the print.css file. Than margins, etc.
Later I figured out what was the problem:
standard CSS file had the following in it:
body {
...
overflow-x: hidden;
overflow-y: scroll;
}
So I've added the following into the print.css file:
body {
overflow-x: visible;
overflow-y: visible;
}
I guess, if you had only overflow specified in the CSS, not -x & -y, you would need to specify only overflow:visible in the print.css file.
Printing from Firefox works now as it should. I just thought, that this may help somebody, who has strange printing behavior happening in Firefox.
In addition to the Kokesh's answer, some times attribute
display: table
generates this problem too. So you need change it to 'block' or another that fits to your requeriments.
I tried the fixes suggested in other answers but they didn't solve the problem for me. After a lot of research and trial & error, I have found this article by A list apart. I was skeptical because it's so old but it states that:
If a floated element runs past the bottom of a printed page, the rest of the float will effectively disappear, as it won’t be printed on the next page.
As I have a big floated container I thought I'd give it a try. So, I made a mix from the other answers and this article and came up with this:
body {
overflow: visible !important;
overflow-x: visible !important;
overflow-y: visible !important;
}
/*this is because I use angular and have this particular layout*/
body > .fade-ng-cloak {
height: 100%;
display: block;
flex: none;
float: none;
}
.l-content,
.l-sidebar {
float: none;
}
So basically:
Setting body to overflow: visible
Setting elements that behave as wrappers to display: block, eliminate all flex styles and reset height if necessary
Eliminate float on long containers
That mix worked for me! I'm so happy I thought I'd share :)
A few other questions have already addressed how best to apply text-align: justify to get inline-block elements to spread out evenly… for example, How do I *really* justify a horizontal menu in HTML+CSS?
However, the 100% width element that "clears" the line of inline-block elements is given its own line by the browser. I can't figure out how to get rid of that empty vertical space without using line-height: 0; on the parent element.
For an example of the problem, see this fiddle
For my solution that uses line-height: 0;, see this fiddle
The solution I'm using requires that a new line-height be applied to the child elements, but any previously set line-height is lost. Is anyone aware of a better solution? I want to avoid tables so that the elements can wrap when necessary, and also flexbox because the browser support isn't there yet. I also want to avoid floats because the number of elements being spaced out will be arbitrary.
Updated the "Future" solution info below; still not yet fully supported.
Present Workaround (IE8+, FF, Chrome Tested)
See this fiddle.
Relevant CSS
.prevNext {
text-align: justify;
}
.prevNext a {
display: inline-block;
position: relative;
top: 1.2em; /* your line-height */
}
.prevNext:before{
content: '';
display: block;
width: 100%;
margin-bottom: -1.2em; /* your line-height */
}
.prevNext:after {
content: '';
display: inline-block;
width: 100%;
}
Explanation
The display: block on the :before element with the negative bottom margin pulls the lines of text up one line height which eliminates the extra line, but displaces the text. Then with the position: relative on the inline-block elements the displacement is counteracted, but without adding the additional line back.
Though css cannot directly access a line-height "unit" per se, the use of em in the margin-bottom and top settings easily accommodates any line-height given as one of the multiplier values. So 1.2, 120%, or 1.2em are all equal in calculation with respect to line-height, which makes the use of em a good choice here, as even if line-height: 1.2 is set, then 1.2em for margin-bottom and top will match. Good coding to normalize the look of a site means at some point line-height should be defined explicitly, so if any of the multiplier methods are used, then the equivalent em unit will give the same value as the line-height. And if line-height is set to a non-em length, such as px, that instead could be set.
Definitely having a variable or mixin using a css preprocessor such as LESS or SCSS could help keep these values matching the appropriate line-height, or javascript could be used to dynamically read such, but really, the line-height should be known in the context of where this is being used, and the appropriate settings here made.
UPDATE for minified text (no spaces) issue
Kubi's comment noted that a minification of the html that removes the spaces between the <a> elements causes the justification to fail. A pseudo-space within the <a> tag does not help (but that is expected, as the space is happening inside the inline-block element), a <wbr> added between the <a> tags does not help (probably because a break is not necessary to the next line), so if minification is desired, then the solution is a hard coded non-breaking space character --other space characters like thin space and en space did not work (surprisingly).
Nearing a Future Clean Solution
A solution in which webkit was behind the times (as of first writing this) was:
.prevNext {
text-align: justify;
-moz-text-align-last: justify;
-webkit-text-align-last: justify; /* not implemented yet, and will not be */
text-align-last: justify; /* IE */
}
It works in FF 12.0+ and IE8+ (buggy in IE7).
For Webkit, as of version 39 (at least, might have crept in earlier) it does support it without the -webkit- extension but only if the user has enabled the experimental features (which can be done at chrome://flags/#enable-experimental-web-platform-features). Rumor is that version 41 or 42 should see full support. Since it is not seamlessly supported by webkit yet, it is still only a partial solution. However, I thought I should post it as it can be useful for some.
Consider the following:
.prevNext {
display: table;
width: 100%
}
.prevNext a {
display: table-cell;
text-align: center
}
(Also see the edited fiddle.) Is that what you are looking for? The advantage of this technique is that you can add more items and they will all be centered automatically. Supported by all modern Web browsers.
First off, I like the approach of the pseudo-element in order to keep the markup semantic. I think you should stick with the overall approach. It's far better than resorting to tables, unnecessary markup, or over the top scripts to grab the positioning data.
For everyone stressed about text-align being hacky - c'mon! It's better that the html be semantic at the expense of the CSS than vice versa.
So, from my understanding, you're trying to achieve this justified inline-block effect without having to worry about resetting the line-height every time right? I contend that you simply add
.prevNext *{
line-height: 1.2; /* or normal */
}
Then you can go about coding as though nothing happened. Here's Paul Irish's quote about the * selector if you're worried about performance:
"...you are not allowed to care about the performance of * unless you concatenate all your javascript, have it at the bottom, minify your css and js, gzip all your assets, and losslessly compress all your images. If you aren't getting 90+ Page Speed scores, it's way too early to be thinking about selector optimization."
Hope this helps!
-J Cole Morrison
Attempting to text-align for this problem is pretty hackish. The text-align property is meant to align inline content of a block (specifically text) -- it is not meant to align html elements.
I understand that you are trying to avoid floats, but in my opinion floats are the best way to accomplish what you are trying to do.
In your example you have line-height:1.2, without a unit. This may cause issues. If you're not using borders you could give the parent and the children a line-height of 0.
The other options I can think of are:
Use display:table on the parent and display:table-cell on the children to simulate table like behaviour. And you align the first item left, and the last one right. See this fiddle.
Use javascript to do a count of the nav children and then give them a equally distributed width. eg. 4 children, 25% width each. And align the first and last items left and right respectively.
There is a way to evenly distribute the items but is a convoluted method that requires some non breaking spaces to be carefully placed in the html along with a negative margin and text-align:justify. You could try and adapt it the the nav element. See example here.
Your fiddle is awfully specific. It seems to me for your case this CSS would work well:
.prevNext {
border: 1px solid #ccc;
position: relative;
height: 1.5em;
}
.prevNext a {
display: block;
position: absolute;
top: 0;
}
.prevNext a:first-child {
left: 0;
text-align: left;
}
.prevNext a:last-child {
right: 0;
text-align: right;
}
As stated by #Scotts, the following has been implemented inside Chrome, without the -webkit part , which I really loved btw, specially since we need to get rid of the -browser-specific-shǐt real soon.
.prevNext {
text-align: justify;
-moz-text-align-last: justify;
-webkit-text-align-last: justify; /* not implemented yet, and will not be */
text-align-last: justify; /* IE + Chrome */
}
Note: Though still the Safari and Opera don't support it yet (08-SEPT-16).
I think the best way would be to create the clickable element with a specific class/id and then assign float:left or float:right accordingly. Hope that helps.
So, I think this is a CSS issue more than anything, but basically, the HTML I've provided contains a fixed header table in a reactive layout.
Code:
http://jsfiddle.net/JpRQh/10/
There are 3 rows of data, but in IE9, it seems like table rows are crazy high, and the scroll bar hase been disabled.
The example that I followed on fixed header tables:
http://www.imaputz.com/cssStuff/bigFourVersion.html
has the same problem in IE9.
Any ideas on how to fix it?
EDIT: I promise the table scrolls if there is enough data. But i only included 3 rows for example.
This is the rule that causes the trouble in IE. Live example: http://jsfiddle.net/JpRQh/12/
html>body tbody.scrollContent {
margin-top: 24px;
padding-top: 8px;
display: block;
height: 400px; /* If you delete this rule you will see the table rows return to their normal size */
overflow: auto;
width: 100%
}
Styling a scrolling tbody and fixed headers etc. tends to cause a lot of issues with cross-browser compatibility. You might look at this link about cross-browser scrolling tbody.
This however seems to be the best looking cross-browser solution. You will need to inspect the CSS.