At my work, we're interested in tracking how often people print our web pages. (If a lot of people are doing it, we'll probably put more focus on making the print view nicer.)
Obviously if we put a "Print" button on the page, we can log when people click on that, but if users just use the "File" menu and choose "Print," we have no way of knowing if they did that.
Is there some clever way to use print-only CSS to cause the browser to issue a web request only when printing? My experiments seem to say no, but this seems like it should be possible.
Edit: A reasonable answer is offered below that works in FF; I'm offering a 100 point bounty for a solution that works on IE as well.
To build on responses from Tyson and Jao, you can try this approach to get around the issue of background images not being displayed/printed by default. instead of background image, use a bullet image...
Insert an element in your HTML source like:
<div id="print_tracker"><ul><li> </li></ul></div>
In your screen CSS:
#media screen {
#print_tracker { display: none; }
}
#media print {
#print_tracker { display: block; }
#print_tracker UL { list-style-image: url(/images/printtracker.gif); }
}
Then track the hits to that image. Hacky... i know
There is no accurate way to see when a page is being printed (and some may consider it privacy invasion). The suggestions for having a separate print CSS do work, but they can create a lot of false alarms - Print Preview, prefetching, and mirroring tools (even wget) would request the CSS file too, even if they are not going to print anything.
Maybe you could add a background image to the print.css file and link that background image to a file on your server which does the logging.
For example:
body {background-image:url(http://www.example.com/printlogger.aspx);}
I'm not sure if that works, just a thought
Update: I just tried the above. It does increment the counter if you do a print preview. However it doesn't when update the counter when printing a page (even with print background images turned off). Another option might be to use the CSS content property.
UPDATE II You can use the content property, works in Firefox, not in IE8. I haven't tested other browsers:
body
{
content:url(http://www.example.com/Count.aspx);
}
Insert an element in your HTML source like:
<div id="print_tracker"></div>
In your screen CSS:
#print_tracker { display: none }
(That's not really needed unless you have some default styles for divs that causes it to have a size.)
In your print CSS:
#print_css { display: block; height: 1px; background-image: url(clear.gif); }
Then just track the hits to that image.
You could check that your printing CSS has loaded (you can select CSS for a particular layout using media selectors) with javascript. The javascript could then log to the server this request.
For IE, explore use the print - related events of the Document body.
window.onbeforeprint - Fires just prior to the page being printed
window.onafterprint - Fires immediately after the page to be printed out has been loaded into printer queue/cache.
$(function() {
//Check to see if browser supports onbeforeprint (IE6, IE7 and IE8)
if (window.onbeforeprint !== undefined) {
window.onbeforeprint = TrackPrint;
}
}); function TrackPrint(){
$.get("http://www.example.com/Count.aspx");}
You could have a "print version" page and put some server-side logging on that page, however that could be a bit annoying for all parties involved.
What else you could do to is something like this:
On page load, use javascript to add a print-only stylesheet on the page which hides everything except a message saying "Please use the print link on this page".
Use javascript here so that users with JS disabled will still be able to print as normal. You won't be able to log them, but you won't piss them off either.
Put a link on the page which, when clicked, logs the event via AJAX, removes that stylesheet and then calls window.print()
Related
Bit of a strange occurrence with my web page, currently trying to resize the font of a facebook like button I have on my website.
Currently the HTML I'm targeting is:
<span id="u_0_3">2.1k people like this. Be the first of your friends.</span>
In the google chrome console adding either of the following will change the font
1.
#u_0_3 { font-size: 14px }
2.
span#u_0_3 { font-size: 14px }
but adding either of these lines of code to my web pages stylesheet has absolutely no effect. No clue how to proceed from here as it works in one stylesheet and not the other?
The reason the styles aren't updating when adding the code to your stylesheet as opposed to in the browser is because you're trying to a stylesheet on an iframe, which isn't possible. You can however add the styles using jQuery or something along those lines.
Try this...
$("iframe#idhere").contents().find("span#u_0_3").css('font-size', '14px');
Ensure that you have added CSS file reference in your HTML.
Also, clear browser cache and load the page.
I'm making a user stylesheet for the add-on 'stylish.'
It applies a semi-transparent dark box over the entire page for night-browsing.
I'm using:
html:before {
content:url()!important;
position:fixed!important;
width:100%!important;
height:100%!important;
top:0!important;
left:0!important;
background:rgba(2,3,3,.35)!important;
z-index:99999999999999999!important;
pointer-events:none!important;
}
to create the fixed, overlying div.
This works just fine, however, if there are any iframes in the site, it will apply this code into the iframes' HTML as well as you can see here:
because these social networking widgets rely on an IFRAME, its repeating the code into those pages, creating a double-overlaying of the semi transparent dark box i've made.
the desired look would be:
I've tried hack-ish things, like applying a much-higher z-index to iframes and specifying the background-color and background of * of anything in the iframes to 'white' and 'opaque' so that it 'floats' on top of the parent html page, but this doesn't work perfectly. i've also tried something like:
html:not(iframe):before{}
but this also doesn't work. I'm wondering if there is a way to do what I'm trying to do in a way that doesn't rely on 'html:before' to create the same effect, or if there's a way to do that but not have it repeat inside the html of iframes on a page.
I've exhausted my efforts trying to get this to work, so any help would be really appreciated. Thank you.
Unfortunately, there is no way using CSS to target only the contents of an iframe from within the source of the iframe, i.e. the page that contains the iframe element.
I'm assuming, since you're using Stylish, that your CSS is in a Firefox user stylesheet. If so, you may have to look at the source URLs of those iframes, create a #-moz-document rule targeting those URLs at their domains, and remove the html:before pseudo-element accordingly.
Something like this, which should go beneath what you already have:
#-moz-document domain(/* Facebook Like */),
domain(/* Tweet Button */),
domain(/* Google +1 */)
{
html:before
{
content: none !important;
}
}
The content: none declaration disables the pseudo-element, preventing it from being rendered.
Having to exclude specific domains in this manner means this method is extremely limited and not very versatile at all, but it's the best I can think of.
You may want to try a different route:
html {
box-shadow: inset 0 0 0 2000px rgba(2, 3, 3, .35) !important;
}
Demo
This way the webpage is still useable when the user's browser doesn't support pointer-events.
You may also want to checkout this question: CSS - max z-index value
To apply these styles to only the parent document's <html> element, and not to iframes, simply apply the box-shadow to document.documentElement with JS:
document.documentElement.style.boxShadow = "inset 0 0 0 2000px rgba(2, 3, 3, .35) !important";
Edit:
I don't know about the addon thing but you could give your HTML tag an ID and target it that way, although if you want this to apply to all pages then that's an issue
or maybe use html:first-child ? I honestly don't know what will happen, you can give it a try though
CSS doesn't allow you to style HTML inside an iframe. Since you're using an add-on, this is a non-standard implementation of CSS. Styles are not inherited by iframes, because an iframe is basically a new browser window. The add-on is adding the style to every HTML page in the browser window. There's no way for the browser to know that a page is inside an iframe (at least not in a way that's accessible via CSS).
I need to print report page that has couple of background images on it. But only these images are not printable. These images are logos actually for graph and hence very important in report.
I have another option that I can crop them and include in page as tag but this is last option. Hence before that I would like to know if there is any way to forcefully print these images? Can anybody help me out?
By default, a browser will ignore background css rules when printing a page, and you can't overcome this using css.
The user will need to change their browser settings.
Therefore, any image which you need to print should be rendered as an inline image rather than a css background. You can use css to display the inline image only for print though. Something like this.
HTML
<div class"graph-image graph-7">
<img src="graph-7.jpg" alt="Graph Description" />
</div>
CSS
.graph-7{background: url(../img/graphs/graph-7.jpg) no-repeat;}
.graph-image img{display: none;}
#media print{
.graph-image img{display:inline;}
}
Using this code, or similar code, means the image is used once in html and once in css.
The html version is hidden using css, and for print it displays as normal. This is a hack, but it will do what you want it to do. It will print the image.
Having said that, what you're doing is terribly bad practice. Nothing which conveys meaningful information to the user should be conveyed using css alone. Not only is it semantically incorrect, but it makes the graph less useful to users. An inline image is much better, and if you can, that's what you should use.
it is working in google chrome when you add !important attribute to background image make sure you add attribute first and try again, you can do it like tha
.class-name {
background: url('your-image.png') !important;
}
also you can use these useful printing roll and put it at the end of css file
#media print {
* {
-webkit-print-color-adjust: exact !important; /*Chrome, Safari */
color-adjust: exact !important; /*Firefox*/
}
}
Hopefully I can explain this well and hopefully I'm thinking the right way :)
My question is, If I have a print style sheet that has a couple of classes that "displays" a background image, is there a way to make the browser download the images at the point of printing or do you have to preload the images.
I have mixed results doing a print styled background image with FF and IE. IE actually seems to download the image at print? where as FF doesn't - (even though Firefox's Live HTTP headers addon says it does!).
My code is basically saying this:
#media=screen
.class
{
display: none;
}
#media=print
.class
{
display: list-item !important;
list-style-image:
}
Not a great solution, but you could provide a "Print" button which modifies the style when it's clicked prior to actually printing and changes it back afterwards?
For example (using jQuery):
<script type="text/javascript" language="javascript">
function doprint() {
$('.class').css('display','list-item').css('list-style-image','img.jpg');
window.print();
$('.class').css('display','none').css('list-style-image','');
}
</script>
<input type="button" onclick="doprint();" />
Obviously you can get around this by using the browser's Print function.
There's also the issue of the overhead you've saved by not preloading the image being well and truly used up by using jquery and script...
Based on my research, it seems that what I want to do is not possible, but in case something has changed, I wanted to check to see if anyone had come up with a way to do this.
I have a web app that generates reports for print based on user selections in the browser window. I have a custom header and footer that, when the report is printed from the browser, should be repeated on every printed page. It is not the browser header and footer I need, but rather the custom ones that I generate. Also, I don't think this is an issue of CSS and media types, but I am not a CSS expert. I have no issues getting the header and footer to print once, but I can't get them to print on each page. I have read that perhaps if I recreated my report pages using tables, and then used table head tags and CSS, that may work at least to get the header on each page. I have not had success with this yet, but I will try it again if it is the only option. A coworker suggested that I count lines in my php and manually put out the header and footer as required. I guess that is an option, but it just seems like there should be a way to do this that isn't so "brute force"!
The other caveat is that I have to support IE 6, so I suspect some of the CSS things I have tried are just not supported.
If anyone knows any way to do this, that would be great! If there isn't, I will have to rethink my approach.
Thanks in advance!
UPDATE (14 Dec 2011)
I made considerable progress with this issue, and using some of the info from the answers, I did produce reports that were usable, but never as nice or as professional as I wanted. Footers would tend to be not close enough to the bottom of the page, I had to do a lot of guess work and "brittle" calculations about how big text was going to be to decide on inserting page breaks, I could only support a restricted set of page formats, and any changes to the reports resulted in a cascade of code changes and yet more brittle calculations. There was always a scenario that broke some part of some report. We revisted the requirements, and are now generating reports as PDFs using TCPDF. The documentation is a bit opaque, and it takes some experimentation, but the results are far superior and now the reports appear as they should. I would say to anyone trying to do HTML reports from the browser, unless they are very simple, save yourself the frustration (as others told me here) and go with PDFs or something similar.
It can be done with tables -- and I know I'm going to risk a downvote by suggesting using tables for layout - but we are talking IE6 here which isn't known for its fantastic CSS support :-)
If you set a CSS style as follows:
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
Then when you create your HTML, render your body as:
<body>
<table>
<thead><tr><td>Your header goes here</td></tr></thead>
<tfoot><tr><td>Your footer goes here</td></tr></tfoot>
<tbody>
<tr><td>
Page body in here -- as long as it needs to be
</td></tr>
</tbody>
</table>
</body>
Yes it's not good (tables vs CSS), it's not ideal, but (importantly for you) it does work on IE6. I can't comment on Firefox as I've not tested it there, but it should do the job. This will also handle differnt sized pages, differing font sizes, etc. so it should "just work".
If you want the header and footer to appear on printed media only, then use the #media parameters to do the right thing:
#media print {
thead { display: table-header-group; }
tfoot { display: table-footer-group; }
}
#media screen {
thead { display: none; }
tfoot { display: none; }
}
Note
As of July 2015, this will still only work in Firefox and IE. Webkit-based browsers (cf. Chrome, Safari) have long standing bugs in their issue trackers about this if anyone feels strongly enough to vote on them:
The comments below this question tell me this is now resolved in Chrome. I haven't checked myself :-)
The original bugs against Chrome (for reference) are:
https://bugs.webkit.org/show_bug.cgi?id=17205
https://code.google.com/p/chromium/issues/detail?id=24826
https://code.google.com/p/chromium/issues/detail?id=99124
This will work in some browsers, not not all. I don't think there is an elegant cross-browser solution
Include the print footer/header you want in divs on the page (in this example div id='printableFooter')
In the screen css file put:
#printableFooter {display: none;}
In the print css file:
#printableFooter {display: block; position: fixed; bottom: 0;}
I would suggest to divide the page in table, and add the header part to first row and the footer part to the last row. The contents of the rows between the first and last rows can be changed dynamically so you will get the constant header and footer at desired pages.
----------
ROW1 HEADER
----------
ROW2
Insert dynamic contents here
ROW N-1
----------
ROW N Footer
try to generate a (rtf | pdf) document for printing