Is it possible to print a HTML page with truly absolute positioned elements to paper? It seems all browsers are doing a big mess here. It is easy to define a body by absolute units (eg. cm) and place elements by position: absolute inside. However, every browser seem to try to make it impossible to print such a page. FF for example is adding print margins, even when printing to a PDF on linux despite 0-margin page settings. Chrome seems to shrink the page in every case.
So how to print something with absolute positioning, eg. paper form fields, markings etc.?
Have I overlooked something?
Sadly, the CSS3 Module: Paged Media allows all this to happen. This are the rules concerning pages which are too big:
3.3.3. Rendering page boxes that do not fit a page sheet
If a page box does not match the target page sheet dimensions, the user agent MAY choose (in order of preference) to:
Render the page box at the indicated size on a larger page sheet.
Rotate the page box 90° if this will make the page box fit the page sheet.
Scale the page box to fit the page sheet. (There is no requirement to maintain the aspect ratio of the page or of any elements on the page when scaling; however, preservation of the aspect ratio is preferred.) [done by Chrome]
Reformat the page contents, including 'spilling' onto other page sheets. [done by many other or older browsers]
Clip overflowed content (least preferred).
The user agent should consult the user before performing these operations.
3.3.4. Positioning the page box on the sheet
When the page box is smaller than the page size, the user agent should center the page box on the sheet since this will align double-sided pages and avoid accidental loss of information that is printed near the edge of the sheet.
And this is the rule which breaks all your positioned stuff:
3.7. Content outside the page box
[...] Also, when boxes are positioned absolutely, they MAY end up
in "inconvenient" locations. For example, images MAY be placed on the
edge of the page box. Similarly when boxes use fixed or relative
positioning, they MAY also end up outside of the page box.
A specification for the exact formatting of such elements lies outside
the scope of this document. However, we recommend that authors and
user agents observe the following general principles concerning
content outside the page box:
User agents SHOULD avoid generating a large number of empty page boxes to honor the positioning of elements (e.g., you don't want to
print 100 blank pages). Note, however, that generating a small number
of empty page boxes MAY be necessary to honor the 'left' and 'right'
values for 'page-break-before' and 'page-break-after'.
Authors SHOULD not position elements in inconvenient locations just to avoid rendering them. Instead:
To suppress box generation entirely, set the 'display' property to 'none'.
To make a box invisible, set the 'visibility' property.
User agents MAY handle boxes positioned outside the page box in several ways, including discarding them or creating page boxes for
them at the end of the document.
Have a look at the second paragraph of section 3.7: A specification for the exact formatting of such elements lies outside the scope of this document. Since there is no other document and no other guideline then the general principle following this paragraph, every browser can do whatever it want.
It's one of the flaws that are currently in this CSS3 module. However, I think those flaws cannot be removed by a CSS4 or revised CSS3 module, as the variety of possible stylesheets and resulting layouts is too huge too cover. Also note a little footnote given in CSS Print Profile:
‡ The printer MAY ignore positioned elements that are placed on the page before the position of the current element in the normal flow.
So it's basically not possible to create the same effect in every browser. As for the time being, the only possible way to achieve a portable document is to create a PDF with a third-party application or via a PDF printer and your most favorite browser. Every other way is bound to fail as long as either the W3C's recommendations aren't strict or the browser vendors implement whatever they want.
See also:
CSS3 Module: Paged Media (Working draft, last revision 2006)
CSS Print Profile (Working draft, last revision 2006)
Additional notes
If you have a bunch of position:absolute elements which need to be printed it's sometimes a good question whether an element actually needs to be positioned absolute, or if the same effect can be achieved in a slightly different or easier way. Also note that you should use display:none on each element that isn't truly needed for the printed media, such as ads, navigations, etc...
As you say, web browsers tend to do crazy things when printing. Print-oriented engines are often better.
WeasyPrint is an open-source engine that renders to PDF and supports absolute positioning as well as CSS 3 Paged Media to set the page margins:
#page { margin: 1cm /* or 0, if you want */ }
Make your container to have relative position. That's the only way to keep absolute positioned elements in the same place at every screen and paper. so if your main div (the div where all of your content is located) add following to your css:
#maindivname{position:relative;}
Should do the trick.
I have tested browser status for printing "position:absolute" elements with the following results:
IE 11: Fail. Doesn't matter what OS, 7,8,8.1.
IE 10: Pass. However, you cannot revert to 10 on 8.1 so folks with that are stuck.
Firefox up to 38.05 = Fail. Unknown if any version ever worked.
The good news is that it looks like the Blink/WebKit people did their homework instead of using poor code.
Chrome: Pass
Opera: Pass
Media Queries will do the trick -- check this link and previous question out, maybe it will help.
Suggestions for debugging print stylesheets?
Media Query transitioning px into inches/cm/whatever needed for printing requirements.
That border/margin you mentioned is probably your printer's printable area (the grip edge). Most printers need some type of edge to grab and feed the stock. That's why when one prints a full-bleed document (ink to the very edge), it's printed on stock larger than needed, then trimmed down.
set the margin with page setup is the first and primary solutions for printing the HTML page or a DIV .
After all not expected result will come then you need some digs on your HTML page.
Make a window without title bar or any custom bar using java script.And put all Original data into that window with a position:relative and also set the media type as print.
position:relative;
media:print;
Hope it will helpful.
Use in CSS this property:
body{
-webkit-print-color-adjust:exact;
}
This help positions absolutes and backgrounds in tables.
Related
I'm trying to make a window based application for web browsers. The number of windows is considerably high, so I'm storing them as HTML files (one per window) that I asynchronously retrieve from the server according to user interaction.
To add a window to the main page, I first add the link elements (CSS) of the downloaded document to its head section, and then I append the content of the body section to a certain div. When a window is closed, I just remove these elements.
This approach seems to be working nicely, but I can see that sometimes when I add a window, its elements are visible out of position with no style, and after a brief moment they are correctly painted.
I don't have a strong background in web programming, but I suspect this might be related to what it is called "browser reflow". Does it mean that it is taking too much time to repaint everything? Is it possible to just hide these "unstyled" elements until it is safe to show them?
Any guidance would be appreciated.
Some time away from the computer seems to have relaxed my mind. I was erroneously assuming that adding new link elements to the head section would load the CSS files immediately. Obviously, the browser needs to retrieve them from the server first. So, the DOM elements I'm adding don't show their style because the CSS files have not been downloaded yet. I think this is the right answer.
I'm mainly a back-end programmer but every now and then I need to put a human-friendly face over something, and end up becoming a web designer/dev for a day.
More than a few times my layout issues have been solved with wrapping everything in a div directly inside the <body> tags and applying some styling to that, mainly sticky footers or pushing content down to fill at least the height of the viewport. Because I use I use it infrequently, I tend to forget the intricacies of HTML/CSS, but I'm wondering should I always wrap all body content in a div as good practice?
On one hand:
It seems to be the most commonly suggested solution to stretching content all the way down (sidebars also seem to be a menace for this).
Even if I don't need it to start with, I may need it in future, and putting it there to start with means it is less likely to affect the rest of the page if I need to add one later.
But I feel like there's enough I don't know about web page rendering that overall it could be detrimental somehow. Is it semantic? Does it open up the potential for bigger problems with other parts of the page? I like clean code and I like scanning through my work and be able to tell at a glance what everything does and why it is there. Something just feels off to me about a div whose purpose is not immediately clear.
Not that you have to wrap body content with div. It just historically web was about content only. You can trace it even how names has changed over time.
Webpage - page in web. Page like a book page, just simple text. Text has flow layout. Styling is minimal (in terms of location). It is not important what is underneath when content is finished, just the rest of blank page.
And now your already mention term viewport. It is place for content and control elements. Modern web-page not a classic page anymore, it is application nowadays. But term web-page already in use. Try to calculate how much of page space takes text content (flow layout) and the rest(buttons, images, video, controls - block layout) for example on Facebook
Element div become universal element used to split content logically into separate blocks. Element div just a block with max available width of his parent and height of inner content. The visual presentation of div element can be widely changed using styling. There are a lot of new semantic elements in html5 those were emulated by div element mostly previously. Easy to guess what for such elements like header, footer, aside, nav...
Main idea of div is to split content logically and style it as you need.
Why do images defined in CSS (like backgrounds, lists marker, ...etc.) not behave in the same way in the browser as HTML images? For example, they can't be selected by the mouse, and you can't right click on them.
Images are generally used in CSS for one thing, backgrounds. Which means they aren't used for the same things HTML images are being used for (displaying the actual image as part of the content).
When an image is part of the content, it can be saved and copied etc, because it
is likely to be considered interesting by the reader. Backgrounds (or list-markers etc) however, are less likely (unless the reader is a developer) to interest the reader enough to want to copy them. Instead, the focus is on the actual content of the element (which the background was applied to).
I guess it is a question for browser vendors why they allow certain behavior only when dealing with <img> tag.
However, you can use dev tools/Firebug/whatever and you can download the image file.
I recently made a new WordPress theme for a local travel company and they are now getting reports that two elements in my design are not in the correct positions in Firefox (seems specific to version 3.6) and Chrome for Mac.
A page where both issues are visible: http://www.totemtravel.com/blog
Issues:
The white flag with the logo on it at the top of every page jumps
several inches to the right to cover the area code of the first
phone number.
The search button at the bottom of the blog categories widget in the sidebar jumps to the right, out of the widget, and off the page content wrapper.
I think the issue has to do with where those browser assume the item should be before the relative positioning, but I need a way to make these all look the same across all modern-ish browsers.
I wont paste the pages of source code behind the theme since it can be easily viewed with Firebug or the Chrome inspector, but please let me know if any additional info would help.
1: The img for the white flag must have left:0. Not all browsers default to left 0. Firefox for example, is defaulted to left:50%. Another problem is your trying to relatively position a td element for the title "Totem Travel", this is invalid and I would recommend using divs here instead of tables.
2: This is due to the native CSS styling differences of the browsers. That is why people use CSS Reset style sheets, to zero everything out so you know for sure the "default" css is the same. Here's an example: http://meyerweb.com/eric/tools/css/reset/. The effect this is having on your css now is that, the submit button is falling down to under the input as it doesn't have enough space - so when you are relatively positioning it it is off in the browsers.
3: Relatively/absolutely positioning everything isn't quite the best way to go about styling a website. You will find many inconsistencies like you are experiencing and there are better ways. I would recommend visiting some example themes on sites such as themeforest.com or elegantthemes.com and seeing how they do their CSS and HTML
Can you explain to me, at a very high level, what I would need to build an image carousel for the web, please. You can use data structures and general computer science terminology - but nothing language specific.
E.g:
Store all the images in an array or linked list
When the carousel is loaded, resize the displayed images as X% window size
When the next button is pressed, imageA moves to a hidden html element.
Et cetera.
I hope that makes sense.
Thanks.
You don't want anything language specific but you want to know about carousels on the web and you've tagged this with 'html' and 'css' so I'm going to assume that I can talk about HTML and CSS but I'll try to keep it high level.
If we ignore Flash, then you're left with HTML + CSS + Javascript. The common way to do this is to arrange the images or their thumbnails (don't resize via HTML - its doesn't look good and can increase your page load time) in HTML elements that are themselves contained in one or more layers of wrapping elements. So the whole set of images strung together might be wider than the viewing window. CSS is used to manage their exact layout and to keep them from overflowing the viewing window. When I say window, I just mean the portion of the page in which you want the carousel to appear. Then Javascript is used to change the CSS properties of one of the HTML elements that is wrapping the images, causing it to scroll or shift position.
With HTML5, you have more options, but the above is the way things have usually been done until now.
Finally, if you are going to actually implement this, there are a number of scripts available that will probably meet your needs, but if not I highly recommend using a Javascript framework like JQuery - it will make things much, much easier.
If you want to build it by yourself, one straightforward way would be to have a master div and all the images in it, lined up horizontally. Have the overflow set to hidden on the master div. Then use javascript and set scrollLeft as the user clicks the next, previous buttons.