views:

1978

answers:

9

I want to resize the font of a SPAN element's style until it the SPAN's text is 7.5 inches wide when printed out on paper, but JavaScript only reports the SPAN's clientWidth property in pixels.

<span id="test">123456</span>

And then:

#test
{
  font-size:1.2in; /* adjust this for yourself until printout measures 7.5in wide */
}

And then:

console.log(document.getElementById('test').clientWidth);

I've determined experimentally on one machine that it uses approximately 90 DPI as a conversion factor, because the above code logs approximately 675, at least under Firefox 3.

This number is not necessarily the same under different browser, printer, screen, etc. configurations.

So, how do I find the DPI the browser is using? What can I call to get back "90" on my system?

+3  A: 

I've determined experimentally on one machine that it uses approximately 90 DPI as a conversion factor, because the above code logs approximately 675, at least under Firefox 3.

1) Is this the same on every machine/browser?

Definitely NOT. Every screen resolution / printer / print settings combo is gonna be a little different. There's really on way to know what the print size will be unless you're using em's instead of pixels.

Joel Coehoorn
Thanks for the confirmation. How do ems help? JavaScript reports clientWidth in pixels...is there some property it will report in ems?
Kev
ems depend on the font metrics, which AFAIK javascript has no access to.
Orion Edwards
+1  A: 

The web is not a good medium for printed materials.

Kolten
Perhaps, but the browser has this number somewhere...so it would be handy to be able to use it without having to fire up a PDF client just to print out something as simple as "a sign with big text."
Kev
+2  A: 
  1. No
  2. You don't

This is actually further complicated by the screen resolution settings as well.

Good luck.

Chris Lively
And yet, the browser has a number that it uses. Where does it hide it?
Kev
The BROWSER has it? No, the Window Manager has it. The browser may or may not have access to it, and even if it does, it's not necessarily exposed to scripting.
R. Bemrose
A: 

If you are generating content that is meant to look a specific way, you may want to look into a format that is meant to be printed, like PDF. HTML/CSS is meant to be adaptable to different configurations of screen size, resolution, color-depth, etc. It is not meant for saying a box should be exactly 7.5 inches wide.

pkaeding
If CSS wasn't meant for printing, "@media print" should not be part of the spec.
Kev
+1  A: 

As made clear by the other answers, printing from the web is tricky business. It's unpredictable and sadly not all browsers and configuration react the same.

I would point you in this direction however:

You can attach a CSS to your document that is targeted specifically for printing like so

<link rel="stylesheet" type="text/css" href="print.css" media="print" />

That way you can format the printed output of your page in a separate style sheet and keep your regular stylesheet for displaying on screen. I've done this before with decent results -- although it required quite a bit of tweaking to ensure that the printed document comes out the way you want it.

An interesting article on the subject of printing from the web:

A List Apart - Going To Print

Some info from the W3C about CSS print profile:

W3C - CSS Print Profile

neonski
The problem is that the person who submitted this question wants to dynamically change the font size so that when the width changes, the font changes with it.It does make me wonder what setting the font size to 100% will do with that width, though...
R. Bemrose
A: 

Have you tried

@media print { #test { width: 7in; }}
JacquesB
Yes, which correctly makes the SPAN itself that big, but the text does not automatically scale to fill it. And to scale the text, AFAICT, I need the DPI the browser is using for printing.
Kev
+1  A: 

I think this does what you want. But I agree with the other posters, HTML isn't really suited for this sort of thing. Anyway, hope you find this useful.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
#container {width: 7in; border: solid 1px red;}
#span {display: table-cell; width: 1px; border: solid 1px blue; font-size: 12px;}
</style>
<script language="javascript" type="text/javascript">
function resizeText() {
  var container = document.getElementById("container");
    var span = document.getElementById("span");

    var containerWidth = container.clientWidth;
  var spanWidth = span.clientWidth; 
    var nAttempts = 900;
    var i=1;
    var font_size = 12;

    while ( spanWidth < containerWidth && i < nAttempts ) {
      span.style.fontSize = font_size+"px";

     spanWidth = span.clientWidth;

     font_size++;
      i++;
    }     
}
</script>
</head>

<body>
<div id="container">
<span id="span">test</span>
</div>
<a href="javascript:resizeText();">resize text</a>
</body>
</html>
Bill
I'll have to test this out, but doesn't it assume that the screen resolution and print resolution are equal?
Kev
Not sure about that. I tested this in Firefox 3 and besides appearing to work in the viewport of the browser, if you do a File -> Print Preview, it also appears to work. But I didn't actually try printing it. So I'll be curious to see what you find out.
Bill
I'm not exactly sure what you think this is doing, but it isn't solving the problem.
Chris Lively
IE 7: the last letter fell off the print wagon.FF 3: it printed at about 5 inches.Chrome: a little closer than the others
Chris Lively
He asked for a way to resize a span element with text in it to a specified width in inches. That's exactly what my example does, at least in FF3 on Windows XP. Sure it's a hack but it works. Or am I missing something?
Bill
And I just printed out the example page and measured it - it really does print out the text "test" to 7 inches after you click on the "resize text" link.
Bill
In FF3. It doesn't work anywhere else...
Chris Lively
+3  A: 

To summarize:

This is not a problem you can solve using HTML. Apart from the CSS2 print properties, there is no defined or expected way for browsers to print things.

Firstly, A pixel (in CSS) is not neccessarily the same size as a pixel (on your screen), so the fact that a certain value works for you doesn't mean it will translate to other setups.

Secondly, users can change the text size using features like page zoom, etc.

Thirdly, because there are is no defined way of how to lay out web pages for print purposes, each browser does it differently. Just print preview something in firefox vs IE and see the difference.

Fourthly, printing brings in a whole slew of other variables, such as the DPI of the printer, the paper size. Additionally, most printer drivers support user-scaling of the output set in the print dialog which the browser never sees.

Finally, most likely because printing is not a goal of HTML, the 'print engine' of the web browser is (in all browsers I've seen anyway) disconnected from the rest of it. There is no way for your javascript to 'talk' to the print engine, or vice versa, so the "DPI number the browser is using for print previews" is not exposed in any way.

I'd recommend a PDF file.

Orion Edwards
A: 

This is a merged answer of what I've learned from the posts of Orion Edwards (especially the link to webkit.org) and Bill.

It seems the answer is actually always 96 DPI, although you're free to run the following (admittedly sloppy) code and I would love to hear if you get a different answer:

var bob = document.body.appendChild(document.createElement('div'));
bob.innerHTML = "<div id='jake' style='width:1in'>j</div>";
alert(document.getElementById('jake').clientWidth);

As the webkit.org article says, this number is fairly standard, and isn't affected by your printer or platform, because those use a different DPI.

Even if it isn't, using that above code you could find out the answer you need. Then you can use the DPI in your JavaScript, limiting the clientWidth like Bill did, combined with CSS that uses inches, to have something that prints out correctly so long as the user doesn't do any funky scaling like Orion Edwards mentioned--or at least, after that point, it's up to the user, who may be wanting to do something beyond what the programmer had in mind, like printing out on 11x17 paper something that the programmer designed to fit into 8.5x11, but still, it will "work right" for what the user wants even then.

Kev