17

The CSS3 GCPM spec defined the following

<style>
 .footnote { float: footnote }
</style>

<p>A sentence consists of words. <span class="footnote">Most often.</span>.

rendering as

A sentence consists of words. ¹

 ¹ Most often. [at the end of (each) page]

when printed (also works for the screen media type, but as long as it works for print I am happy).

Which is exactly what I want to do, no matter how complex, but as far as I am aware no modern browser implements this spec, nor the css-paging spec. Is there any way at all to achieve this effect if I am willing to use javascript. At the very least it would be possible to generate a pdf using some libraries, but if possible I would like to not lose the power of html (things like floats etc.).


And just in case you're wondering, notes are

A note is a string of text placed at the bottom of a page in a book or document or at the end of a chapter, volume or the whole text.

and footnotes are

... notes at the foot of the page while endnotes are collected under a separate heading at the end of a chapter, volume, or entire work.

For more information I refer to the wikipage on notes in typography.


One possible direction a solution can be sought is figuring out the height of a single page, in that case a disparity is noted between the expected height of 29.7cm and the trial&error height (at least on my system) of 26.1cm, this can be observed using the following code:

<style>
    @page{
        margin:0px;
        padding:0px;
    }
    html,body,*{
        margin:0px;
        padding:0px;
    }
    p{
        border:1px solid black;
        height:26.1cm;
    }
</style>

and a couple of empty <p>'s. I would consider an explanation of this disparity (thus allowing it's control) to be enough of a solution.

Maxolotl
  • 9
  • 3
David Mulder
  • 26,123
  • 9
  • 51
  • 114
  • 1
    Never knew it was specced as a new value for `float`. You'd think it would have been specced as `display: footnote/inline-footnote` instead, but I guess the spec writers decided otherwise for a reason... – BoltClock May 06 '14 at 15:35
  • @BoltClock: Well, it's just a working draft, so it's not really 'specced', but then again, a lot of the stuff we're using nowadays just consists of WD's. – David Mulder May 06 '14 at 21:41
  • Are footnotes generally printed on *each* page? Doesn't seem right to me, usually it's just the last page. – Wesley Murch May 06 '14 at 21:42
  • 2
    Ehm, ever read any academic literature? You don't want to browse to the end of a book just to see a footnote ;-) – David Mulder May 06 '14 at 21:43
  • 1
    I believe that does happen and it's called an appendix. However, you mean each page the footnote appears on, not *every* page. Correct? – Wesley Murch May 06 '14 at 21:44
  • @WesleyMurch: Indeed that's correct. – David Mulder May 06 '14 at 21:48
  • Definitely is a way to do it. If you're prepared to wait a bit I'll write the whole thing tomorrow. – ArtOfCode May 06 '14 at 21:49
  • @CaolanEvans: Care to give a spoiler how you want to approach it? O:) – David Mulder May 06 '14 at 21:50
  • It's not really what you want and kind of yucky, but you can use the `title` attribute to store the footnote, and have your print CSS display it inline with `element:after { content: attr(title); }`. It might work for your client. This means storing the footnote in every element that refers to it. Example: http://jsfiddle.net/3yr8s/ – Wesley Murch May 06 '14 at 21:50
  • @WesleyMurch: Yeah, quite aware of that solution, but that's when the printed media is secondary and screen media comes primary. If it turns out to be possible what I want is to have screen and print be true equals :P – David Mulder May 06 '14 at 21:53
  • @David I'll do it with jQuery. If you use a class on each paragraph that has a footnote and the footnote is directly after that paragraph, I can grab the footnotes with jQuery, move them all into an
      at the bottom and remove the originals.
    – ArtOfCode May 06 '14 at 21:57
  • @WesleyMurch: I won't deny that I was indeed quite surprised by the question. After all, I did refer to a specification which exactly describes to the letter what I want to do, so I am surprised that there is any uncertainty in that regard. – David Mulder May 06 '14 at 21:59
  • @CaolanEvans: Well, the problem is, how are you going to position that `
      ` then at the bottom of each printed page without nearly any support for the `css3-page` module in modern browsers?
    – David Mulder May 06 '14 at 21:59
  • @David: Shouldn't be too hard, especially using jQuery. Any chance you could find an image of what you want it to look like? – ArtOfCode May 06 '14 at 22:03
  • @CaolanEvans: Just standard footnotes (not endnotes)... : http://www.paperbackdesign.com/wp-content/uploads/2013/03/footnotes.jpg – David Mulder May 06 '14 at 22:06
  • You might want to link to the spec to avoid more uncertainty. You "referred" to a (rather obscure) spec, but don't assume we all know what you're after. – Wesley Murch May 06 '14 at 22:11
  • @David: Ok, that doesn't sound too hard. How will the 'pages' be formed? Are they just
    s with a specific class? Or something else?
    – ArtOfCode May 06 '14 at 22:12
  • Spec: http://www.w3.org/TR/css3-gcpm/ – ArtOfCode May 06 '14 at 22:13
  • @CaolanEvans Better to put in your post, comment thread is pretty long. – Wesley Murch May 06 '14 at 22:13
  • Will do when I post the solution. – ArtOfCode May 06 '14 at 22:15
  • @WesleyMurch: If you feel that's necessary do feel free to edit it in, personally I felt and feel that the tag I added (including description with a link to the spec) covered that base quite adequately for people new to the spec. – David Mulder May 06 '14 at 22:15
  • @CaolanEvans: Hit CTRL+P and take a look at the way pages are 'formed'... I have been spending the last 2 hours trying to figure out a way how to calculate the height of these pages so that I can calculate the dynamic content into them. Might be there's an entirely different solution, not sure, using the supported parts of the css3-page module and css2.1 page break related stuff you can get some basic stuff working, but I am no where close even at the moment. – David Mulder May 06 '14 at 22:17
  • @DavidMulder If you actually want help then make your question clear as possible. Personally I don't care too much if you find an answer at this point, Not a huge fan of your attitude and the way you talk down to people. – Wesley Murch May 06 '14 at 22:17
  • @David: Go and measure a sheet of A4 paper. Once you've got that you can work out the height from the text size (pixels, same as printed size) and margins. – ArtOfCode May 06 '14 at 22:20
  • @CaolanEvans: Yeah, I was hoping that would work, but for some reason I just can't wrap my head around when you make a box of `29.7cm` with no margins anywhere it will be bigger than 1 printed A4... might be some stupid mistake, really do hope so :) – David Mulder May 06 '14 at 22:22
  • @David: The user's system automatically adds margins in almost all cases. The best solution I can come up with for print is to take off the default margin size from your 29.7cm box. Screen media is different and will be much easier. – ArtOfCode May 06 '14 at 22:27
  • @CaolanEvans: Yeah, something like that indeed, if you would be able to refer me to the spec which describes where those margins are coming from I would very gladly accept that as the answer as the rest is quite doable (and then I would know how to predict those margins (or how the user could set them up correctly)). – David Mulder May 06 '14 at 22:29
  • @David: Spec shouldn't be needed. The margins are added at print - as you say, hit Ctrl-P and look at the default margin size. – ArtOfCode May 06 '14 at 22:30
  • @WesleyMurch: Could you suggest then how I should change my question to prevent users from answering/commenting without understanding the question? I am sincerely open to improvements in that area. I incorrectly assumed that using the term 'footnote' would be quite clear and in case it wouldn't I also referred to a specific spec. Now, I mean it that I am open to improvements, so how would you suggest I would word this question as such that I make it clear this is far from an easy problem? – David Mulder May 06 '14 at 22:30
  • @David: You may want to put instructions for users on the page that asks them to set their margins specifically. Improves usability. – ArtOfCode May 06 '14 at 22:34
  • @CaolanEvans: I am not talking about the margins around the box, but more so about the disperaty between `div{height:29.7cm;border:1px solid black;}` and the 'real' height of `div{height:26.1cm;}` (at least on my system), but wait, let me add some useful stuff to my question. – David Mulder May 06 '14 at 22:36
  • @David: Let me have a look at it properly tomorrow when I've got some decent computing resources with me. I'll get back to you with whatever I find. – ArtOfCode May 06 '14 at 22:42
  • The [currently commonly supported paging-related CSS attributes](https://developer.mozilla.org/en-US/docs/Web/CSS/Paged_Media) don't offer enough feature-wise to achieve what you want. Different printers (and different manufacturers) use different margin sizes ([see a sample Canon spec](http://usa.canon.com/app/images/service_ware/Printers/specifications/specifications.htm), namely print width) so it's likely these will also differ from one digital system to another. Your best bet seems to be generating a PDF via Javascript (or any other language if you pass your document to it over Ajax). – Etheryte May 09 '14 at 00:10

3 Answers3

4

I hope this is what you're looking for... It is loosely based off of this answer with some adjustments for the specific use case.

In my opinion the css counter is the fun part.

Full Screen Result <-- Try print preview on this one
Working Example

HTML:

<div id="pagewrapper1">
    <p>Zombies<sup>1</sup> reversus ab inferno, nam malum cerebro. De carne animata corpora quaeritis. Summus sit, morbo vel maleficia? De Apocalypsi undead dictum mauris brains<sup>2</sup>. Hi mortuis soulless creaturas, imo monstra adventus vultus comedat cerebella viventium. Qui offenderit rapto, terribilem incessu. The voodoo sacerdos suscitat mortuos comedere carnem. Search for solum oculi eorum defunctis cerebro. Nescio an Undead zombies. Sicut malus movie horror.<sup>3</sup>

    </p>
    <ol class="footnotes">
        <li>This is a foot note about Zombies.</li>
        <li>This is a foot note about Brains.</li>
        <li>This is a foot note about Horror.</li>
    </ol>
</div>
<div id="pagewrapper2">
    <p>Zombies<sup>4</sup> reversus ab inferno... and so on...

CSS:

*{
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
body, html {
    font-size: 1em;
    padding:0;
    margin:0;
    height:100%;
}
#pagewrapper1, #pagewrapper2 {
    position:relative;
    border: 1px solid #000;
    min-height:100%;
    -webkit-region-break-inside: avoid; /* added these bits to work out print issue */
    page-break-after: always;
    page-break-inside: avoid;
}
p {
    margin:20px;
}
sup {
    font-size: .6em;
}
ol.footnotes {
    list-style-type: none;
    margin-left: 3em;
    position: absolute;
    bottom:0;
}
ol.footnotes > li {
    counter-increment: customlistcounter;
}
ol.footnotes > li:before {
    content: counter(customlistcounter)" ";
    position:relative;
    top:-4px;
    font-size: .6em;
    width: 3em;
}

jQuery for position and counter:

$('#pagewrapper1, #pagewrapper2').css({
        'padding-bottom': $('.footnotes').height()
});

$('#pagewrapper2 ol.footnotes').css({
    'counter-reset': 'customlistcounter ' + $('#pagewrapper1 ol.footnotes li').size()
});

I've played with this a bit more, the print preview looks good in Firefox, Chrome, and IE10, but seems to have issues in Safari.

Community
  • 1
  • 1
apaul
  • 16,092
  • 8
  • 47
  • 82
  • `$(window).height()` !== `printed page height` – David Mulder May 13 '14 at 09:23
  • @DavidMulder See update... Try print preview on this: http://fiddle.jshell.net/2pfyF/19/show/light/ – apaul May 13 '14 at 16:26
  • 2
    @everyone who reads this: What this guy figured out is amazing. It's far from perfect, but finding even an imperfect solution to something that looked virtually impossible... that really does deserve your upvote. – David Mulder May 14 '14 at 11:05
4

First to answer your question about page height 27.9cm vs 26.1cm. This can be attributed to a few causes including at least the following:

  1. Your current printer may impose it's own non-printable margins caused by its printing mechanism.
  2. Your current browser adds its own margins for page headers and footers etc and may or may not suppress these depending on whether the user has chosen to suppress page headers and footers. Some browsers suppress, some retain the space and blank it out.

Neither of these two sources are available to the page author to interrogate.

But...

I have managed to develop a JQuery solution that will get footnotes to behave as they should.

  1. The embedded footnote is extracted, automatically counted and replaced by a superscript number. Ie:

    <div>My first sentence consists of words<span class="footnote">My first footnote.</span></div>
    

    becomes

    <div>My first sentence consists of words<sup>1</sup></div>
    

    with the text

    1 My first footnote.

    at the bottom of the current print-size "page".

  2. The document content is formatted into "pages" by using inserting the current page footnotes at the end of each print-sized "page". No special manually inserted <div> per page is needed.
  3. The solution does not split a text block, rather inserts the footnotes between existing text blocks (the solution supports scanning top level <div> or<p> elements).
  4. I've tested this on Safari, Firefox and Chrome (Mac only).

See fiddle for working example. The Javascript is a bit more complex than I would like (92 lines) and works by temporarily getting the browser to layout the page based on your instructed pageHeight and pageWidth before reverting to normal layout.

UPDATED:

I have produced an easier to follow version that merges the technique @apaul34208 used to achieve full page size independent of browser but retains the concepts of embedded footnote extraction and automatic paginating of the correct footnotes for each page to suit the printer. This now works for Safari, Chrome and Firefox (only tested on Mac) without change on both A4 and US Letter. Page breaks are confined to a <div> or <p> boundary. Thanks to Paul.

Updated working example is here: fiddle

or full screen for page preview here: result page only

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Mike
  • 3,722
  • 1
  • 28
  • 41
  • Just noticed that @apaul34208 has updated his solution so that it now works for print preview. The technique he used to achieve full page size independent of browser could also be included here - combining both approaches will give you a complete solution that extracts and numbers the embedded footnotes in a browser independent manner. – Mike May 13 '14 at 18:52
  • @apaul34208 and David - I have produced an updated solution that merges the technique Paul used to achieve full page size independent of browser but retains the concepts of embedded footnote extraction and automatic paginating of the correct footnotes for each page to suit the printer. This now works for Safari, Chrome and Firefox (only tested on Mac) without change on both A4 and US Letter. Page breaks are confined to a
    or

    boundary. Thanks to Paul.

    – Mike May 14 '14 at 04:02
  • How can I modify the updated solution if my pre-existing html page already has page breaks interspersed throughout? – reedog117 Sep 17 '15 at 20:27
1

I've been using PrinceXML to do exactly what you're talking about, the downside to it is that you have to install it on your computer with a shell script.

A colleague and I are working on a simple app that is basically an html text editor but can export the html as a PDF, with a table of contents, footnotes running heads and all.

Prince is the best we've come across so far. Let me know if this is not something that will work for you.

Circle B
  • 1,616
  • 3
  • 26
  • 45
  • Use a little vps server ? It is cheaper than a PrinceXml licence and you can do what you want... – Superdrac May 12 '14 at 17:12
  • That is a possibility, it just doesn't quite fit our needs being that we want to be totally offline. – Circle B May 12 '14 at 18:06
  • And what about a Virtual Machine ? It's a little bit loud just for this, but it's offline, cheap and easy to use. – Superdrac May 12 '14 at 18:45
  • @Superdrac: wkhtmltopdf looks amazing, but as far as I can see there would be no way for it to do what I am looking for, right? @ footnotes – David Mulder May 13 '14 at 00:20
  • http://wkhtmltopdf.org/usage/wkhtmltopdf.txt Look at the header & footer options part. – Superdrac May 13 '14 at 07:31