Div doesn't fill container 100% of the way when shrunk - html

Let's say hypothetically you have 5 divs. One is a container and the other four are children. You've set each one to be 25% of the container and you've given each one a background separate from the container background.
When you resize the browser your 4 divs at some point in time do not go all the way across, they might be a couple pixels off. Is there a way to stop this form happening? I'm assuming it's happening because it's 'snapping to each pixel' therefore leaving a small gap when resizing the browser.
#container {
width: 100%;
background: #000;
}
.children {
width: 25%;
float: left;
background: #fff;
}
JSFiddle: http://jsfiddle.net/AEvUL/
Screenshot of JSFiddle page in safari: http://cl.ly/image/1o1O2O401E0f

John Resig has a post about this issue that uses this exact case as its example.
http://ejohn.org/blog/sub-pixel-problems-in-css/
Take the following page for example. You have 4 floated divs, each
with a width of 25%, contained within a parent div of width 50px.
Here’s the question: How wide are each of the divs?
The problem lies in the fact that each div should be, approximately,
12.5px wide and since technology isn’t at a level where we can start rendering at the sub-pixel level we tend to have to round off the
number. The problem then becomes: Which way do you round the number?
Up, down, or a mixture of the two? I think the results will surprise
you, as they did me.
There are also several Stack Overflow questions on the subject:
safari rounding down on subpixel calculations
percent (%) width rendered differently in different browser (firefox, safari, opera, chrome)

Related

Style elements on different viewports even when simply resizing?

I'm admittedly not a fan of CSS and I hate even more responsive layouts but I'm creating an UI with Bootstrap (version 4, for what matters) in which I have some absolutely positioned elements that aren't exactly perfectly aligned as I want, be it in different native resolutions (monitor or VGA-defined) or when simply resizing the viewport (i.e.Ctrl++).
Since I began to create this UI I'm using vh and vw units for most elements (except those related to Bootstrap Grid, of course) thinking I wouldn't have such problem and this decision worked quite well for most of scenarios.
However, until now, I was using an old and very small monitor (1366x768) and recently I (finally) acquired a 21.5" monitor (FullHD, if this matters) and these values I've defined in my CSS rules, after exhaustive testings, are now slightly mispositioned, a bit to the left or to the top. For example:
This is a UUID I use for Unique User Identification in the Application and its positioning and text sizing was defined according to the rules below:
#user-identification {
bottom: 2.05vh;
font-size: 0.64vw;
height: 4vh;
left: 3.05vw;
width: 15vw;
}
As you may have noticed, the blueish background is in fact an image and the text is absolutely positioned on top of it, so I can reuse it for different use cases.
These rules created while developing in the small monitor where enough to center the text in the box of this background image. But now, in the bigger monitor I took this screenshot, you can see that the text is aligned to the left. It may be difficult to notice, I know, but this is a crop of the bigger picture which, unfortunately, I cannot show more :(
Well, I was about to start fixing all issues based on the big screen, for example, by changing the left to 3.4vw instead, but then I realized that if for any reason someone accessing the website is under the same situation I was before, the user experience would be prejudiced.
The first solution that came to me was to use Media Queries but I don't know the values I should be using to create the rules.
Worse! Regarding the viewport resizing, Firefox goes 10% by 10% while Chrome has a wider range (25%, 33%, 50% 67%...) and other browsers may have other values. And because I'm not a specialist I don't know the values I'm looking for to create the rules.
Can anyone help me?
Although it would be awesome, it's not my intention to fit the whole UI in the viewport of, for example, an iPhone 5 (the smallest I've found on Chrome Developer Tool with 568x320). I just don't want these small icons and texts absolutely positioned to be out of place.
[EDIT]
Describe the scenario in a Fiddle proved harder than I thought, that's why I tried to avoid it. But as asked, in this one I've positioned as best as I could and it looked good in the default preview area. But just by resizing it text already goes way out of positioning.
So I made this one, specifically for the embedded version. I believe it would be better as it's close to have the editor in one window and the preview in another (browser).
However, neither of them truly reflects what I really have. although the markup is compatible, both <img> and <span> inside the <figure>, I don't have these drastic changes when resizing the viewport. I have only small mispositionings on bottom and left.
I'm probably not extracting everything I should. I've got most of the Grid where this image (or the bigger, complete version of it) is located. .box is not relevant as it's just a few lines with linear and radial gradients and some box-shadow.
The whole UI is complex and I may have left something out of these Fiddles, but at least is something visual that shows positioning going wild when resizing (and definitely in different resolutions). My apologies for that.
This is the root of the problem to my understanding. There is an increase in height of the <span> element tied to the height of viewport, so the text container which is the <span> element is increased in height at the same time that the position of it via bottom and left are adjusted using viewport width/height. Removing the height setting of your elements in css, might solve the issues that you are having. Please leave a comment below, if this is not the solution to your question, and we can work together to the solution that fits this case. Thank you.
html, body {
font-size: 1rem;
height: 100%;
}
figure {
display: flex;
position: relative;
z-index: 1;
}
img {
height: 100%;
}
span {
bottom: 3.5vh;
color: #FFF;
font-size: 1.9vw;
/* height: 4vh; No need for this line right here. */
left: 1.1vw;
position: absolute;
text-shadow: 2px 2px 0px rgba( 0, 0, 0, 0.5 );
text-transform: uppercase;
width: 37vw;
z-index: 2;
}
<figure>
<img src="http://nick.mtvnimages.com/nick/promos-thumbs/videos/spongebob-squarepants/rainbow-meme-video/spongebob-rainbow-meme-video-16x9.jpg?quality=0.60" />
<span>f51bbe1e-7445-4545-bb84-15e614a119a2</span>
</figure>

What is the space on the right of images in chrome?

Consider the following example:
<!doctype html>
<html>
<head>
<style>
td {
padding: 0;
background: red;
}
img {
display: block;
}
</style>
</head>
<body
><table
><tr
><td
><img src="https://raw.githubusercontent.com/sinatra/sinatra/v1.4.7/lib/sinatra/images/500.png"
></td
></tr
></table
></body>
</html>
There's a red line in chrome on the right of the image. No such line in firefox. It doesn't seem like a space, because the html markup has no spaces between tags. It doesn't seem like a margin, because Developer tools doesn't report any margin.
What is this? How much space could it take?
I'm running chromium-47.0.2526.111 (64-bit), if anything.
UPD I made an example without spaces specifically to show that the red line is not caused by spaces.
Next, it was found the line appears when Zoom is, for instance, 110%. So, everything is supposedly clear now.
It is because of the way <td> elements are displayed. As you can see, they are displayed as:
display: table-cell;
This is because of how table-cell is ment to calculate pixels. Since 1 pixel is not equal to 1 pixel in CSS if you have DPI scaling enabled (or you zoom), it will start to behave weird.
You can either find another approach of your <td> inside <tr> or simply change the display to display: inline;
It's all because of how pixels sizes are calculated. I know it sounds weird, but 1px is not 1 physical pixel. Essentially what happens is your td's background changes according to the size of your image. When your image hits an odd number (because of zooming or DPI scaling), it will either round down or up. This is when the calculation happens and is wrong.
Sources: https://www.w3.org/TR/css3-values/#absolute-lengths
http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
There is no red line for me on initial load, however I can see red lines if I zoom in, which begs the question, is your browser set to zoomed in?
Look for the magnifying glass in the url bar of google chrome and make sure you're set to 100%
Causes when not zoomed
Since you have padding set to zero on your td element, that's fine, and the only thing that can make the same effect is to have the margin on the image (the margin on the child element sort of behaves like a padding on the parent element in this case). The margin could be set either by you, or by your browser's stylesheet (I don't see it on mine).
Set img {margin: 0} and it should be gone because you've covered both cases that could cause it.
Zooming problem
If you see it only when zooming, it's because of browser's sub-pixel rendering (when the pixel values become floats and the browser starts rounding or flooring them). And due to the extremely non-power-of-two dimensions of the image (313x161) it's highly likely to get that extra pixel line on various zoom levels when, say at 110% zoom, the calculated width of the td is 313.636 pixels, and the image 312.997 pixels, which become 313 and 312 when floored. That leaves us with the td element being one pixel wider than its child image, which is where the line (the red td background not being "covered" by the image) comes from.
img {width: 100%} fixes this (as Aziz already said in the comments)
This may help you:
td {
padding: 0;
background: none;
}
The correct answer is that for several years Chrome has handled images in tables defectively and no one can comprehend that this the actual problem. You have to take the images out of the table and put them in divs...

element with height 100% and overflow

What I basically need to achieve is to have an element (div, span, table, whatever) to consume 100% of its' parent height and show scrolls if it's content is taller.
The problem is, only chrome and IE in quirks work OK with height:100%; overflow: auto;. Firefox, Opera and IE in standards (any IE 7+, any "standards") just ignore the overflow and stretch the html element below the parent size. If I set fixed height it works, but I can't determine the available height before rendering, there are multiple possible values.
Simplified example (jsFiddle for this):
<body>
<div id="parent">
<table id='container'>
<tr>
<td>
<div id='element-in-question'>
<!--Content long enough to stretch the div-->
</div>
</td>
</tr>
<tr>
<td id='footer-cell'>
<div id='footer'>I'm footer<div>
</td>
</tr>
</table>
</div>
</body>
Css:
#parent { height:500px; width:500px; position:absolute; }
#container { height: 100%; width:100%; }
#element-in-question { height:100%; width:100%; overflow: auto; }
#footer-cell { height:30px;}
#footer { height: 30px; }
In real app all this stuff runs in an iframe, table is used to render header and footer and so on. Please do not suggest stop using tables, it's legacy application with 100+ places that need attention. CSS only solution would be ideal.
One more point: it should work in Chrome, IE10 standards mode. FF, Opera and Safari are not supported, IE9 and below handled differently.
Update: there are about ten footers with different heights, ideally the solution should not depend on fixed footer height.
Here you go:
Updated fiddle.
The problem is that height: 100%; is going to fill the next defined container. For whatever reason, tables aren't seen as a valid container for that purpose. So what we need to do is utilize some of the quirkiness of how tables are laid out.
position: absolute;
top:5px; left:5px;
right: 5px;
bottom: 40px;
overflow: auto;
border: 1px solid green;
background-color: #eee;
No need for relative positioning on the td. Don't ask me why, perhaps someone more knowledgable than I can chime in.
Regardless, with this we can force it to expand to fill a set amount of space, while still allowing:
The footer to be visible.
The padding to be present (even if it's not technically padding.)
This solution to work in a cross-browser environment.
Really hope this helps; if it doesn't, I'd be more than happy to give it another shot.
Update
You said that javascript isn't how you'd like to do it, but here's a short solution using jQuery which would actually solve the problem:
Updated Fiddle
$('td > div').each(function() {
var t = $(this);
var text = t.html();
t.hide();
t.height(t.parent().height());
t.show(text);
});
Why this works:
The div needs its parent to have a defined height before 100% height works, however that's not an option for you as you've already stated that this is all dynamic content. No problem. We just need the jQuery to push the calculated height to the div after the browser has already rendered it. Simple enough, right?
Well, not so fast. Divs aren't meant to be bounded by table cells, at least not ideally. We already have something that serves as a logical, separate container in the td, and the div doesn't much care what the td's height is if it has a boatload of content that's spilling over its borders already. And when we go to query the height of that td, no matter what it actually is, it's going to report that it's larger than the elements which it contains. So, if you look on the fiddle after commenting out the lines where we empty the div, you'll see that the td is erroneously reporting itself to be almost 900 pixels tall.
So what do we do?
Well, we take that content away from the div. Now it's just a husk, and it's going to be smaller than its container in every circumstance. That means that the td isn't going to lie about misreport its size when we query it, since it's confidently containing its children.
And once we get the truth from the TD, we tell the div that the size its parent has reported is the size that it needs to be, and give it back its content.
Voila. You've got a div that actually respects its parent now. If only real children were that easy.
The basic behavior of HTML tables
Here's a demo showing how small and extra-large content affects the width and height of a table. There are gray rulers alongside the tables, showing the intended dimensions of the tables. Standalone version of the demo.
Scrolling extra-large variable-size content in a table cell appears to work to some extent vertically, and not at all horizontally.
For height, there are 3 different outcomes in different browsers:
The overall height of the table is correct. This occurs with Chrome and Safari (Webkit browsers).
The content row occupies the intended height of the overall table, and the footer row adds additional height to the table, causing the table to be a little taller than intended. This occurs with Firefox and Opera, and IE7/8/9/10 in Standards mode (though in IE, the footer cell is even taller than the height of the footer content, which adds significant extra height to the table).
The entire height of the content row is displayed with no scrollbars, causing the table to be much taller than intended. This occurs with IE7/8/9/10 in Quirks mode.
For width, the outcome is comparable to #3 for all browsers (the full content width is always displayed with no scrollbars).
CSS compromise
The closest to a CSS solution that appears to be possible is setting a fixed height for #element-in-question (though letting it remain scrollable), and allowing the footer to vary in height. The overall size of the table would vary by however much the different footers vary in height. If the height difference of the footers is small, or if it's not critical that the overall table always has the same height, then this may be a reasonable compromise.
The CSS posted in the question would look something like the following (giving #element-in-question whatever height is determined to be optimal, when combined with the average or most-common footer height).
#parent { width:500px; position:absolute; }
#container { width:100%; }
#element-in-question { height:450px; width:100%; overflow: auto; }
#footer-cell { }
#footer { }
Here's an updated version of the demo posted in the question, using the changes listed above (tested in: IE7/8/9/10 Standards and Quirks mode, Firefox, Chrome, Safari, Opera). If there are difficulties running JSFiddle in older versions of IE, try this standalone version of the demo.
The website design appears to go beyond the bounds of what HTML tables are capable of. Unless some constraints can be imposed upon the design (such as the one described here), it looks like this will require JavaScript or jQuery.
I've got a workaround for this.tbody tag is added automatically in firefox and that cause the problem. Add height:100% to your td and height:90% to your tbody. The tbody tag never existed so you should add it with css.
table tbody{height:90%}
Live Demo

Zooming in Firefox Causes Page Layout to Break

I'm having trouble with this page: http://seatgeek.com/atlanta-hawks-tickets/. If you zoom out one level from the "normal" setting in Firefox, the page looks like this: . This happens with both versions 3.6 and 4.0 of FF. It does not happen with Webkit.
Clearly the problem lies in the elements within the "list_details" div. The problem can be fixed by decreasing the width of the "col1" or "col2" spans by 1px or by increasing the "vevent" li element by 1px, but these fixes cause the design to render improperly.
If you add up the width of "col1" and "col2", also taking into account their horizontal padding and border, the total width is 647px. But it only displays properly in Firefox (when zoomed out one level) when the "vevent" element, which contains the two, has a width of 648px. Why is that?
as this appears to have been bumped, but the original code is not available, I can say that the difference would have been caused by rounding (or sub pixels), the OP said the problem didn't happen when the div was 648px wide.. an even number can be halved, or split between 2 columns (OP also mentions 2 columns) quite easily no matter the zoom level
However the odd number647px will have been treated differently by Firefox
I cannot say exactly how as I can no longer see the widths of the two columns, but this blog post by John Resig, may explain better
Sub-Pixel Problems in CSS
one possible solution, or at least a helper, is to make sure the available width of the container is always divisible by the number of columns?
removing the margin-right from the following css fixed the zoom out issue
#left_container .search_details .list_details {
margin-right: 1px;
}
Add the margin-right:-1px to the following css. This can fix the zoom out issue.
.team-show .static-sidebar {
line-height: 22px;
margin-right: -1px;
position: relative;
width: 255px;
}
For future reference those looking for a general answer to why zooming can cause layout breaks
http://dev.jeffersonscher.com/resolution.html
Also use relative units to size things
https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units

images with width: 100% in table cells don't scale right in IE

I have a 3-column table which contains images. All td's have width="33%", and the images contained have CSS width:100%. In FF and Opera, the images scale like I want them to, i.e. fill the entire width of the cell, maintaining their aspect ratio. However, in IE7, they behave quite differently: I think the pic with the largest width stretches the entire column, and the smaller ones are stretched up to the new available width.
The page in question is: http://mybgagent.com/print.php?offers_id=4515
(I know the site is a mess, I didn't code it)
Any advice on what to do? Setting css position:absolute makes images scale correctly in IE, but breaks scaling in Opera and FF, as well as positioning in all browsers.
I ran into this issue a lot with IE7 "compatibility" mode. the easy fix was to not only put
width: 100%;
in my css, but also
width: 100%;
float: left;
cleared that nasty hiccup right up.
Sounds like you have a solution for each browser but no way to target it, well here comes the CSS Browser Selector to help you with that! Just plug in this jQuery to your site (in the <head> section), then write separate rules for IE and the real browsers and append .ie before your IE selectors :)
Works great, I use it all the time!
Example:
myTd
{
background: #f00; /*whatever your rules are*/
}
.ie .myTdv
{
position: absolute;
}
And that's it!
Try setting the style of the parent cell to position:relative.