Where Do the Lost Pixels Go in a Percent CSS Layout

Where do the lost pixels go in a percent CSS layout?

If, for example, you're using a % width, and the exact width should be 103.333px, then the browser must make a decision on how display that.

Different browsers make different decisions, read these links for more information:

  • http://ejohn.org/blog/sub-pixel-problems-in-css/
  • http://elasticss.com/determination-of-algorithms-used-for-percentage-based-rounding-divs-on-browsers-and-css-frameworks/

I particularly like this explanation from John Resig/David Baron of why this is even a problem:

I was talking this over with some
Mozilla developers and David Baron
explained the situation quite well:

We’re trying to meet a bunch of
constraints that can’t all be
satisfied at the same time
(the proof
is left as an exercise to the reader,
though I may have actually written it
out once in a Bugzilla comment):

  1. 4 adjacent objects of width/height 25% (for example) starting at one edge
    of a container should end exactly at
    the other edge; there should never be
    an extra pixel in the container and
    they should never be wrapped due to
    being a pixel to wide

  2. objects that are logically adjacent should always touch visually; there
    should never be a pixel gap or a pixel
    of overlap due to rounding error

  3. objects given the same width should occupy the same number of pixels

  4. object boundaries should always (visually) be aliased to a specific
    pixel boundary in the display (they
    should never be blurred)


The one [Mozilla] sacrifices is
typically (3), except for borders
where we sacrifice (1) by rounding the
widths to pixel boundaries much
earlier.

See this question for a JavaScript fix that forces consistency:

Evenly distributed height of child elements with CSS

Another relevant question:

Are the decimal places in a CSS width respected?

CSS percentage and pixel layout combined

Why not try this approach: http://jsfiddle.net/Er8uX/2/

#wrapper {
width: 1260px;
border: 1px solid #ddd;
overflow: hidden;
position: relative;
}
#column-left {
width: 245px;
position: absolute;
left: 0;
border: 1px solid #f0f;
}

#column-mid {
margin: 0 280px;
border: 1px solid #00f;
}

#column-right {
width: 245px;
border: 1px solid #f0f;
position: absolute;
height: 100%;
right: 0;
}

I think this is what you want, basically: fixed left and right column, main content according to wrapper width. I've used absolute positioning to keep them in place; on the right one I've used 100% height if you have a column with a background and want it to run all the way down, the left one has height according to content.

CSS Percentages And Pixels

% value in margin and padding is always % of the parent's width.

So say you have a <div> with margin-bottom: 25%;, inside another <div> which is 1000px wide, then the bottom margin of the <div> is 1000*25% = 250px.

.container {  width: 100px;  background: green;}
.child25,.child45,.child-none{ background: yellow;}
.child25 { margin-bottom: 25%;}
.child45 { margin-bottom: 45%;}
<div class="container">  <div class="child25">This one should have 25px margin bottom.</div>  <div class="child45">This one should have 45px margin bottom.</div>  <div class="child-none">This one has no margin</div></div>

Can a CSS pixel be a fraction?

Yes, you can specify fractional pixels. As this has been part of CSS since the very first version, it should be well supported by any browser that supports CSS at all.

Reference: CSS 2.1: 4.3.2 Lengths

"The format of a length value (denoted by <length> in this
specification) is a <number> (with or without a decimal point)
immediately followed by a unit identifier (e.g., px, em, etc.)."

When the elements are displayed on the screen, most browsers will naturally round the position to the nearest pixel when using 100% zoom level. On higher zoom levels you will notice that fractional pixel values are recognized.

CSS How to Properly use ems instead of pixels?

line-height: 1.4em;

Probably isn't what you want. The line-height will stay at the same computed height for the size of an ‘em’ on that element, even when you change the font-size on a descendant element.

line-height has a special case where it allows a unitless number:

line-height: 1.4;

Which makes each descendant line-height depend on its own font-size rather than the ancestor's.

Should I be defining my font-size [on a wrapper or on many element types]?

Well that rather depends on what you're trying to do. With relative font-sizes it is generally best to keep the number of declarations down to a minimum, because they nest: that is, with your blockquote { font-size: 1.5em; }, if you put a blockquote inside a blockquote you'd get a font-size of 1.5*1.5=2.25em compared to the body font size. Is that what you want? Maybe, maybe not.

where ELSE should I be using ems

Anywhere you want the size of an element to respond to the user's preferred font-size. One common example would be something like:

#maintext {
width: 60%;
min-width: 8em;
max-width: 40em;
}

to try to restrict text lines to a reasonable column width when doing liquid layout.

But if you are limiting yourself to a fixed-width layout it may not make sense to make element widths font-size-dependent.

CSS Calc() using two pixel amounts to get a percentage

You need to pass a % unit, than the desired integer values

div{  background:red;  height:24px;  width: calc(100% * (540 / 750));               /* 72% */}
<div></div>

safari rounding down on subpixel calculations

There isn't a whole lot you can do about how different browsers render subpixels, sadly. It'd be great if we could choose how the rounding should be handled through CSS, but nope.

Simply using pixels rather then percentages would solve the problem but that's obviously not what you want. I guess you could get around with static pixels if you change the values (possible to a percentage value) through media queries.

Whenever I find myself in a similar scenario I float the last child to the right. A few additional pixels between the last and second last elements don't usually hurt as much as a few additional pixels between the last element and its parent.

how do I know how many pixels are being used when I use 100% width for the body tag

You have to read the specs to find the answer to your question:

https://www.w3.org/TR/CSS22/visudet.html#x3 says about percentage widths:

<percentage>
Specifies a percentage width. The percentage is
calculated with respect to the width of the generated box's containing
block
.

About containing blocks:

https://www.w3.org/TR/CSS22/visudet.html#containing-block-details says:

The position and size of an element's box(es) are sometimes calculated
relative to a certain rectangle, called the containing block of the
element. The containing block of an element is defined as follows:

The containing block in which the root element lives is a rectangle
called the initial containing block. For continuous media, it has the
dimensions of the viewport and is anchored at the canvas origin;

(...)

The root element is <html> (https://www.w3.org/TR/html-markup/html.html).

The screen is considered a continuous media.

The relationship between viewport and canvas is simple:

https://www.w3.org/TR/CSS22/visuren.html#viewport
https://www.w3.org/TR/CSS22/intro.html#canvas

User agents for continuous media generally offer users a viewport (a
window or other viewing area on the screen
) through which users
consult a document. User agents may change the document's layout when
the viewport is resized (see the initial containing block).

When the viewport is smaller than the area of the canvas on which the
document is rendered, the user agent should offer a scrolling
mechanism.

So, trying to simplify this, the canvas size considers the content size even if it doesn't fit on the browser window.

The browser window contains the viewport (considered without menus, scrolling bar and status bar).


So, if <body> has 100% width, that means it would be the same width as the <html> element, which width is equal to the viewport's width.

You can easily find the viewport width by inspecting the css for <html> element on Chrome.



Related Topics



Leave a reply



Submit