Browser Support for CSS Page Numbers - css

So I am aware of this option: Page numbers with CSS/HTML.
It seems by far to be the best way to add page numbers to a print version of a page, but I can't get any variation of this to work anywhere. I have tried on my Windows 7 machine in Chrome, Firefox, and IE9. Based on some of the links it looks like this may be supported in more proprietary software like Prince XML. Is this supported by web browsers for print versions?
I have tried making just a blank html file and in the head adding this between two style tags:
#page {
#bottom-right {
content: counter(page) " of " counter(pages);
}
}
I have also simplified it even to just use content: "TEXT"; to see if I can get something to show up. Is this supported anywhere? By 'this' I'm specifically meaning the #page and #bottom-right tags, since I have gotten content to work many times.

I've been trying to implement paged media as well and have found, according to this Wikipedia page, that there's no browser support for margin boxes as yet. No wonder it wouldn't work!
http://en.wikipedia.org/wiki/Comparison_of_layout_engines_(Cascading_Style_Sheets)
See the table, Grammar and Rules, margin boxes section. Margin boxes are what's needed for page numbering as well as running headers and footers. Getting this implemented would save me the overhead of having to convert the printed media to PDF.

Not using #page, but I have gotten pure CSS page numbers to work in Firefox 20:
http://jsfiddle.net/okohll/QnFKZ/
To print, right click in the results frame (bottom right) and select
This Frame -> Print Frame...
The CSS is
#content {
display: table;
}
#pageFooter {
display: table-footer-group;
}
#pageFooter:after {
counter-increment: page;
content: counter(page);
}
and the HTML is
<div id="content">
<div id="pageFooter">Page </div>
multi-page content here...
</div>

This does not seem to work anymore. Appears it only worked for a short time and browser support was removed!
Counters have to be reset before they can be used, according to https://developer.mozilla.org/en-US/docs/CSS/Counters.
You can set your starting number to whatever, the default is 0.
Example:
#page {
counter-increment: page;
counter-reset: page 1;
#top-right {
content: "Page " counter(page) " of " counter(pages);
}
}
... in theory. In real world only PrinceXML supports this.

Via Mozilla, (Printing a document)
This puts a header and footer on each printed page. This works well in Mozilla, but not quite so well in IE and Chrome.
<!DOCTYPE html>
<html>
<head>
<title>Print sample</title>
<link rel="stylesheet" href="style4.css">
</head>
<body>
<h1>Section A</h1>
<p>This is the first section...</p>
<h1>Section B</h1>
<p>This is the second section...</p>
<div id="print-head">
Heading for paged media
</div>
<div id="print-foot">
Page:
</div>
</body>
</html>
The CSS:
/*** Print sample ***/
/* defaults for screen */
#print-head,
#print-foot {
display: none;
}
/* print only */
#media print {
h1 {
page-break-before: always;
padding-top: 2em;
}
h1:first-child {
page-break-before: avoid;
counter-reset: page;
}
#print-head {
display: block;
position: fixed;
top: 0pt;
left:0pt;
right: 0pt;
font-size: 200%;
text-align: center;
}
#print-foot {
display: block;
position: fixed;
bottom: 0pt;
right: 0pt;
font-size: 200%;
}
#print-foot:after {
content: counter(page);
counter-increment: page;
}

If you are looking to add page numbers when printing under Chrome/Chromium, one easy solution is to use Paged.js.
This JS library takes your HTML/CSS and cuts it into pages, ready to print as a book, that you will preview in your browser. It makes the #page and most the CSS3 specifications work for Chrome.
Solution 1 (easy) if you are OK with cutting your view into pages, ready to print
Just add their CDN in the head tag of your page :
<link href="path/to/file/interface.css" rel="stylesheet" type="text/css">
You can then add page numbers by using the automated counter page. Example :
HTML to put anywhere you want to display the current page number:
<div class="page-number"></div>
CSS to make the number appear in the div :
.page-number{
content: counter(page)
}
The library also allows to easily manage page margins, footers, headers, etc.
Solution 2 (trickier) if you want to show numbers (and page breaks) only when printing
In this case, you need to apply the Paged.js CDN only when printing the document.
One way I can think of would be to add a print me button that fires Javascript to :
add the CDN to the page
and then execute window.print(); to launch the printing prompt of the navigator

Related

When zooming, <audio> object moves up from bottom and overlaps stuff on top

The following problem occurs for my <audio> tag with iOS Safari, Firefox and Dolphin browsers, but not on any OS browser = the audio control moves up with zooming+ and ultimately overlaps the object above it.
The static layout, no zooming, is great ... zooming throws everything over the cliff.
FWIW, I did mess with the meta "viewport" tag, but no luck.
<audio> object is at the bottom of the layout. It obeys my css code, except when I zoom. When I zoom via pinching out, the object moves up and overlaps the <section> above it.
html {
font-size: 20px; /* baseline for all descendants */
font-size: 2.5vw;
}
.caroler {
text-align: center;
font-size: 1.70em;
color: blue;
padding-bottom: 1.0em;
}
.aSongControl {
display: block; /* center ... */
margin: 0 auto;
width: 90%; /* squeeze width because of .content's rounded corners */
font-size: 120%; /* for non-support text ... */
color: #990099;
}
/*
This is the audio control-specific Selector.
Other Selectors handle position and sizing.
*/
audio {
background-color: white;
}
#theSong {
/*
deliberately empty just to initialize
certain <audio> parms, e.g., the volume
*/
}
<meta name="viewport" content="width=device-width, initial-scale=1">
Inside <body>
<section class="caroler">
as sung by an unknown Caroler<br>
in front of the White House<br>
on December 24th, 2018
</section>
<audio id="theSong" class="aSongControl" controls preload="auto">
<source src="audio/Lafayette_Square.m4a" type="audio/mp4">
<a href='http://www.apple.com/quicktime/download/' title='Get Quicktime' onclick='window.open(this.href); return false'>
Install Quicktime to hear this awesome Hymn
</a><br>
</audio>
<audio>
As General Custer probably yelled "HAALP!"
NEW ADDITIONS TO OP:
1) a reader below strongly urged to disable zooming via a small change to the <meta> tag. Easy enough, but I can only echo what another member of STO said "It's just not nice to disable zooming, especially for those who depend on this feature".
2) Anyway, let's press on. I have 'regressed' to using JS and ditched the Viewport units, vw and vh:
document.body.setScaledFont = function(f) {
var s = this.offsetWidth, fs = s * f;
this.style.fontSize = fs + '%';
return this
};
document.body.setScaledFont(0.10);
window.onresize = function() {
document.body.setScaledFont(0.10);
}
Guess what? The <audio> STILL MOVES UP and eventually covers the <div> immediately prior to the <audio>. This undeniably means that the use of vw, vh units are not the problem.
Here is a repeat of the code for the <audio> above:
<audio id="theSong" class="aSongControl" controls preload="auto">
<source src="audio/Lafayette_Square.m4a" type="audio/mp4">
<a href='http://www.apple.com/quicktime/download/' title='Get Quicktime' onclick='window.open(this.href); return false'>
Install Quicktime to hear this awesome Hymn
</a><br>
</audio>
<audio>
with:
.aSongControl {
display: block; /* center ... */
margin: 0 auto;
width: 90%;
font-size: 120%; /* for non-support text ... */
color: #990099;
}
audio {
background-color: white;
}
At this point, I do not understand why I have to place the class="aSongControl" inside the <audio> tag in order to get the <audio> to fill the window's width via width: 80%
If I try:
<section class="aSongControl">
<audio id="theSong" controls preload="auto">
...
</audio>
</section>
there is no block centering and no window-filling, both of which are called for within .aSongControl.
I wish I knew the answer because just maybe this answer holds a clue as to why the <audio> control exhibits a mind of its own by mysteriously moving up and covering the <div> above the <audio>.
Again, no problem on OS browsers ... just the iOS browsers.
It's New Year's folks, take pity on me!
Try using this, Hope it will help.
<meta
name='viewport'
content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0'
/>
This will prevent user from zooming

Is it possible to negate an element from receiving display:none using the :not pseudo-class in CSS?

<html>
<body>
<nav>....</nav>
<article>more things...</article>
<div id="myModal" class="modal">contents</div>
<body>
</html>
In linked CSS file (using Chrome):
#media print{
body:not(#myModal){
display:none;
visibility:hidden;
}
#myModal{ /*shouldn't have to but doesn't work anyway */
display:block;
visibility:visible;
}
}
This does not work. I am trying to get rid of everything behind the modal for printing without scripting. Apparently that is not possible. Can a display:none :not not negate elements contained within the container?
Edit: I have looked here, but cannot find the answer. https://www.w3.org/TR/css3-selectors/#negation
Edit: I want to hide everything except the modal. But display:none keeps that from happening. It does it for the whole body element, regardless of my negation.
Edit: Whatever it is, it does not work in the media call, so my current idea is to move the div. I thought there might be a better way. Edit: I also need display:none because print will still print the blank pages where the elements are hidden. display will remove those elements and allow me to print my modal without a bunch of blank pages of hidden elements.
display: none doesn't load the element or it's children. To Chrome, Firefox, etc., #myModal doesn't exist. Consequently, you can't use display: none as the way to did.
There are other alternatives though:
Option 1
#media print {
* {
visibility: hidden;
height: 0 !important; /* added !important with info from update */
}
#myModal {
visibility: visible;
height: auto !important;
}
}
<body>
<nav>....</nav>
<article>more things...</article>
<div id="myModal" class="modal">contents</div>
<button onclick="window.print();">Print</button>
<body>
Option 2 This probably won't work with your new update.
#media print {
body > *:not(#myModal) {
display: none;
}
}
<body>
<nav>....</nav>
<article>more things...</article>
<div id="myModal" class="modal">contents</div>
<button onclick="window.print();">Print</button>
<body>

Counting DOM elements with CSS - not working consistently

As part of some performance testing, I want to see how many DOM elements there are within a page at any given time.
Initially I used the console and manually typed: document.getElementsByTagName('*').length
But being that elements are dynamically added and removed, I wanted a way to show this automatically without having to do this manually.
Using CSS counters seemed to be the easiest way for me to do this:
(Here's a demo: see the yellow box in the top right)
html {
counter-reset: elems;
counter-increment: elems;
}
html * {
counter-increment: elems;
}
body:after {
content: counter(elems) ' elements';
position: absolute;
top:0;
right: 0;
padding: 0.5rem;
background-color: yellow;
z-index: 1000000000; /* make sure display appears on top */
}
html + head + body = 3... +
A section with 4 divs = 5..... 3 + 5 = 8
<section>
<div>div1</div>
<div>div2
<div>div3</div>
</div>
<div>div4</div>
<section>
The problem is that this technique is not working for some more complex websites, and i'm guessing that it's because it's somehow naive.
Take for instance wikipedia's main page - I used the browser inspector to add the above css-counter css and that produced "888 elements"
However when I used the console document.getElementsByTagName('*').length - it returned 975 elements.
So my question is:
What is causing this huge discrepancy in the number of DOM elements, is there something I haven't taken into account?
Can this be done reliably with CSS?
The reason you get different counts is because your counter-increment: elems; rule is lower priority than some existing counter-increment rules in Wikipedia's stylesheet, so there are elements which increment other counters (one example is named "listitem") but not yours.
You'd have to make your selector more specific and override Wikipedia's, or add the website's own counter (or write some JavaScript to add your own counter in the existing counter-increment rules, to avoid breaking the existing style).
What is causing this huge discrepancy in the number of DOM elements,
is there something I haven't taken into account?
Yes, elements which have display:none applied are ignored by css counters.
From the spec:
An element that does not generate a box (for example, an element with
display set to none, or a pseudo-element with content set to none)
cannot set, reset, or increment a counter. The counter properties are
still valid on such an element, but they must have no effect.
Demo:
html {
counter-reset: elems;
counter-increment: elems; /* Include the html element as well */
}
html * {
counter-increment: elems;
}
body:after {
content: counter(elems) ' elements';
position: absolute;
top:0;
right: 0;
padding: 0.3rem;
background-color: lightyellow;
z-index: 1000000000; /* make sure display appears on top */
}
.hidden {
display: none;
}
html + head + body = 3... +
A section with 4 divs = 5..... 3 + 5 = 8
<section>
<div>div1</div>
<div>div2
<div>div3</div>
</div>
<div>div4</div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<div class="hidden"></div>
<section>
On the other hand document.getElementsByTagName('*').length WILL count elements with display:none
This may only be one of the differences which I hadn't taken into account, but I'd say it's probably the main culprit as to the discrepancy.

display: run-in dropped in Chrome?

I have tried to use display: run-in in order to create a semantic and nice-looking metadata name-value list, liks this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Run-in description list test</title>
<style>
dt {
font-weight: bold;
display: run-in;
}
dt:after {
content: ": "
}
</style>
</head>
<body>
<dl>
<dt>Subject</dt>
<dd>A Question</dd>
<dt>From</dt>
<dd>Mr Smith</dd>
<dt>Time</dt>
<dd>2013-08-05</dd>
</dl>
</body>
</html>
The expected result is
Subject: A Question
From: Mr Smith
Time: 2013-08-05
You can watch it live. (Actually, the idea to use display: run-in was given to me by Ian Hickson, after I started nagging about the di element from XHTML 2.0. One alternative is to use float, but that comes with a number of difficulties.)
Until recently, this worked wonderfully in every modern browser except Firefox (that is, it worked perfectly in Internet Explorer, Google Chrome, Opera, and Safari (I think)). But very recently I discovered that it doesn't work in Google Chrome anymore.
Question: Has Google Chrome dropped support for display: run-in? Is there an alternative that works the same way?
I'm not aware of any change to Chrome's support of display:run-in but the setting has always seemed unloved.
Hixie has been consistently opposed to <di> and I kind of understand why. HTML is a semantic language and the semantics are fully defined by dl/dt/dd. The only practical problems are presentational, and that makes it a CSS problem, not an HTML one.
Unfortunately, then current state of CSS doesn't seem up to the job. For dl/dt/dd, and for many similar problems, we really need a mechanism for wrapping groups of elements in a pseudo element which could then perform the role of the <di>.
Obviously, there is no current setting that does what display:run-in is supposed to do. Having said that, in your specific test case, you could achieve the same effect with this CSS:
dt {
font-weight: bold;
display: inline;
}
dt:after {
content: ": ";
}
dd {
display: inline;
margin:0;
}
dd:after {
content:'\0A';
white-space:pre;
}
I'd like to offer a different, more explicit approach to the solution. One that can be extended to a more general case of missing display:run-in behavior.
I.e. I'm using h4->p flow-in transition to compose a nicely formatted list of item properties:
h4 {
font-weight: bold;
display: inline;
}
h4::after {
content: ": ";
}
h4 + p {
display: inline;
}
h4 + p::after {
content: '\0A';
display: block;
}
Here, I'm using "immediate sibling" (+) CSS selector to select p elements immediately preceded by h4 elements. If h4 is followed by any other element, it will be displayed following the normal flow.
An alternate selector ~ will select not one but all elements of the said type, which is not what usually expected from run-in behavior, and will also extend to all tags of the same type in current scope regardless of the other intermixed tags, which could break the layout completely.

How to only show certain parts with CSS for Print?

I have a page with lots of data, tables and content.
I want to make a print version that will only display very few selected things.
Instead of writing another page just for printing, I was reading about CSS's feature for "#media print".
First, what browsers support it? Since this is an internal feature, it's OK if only the latest browsers support it.
I was thinking of tagging a few DOM elements with a "printable" class, and basically apply "display:none" to everything except those elements with the "printable" class.
Is that doable?
How do I achieve this?
EDIT:
This is what I have so far:
<style type="text/css">
#media print {
* {display:none;}
.printable, .printable > * {display:block;}
}
</style>
But it hides everything. How do I make those "printable" elements visible?
EDIT:
Trying now the negative approach
<style type="text/css">
#media print {
body *:not(.printable *) {display:none;}
}
</style>
This looks good in theory, however it doesn't work. Maybe "not" doesn't support advanced css ...
Start here. But basically what you are thinking is the correct approach.
Thanks, Now my question is actually
becoming: How do I apply CSS to a
class AND ALL OF ITS DESCENDANT
ELEMENTS? So that I can apply
"display:block" to whatever is in the
"printable" zones.
If an element is set to display:none; all its children will be hidden as well. But in any case. If you want a style to apply to all children of something else, you do the following:
.printable * {
display: block;
}
That would apply the style to all children of the "printable" zone.
If you want to display some links etc. when in the browser, that you don't want to be printed. Furthermore you have some logos and letterhead info that only should go on the printed page.
This seems to work fine:
Example:
CSS:
#media print {
.noPrint {
display:none;
}
}
#media screen {
.onlyPrint {
display: none;
}
}
HTML:
<div class="noPrint" id="this_is_not_printed" >
<a href=links.html>
</div>
<div class="onlyPrint" id="this_is_only_seen_on_printer" >
<img scr=logo.png >
<img scr=letterhead.png >
</div>
A simple way:
<style>
.print-only{
display: none;
}
#media print {
.no-print {
display: none;
}
.print-only{
display: block;
}
}
</style>
I got here because I was curious about printing a chart generated by chart.js. I wanted to just print the chart directly from the page (with a button that does a 'window.print') without all of the other content of the page.
So, I got closer by using the technique from the answer here: Why can't I override display property applied via an asterisk? .
You have to apply the 'asterisk' to the 'body' element, not just by itself. So, using the example CSS that the OP (Nathan) added to the question, I changed it to this:
<style type="text/css">
#media print {
body * {display:none;}
.printable, .printable > * {
display: block !important;
}
}
</style>
Then adding that 'printable' class to the chart itself, as in
<canvas id="myChart" class="printable" width="400" height="400"></canvas>
Which removed all page elements on the printed output except the chart when the 'print' button is clicked (via this):
<script>
myChart.render();
document.getElementById("printChart").addEventListener("click",function(){
window.print();
});
</script>
So, perhaps this will help anyone that gets to this question via the googles.
Came across the same question recently and for me, this solution works just perfect:
#media print {
* {
visibility: hidden;
}
.printable {
visibility: visible;
position: absolute;
top: 0;
left: 0;
padding: 10mm;
}
.printable * {
visibility: visible;
}
}
Since visibility: hidden doesn't remove elements, as display: none does, it is possible to change it for desired elements separately.
Nearly all browsers support it. It might be advantageous to use the media attribute on the link tag.
Using display: none; in some of your rules would be an appropriate way to handle your situation.
I suggest to hide the element that you won't print:
HTML
<h1 class="no-print" >Welcome Just Screen</h1>
<div> I want print this section :)</div>
<div class="no-print">It's display only on screen</div>
CSS
#media print {
.no-print {
display: none;
}
}

Resources