I'm trying to make a basic A4 document in HTML using mm CSS sizing. The document is sized perfectly - it prints fine on A4, covering virtually the full page, leaving a nice 3mm margin around it. I'm using a table for the layout, as the original document (that i'm re-creating in HTML) was created in Excel, and therefore has a table structure.
As I need the table to have an exact 3mm margin, i'm setting the width and height in mm, and using absolute positioning (3mm top and left). I had originally created the table-like layout using divs - but making the lines overlap perfectly using this is extremely fiddly - you can't really do it properly, as you're working with a mixture of millimetres and pixels, hence my choice for using a table.
The table displays perfectly, all rows uniformly fill the document. Some of the rows need to be split, so I chose to use floated divs within the s, within the s.
Despite resetting the CSS, and setting the <tr>s padding to 0, and the <td>s padding to 0, and giving the table border-collapse: collapse; and border-spacing: 0;, there's an annoying little margin between the div, that even Chrome can't explain why it's there:
https://www.dropbox.com/s/qt1n54m9fxxl6f2/job_sheet_template.html
You may need to open the image link, and zoom in, to see the green highlighted space below the divs (which is apparently the <td>s padding). In the bottom, right hand corner, you can see that the padding isnt set?
Why is this here?
Your image shows that border collapse isn't being applied. Try using:
table {
border-collapse: collapse !important;
}
I've fixed the problem -
The padding isn't set, but somehow setting the divs height to 100% doesn't work - I've now set it to 5.4mm which fits perfectly.
for html
html
{
font-size:0;
}
Related
I have a page with a container div, this container div has two columns, both inline-blocks. One column (left Hand side (LHS)) is the ticbox selection for a shopping catalogue, the right column is the output of the chosen selection.
The issue I have is that each is assigned a width based on percentage of the parent width, the left - fixed column is 20% width, the right, output column is 79% width (I tend to allow 1% for variability) .
BUT: the left column needs a minimum width - defined in px as 155px;
The right hand side (RHS) column is filled with inline-blocks for each product displayed by the catalogue search. These blocks are fixed width (140px)
MY ISSUE:
When the page loads on my screen it's fine, but when:
LHS:
min-width:155px < width:20%
(the browser window is resized)
The whole of the right hand side drops below the content of the left hand side (as the width for it is less than the required 79%.
Some simple example:
Please note there is no borders or paddings to be considered when measuring widths.
HTML:
<div id="container">
<div class="leftsideMenu">Menu column.</div>
<div class="rightsideShop">Shop Contents</div>
</div>
CSS:
#container{
width:80% /* of screen */
min-width:555px; /*should leave 400px for shop contents */
}
.leftsideMenu {
display:inline-block;
width:20%;
min-width:155px;
vertical-align:top;
}
.rightsideShop{
display:inline-block;
width:79%;
max-width:calc(100% - 156px) !important; /* fix attempt - doesn't appear to work */
vertical-align:top;
}
[Some] ATTEMPTED FIXES (not in order of attempt):
1) Calc to make the max-width always less than 100%-155, doesn't appear to work
2) Floats and margins : this does work but presents the problem of layout that the client doesn't want shoes underneath the LHS column and float height = 100% parent is another issue,
3) I have also tried to use https://stackoverflow.com/a/6350781/3536236 answer to a similar question - with the approach of having the RHS relative and using a forced LHS margin but this doesn't work as the solution linked here didn't work for me in this situation.
4) I think flex-box style working is probably a best way forward but I do not know enough about it, and to be brutally honest, I was hoping to avoid a massive reworking of the page CSS. (I had originally expected this issue to be 30minutes!).
5) Setting no width (just max-width) for RHS - to auto defined width, this auto defines to 100% and goes underneath the left hand side column.
I think the answer is pretty simple but I can't see it :(.
To explain parts for the points above, the LHS was originally a float and that worked fine but the client wanted no products appearing underneath the menu in the LHS column, so I thought - ah simple, make it an inline Block....
Any help as to keeping the right hand side giving the left hand side the space it needs, even upon screen resizing?
............
OH FOR FFFFFFFF SAKE -- I have just written this all out, and while I've been writing this have been trying different ideas as they've occured and it's finally worked:
Now after all this effort for writing this out I want to post it anyway, but the Solution is below!!!
OH FOR FFFFFFFF SAKE -- I have just written this all out, and while I've been writing this have been trying different ideas as they've occured and it's finally worked:
For some reason my calc works with:
max-width:calc(100% - 160px); Giving a spare space of 5px .
Any ideas why this is so, as I say, within the container div standard widths are percentages and there is some padding in the product container (inline-blocks) inside the RHS, but this really shouldn't have influenced having to add more "padding" space in the calc method.
Anyway, it works now. I'm happy. Maybe this will help someone?
With inline-block you will have some whitespace taking up some space in your layout.
Two inline-block divs with a width of 400px in a container div of 800px won't always render next to each other.
You can fix this by making sure the closing tag of an element is directly next to the opening tag of the next element in the HTML (e.g. </div><div>, no newlines or spaces).
A better option is to apply font-size: 0 to the containing element and then reset the font-size to e.g. 1rem for the inline-block elements.
This simple table with one absolutely-positioned column renders differently in Firefox (and IE) than in Chrome (and other Webkit-based browsers):
http://jsfiddle.net/WZ6x8/
<div>
<table>
<tr>
<th class="absolute"> </th>
<th> </th>
</tr>
</table>
</div>
* {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
table-layout:fixed;
}
th {
border: 1px solid black;
width: 100px;
}
.absolute {
left: 0;
position: absolute;
}
div {
margin-left: 100px;
}
Why is there a difference? Which browser is wrong (according to the standard)? How can this be fixed to work on all browsers, without removing the line border-collapse: collapse?
Edit: as noted by #urzeit, "If you specify top: 0; the output in firefox is the same as in chrome." However, there are two issues: first, with multiple rows, top: 0; collapses them all into one; second, the right edge of the absolutely-positioned column extends one pixel too far. You can see both issues at http://jsfiddle.net/WZ6x8/3.
This is caused by rounding issues which are often inconsistent across browsers, and are probably the same ones that plague things like background offsets, percentage calculations and so on.
In a nutshell, the reason why rounding issues come into play is found in section 17.6.2 which, as you may have guessed, describes the collapsing border model:
Borders are centered on the grid lines between the cells. User agents must find a consistent rule for rounding off in the case of an odd number of discrete units (screen pixels, printer dots).
And:
The top border width of the table is computed by examining all cells who collapse their top borders with the top border of the table. The top border width of the table is equal to half of the maximum collapsed top border. The bottom border width is computed by examining all cells whose bottom borders collapse with the bottom of the table. The bottom border width is equal to half of the maximum collapsed bottom border.
Since the border width is 1 pixel, which is an odd number, rounding issues occur when attempting to halve that value. So the question of which browser is wrong — or if any of them are — is debatable.
Unfortunately, because this is a rounding issue, it's not possible to work around this using pure CSS unless through inconceivably elaborate hackery, and very difficult to do so using a script as browsers tend to be inconsistent when reporting decimal/fractional offset values as well (in particular, Firefox, IE and Chrome all report wildly different values for offsetTop of your table-cell and its next sibling).
While I can't offer a solution to your problem, hopefully at least I've helped you understand why browsers are behaving the way they do.
Here's the nitty gritty if you're interested in why the issue ultimately lies in the way the collapsing border model is defined.
Section 9.7 states that if an element is absolutely positioned, then its display is set to block, even if it would otherwise be a table-cell. In all browsers, the computed display for that th is in fact block, so no problem there.
As you've correctly pointed out, the containing block of your table cell is the initial containing block. This removes it from its usual containing block which would otherwise be the table. Section 10.6.4 does add that that if your cell does not have any specified height, top or bottom offsets, i.e. they are all auto, then it should remain in its static vertical position and measurements made accordingly. (Likewise the horizontal position is accounted for in section 10.3.7, however since you've given it left: 0 and width: 100px, it gets shifted to the left edge and its width is as specified, excluding the borders.)
But what is this static vertical position? Because it would ordinarily be display: table-cell if it wasn't absolutely-positioned, the static position, and its corresponding measurements, is determined by its position in the table.
Your given table layout is covered by the following subsections of section 17:
17.5 Visual layout of table contents
17.5.2.1 Fixed table layout
17.6.2 The collapsing border model
Section 17 contains elaborate descriptions on how tables, captions, table-rows and table-cells should be laid out. A lot of it is based on HTML, and certain sections are left vague and/or undefined for various reasons. Fixed table layout is pretty well-defined though, and in this case it is not even relevant.
Section 17.5 says this near the bottom:
The edges of the rows, columns, row groups and column groups in the collapsing borders model coincide with the hypothetical grid lines on which the borders of the cells are centered. (And thus, in this model, the rows together exactly cover the table, leaving no gaps; ditto for the columns.)
And:
Note. Positioning and floating of table cells can cause them not to be table cells anymore, according to the rules in section 9.7. When floating is used, the rules on anonymous table objects may cause an anonymous cell object to be created as well.
Which, of course, has been explained just above.
But if an absolutely-positioned table cell is no longer a cell, what happens?
A "missing cell" is a cell in the row/column grid that is not occupied by an element or pseudo-element. Missing cells are rendered as if an anonymous table-cell box occupied their position in the grid.
So while the actual th box is absolutely positioned, it leaves an anonymous "ghost" cell in its place in order for the table to be rendered properly. This anonymous table-cell is empty and does not inherit the styles from the actual table-cell, so it has no intrinsic width.
However, because the actual table-cell's vertical position is static, it is still affected by how the table is rendered, which brings us to section 17.6.2 on the collapsing border model.
multiple rows - Try this css..
<style>
.absolute {
left: 0;
margin-top: -1px;
border-right:0px;
position: absolute;
}
#media screen and (-webkit-min-device-pixel-ratio:0)
{
.absolute {
margin-top: 0px;
}
}
</style>
Chrome And Firefox Demo Screenshot.
The reason this is happening is because you've specified the entry as absolute, meaning firefox's browser style where it sets the "top" css property to 1px is being used. If you want to avoid this you might be able to use a css reset file which blows away browser-specific default formatting.
As for your issue with setting top:0 resulting in the cells collapsing into each other, that is the correct behavior. Absolute renders in the space of the closest positioned CSS element. Think of it as if the element is no longer in its usual place in the DOM. If the two cells specified as absolute have the same closest positioned parent element (in this case the body) then they would both render relative to the same place with each having the top:0 property which means they would overlap.
I don't think either is wrong, you're just running into the (common) issue of browser styles.
In short ,
There are two problem to me in this problem
a) The first problem is overlapping of left <th> with right <th>
The correct browser is one which overlapp the <th> because
you are firstly giving the outer div margin-right:100px;
the <th> with aboslute property should fit this area, but the extra border of 1px increase the width by 2px(left border + right border) .Hence the overlap is correct
b) The second problem is of top margin for the left element
It can be removed by adding
th{
top:0px;
}
This is because of browser effect to html page
I recently designed a website (http://willryan.us/typefun01), mainly using Chrome while coding to test. I recently noticed that there are some weird things happening at the end of certain sections, (the gap after History, the overlap of Styles onto Anatomy).
I have a css reset in my stylesheet (not sure if that has anything to do with this), and I can't figure out what's causing this, and how to get the site to look like how it does when viewed in Chrome
The gap after History is due to:
#historyWide {
margin: 250px 80px 75px;
}
It could be remedied with:
div#content > div {
overflow: hidden; /* or auto */
}
You could also move the large top and bottom margins of elements inside the child divs of #content to padding on the child divs themselves. Anything will work as long as it's all contained by those child divs.
You're simply seeing the different ways that browsers handle imperfect layout.
If you want to avoid the gap after History you would want to use a padding in historyWide instead of a margin; the margin pulls aways elements while padding makes them bigger
On anatomy what's happening is that you're using the property "top" to modify #styles, this will move the element but the parent will reserve only the original space for the element. You will be better off working with margins and padding than with "top" if you have to keep a relation between the elements.
Lastly, i woulnt position elements with margins like you did with #stylesMono. I think you could better work with paragraphs to keep keep the vertical position and, from there, working with floats, margin and padding in the scope of the "p".
I have no control over the html in this project, so I need a css only solution unfortunately. The html is horrible, and it this wouldn't even be a problem if I could edit it. I have made a fiddle of where I am at at the moment.
I have a fixed width div, with a fixed width table inside it. They are the same width (500px in example) The table has an unset number of rows, generated in asp. I have floated the rows left so they appear in line (I know this is awful, but it was all I could do without editing the html) Each td is 100px. The heights and background colours added in the css are just to make it a bit clearer, they can be changed to whatever.
What I want to achieve is to get the td to start at the right hand side instead of the left. I have tried floating right instead of left, but this makes the links appear in reverse order which is undesirable.
The only solution I can come up with is to change the table width in css and float it to the right, which would be fine if the number of rows was a constant, but there could be some added to it or removed, which would leave it looking incorrect again.
fiddle link
I think you were correct with your thought to change the table width in css and float it to the right. I think I get what you want if I set the table width to 0px (it will expand to contain the tr's) in CSS, and float the table to the right.
Edit: nevermind. I was using Chrome and it worked there, but not in IE
Edit2: width:auto seems to make it work in IE, Chrome, and Firefox
I you have fixed width tds in your table, they should add up to 500px. In this case they add up to 400px. So you have to prepend one tr with auto width to your table.
Update: Hmm, this does not work since you have floating trs instead of tds
I've got an example mht file here that will help demonstrate my issue; if you are using FF then this addon will help you view the mht file. You will prob need to download the file and view it locally since github doesn't provide the right mime type for the file.
Basically my issue is this that I have a div which is 32px in height surrounding another div which is 29px in height, and I have no idea why the former is 32px tall.. It should be 29px tall afaict.. I don't want to set height:29px tho because if you resize the window so that the nav items take two lines then the height shouldn't be 29px for either div.
So what is wrong here?
make the following changes-
(-) to make your ul and wrapper div bottoms to align change class #navigationSecondary ul.base
to have a display:table; instead of display:inline-block;
(-) to remove the 3px of blue at the bottom change class #navigationSecondary to have padding:0; as sugested by Marcel.
the use of display: inline-block; on the ul.base is the cause.
when you use that it formats an element like it were inline (it only formats the actual content of the element like a block), so ul.base will have the usual 2-3px top and bottom "padding" that a normal inline element has. It's not really padding it's the leading vertical spacing i.e. it's what gives lines enough space to provide for the ascenders and descenders of letters like g, h, p, etc.
the use of it here is to make it seem like your ul is containing the floated child list elements. To make an element contain it's floated children there are other ways to do this, one way is, on ul.base
remove: display: inline-block
add: overflow: hidden;
[UPDATED] re the tabs.. sorry I didn't see them before I started
Here's the "float everything" solution to containing child floats as it applies to your code, with some other suggestions too
.menuContainer all it needs is position:relative; and the border-right rule
.navigationSecondary float it left with a width of 100%; (you can remove z-index it's not doing anything)
.wrapper float it left with a width of 100%, remove the height
ul.base doesn't actually need anything but remove the display-inline-block.. it's not containing the child lists but there's no effect involved, if you want to you can float it left with a 100% width too
[UPDATE 2]
I just copied this to a plain HTML document and I think that just changing the DOCTYPE to an HTML4 transitional one solves the problems with no changes to the code ?? (why that should change the display be I don't quite know! - but the use of "target=_parent" is "not allowed" in Strict Doctypes so that'll be why it's not validating)
I'll put it in JSBIN so others can try it out on various browsers
I changed it to:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
jsbin (with original HTML5 doctype) is here http://jsbin.comhttp://jsbin.com/agihe5/2/ - shows gap
jsbin with changed Doctype - but no changes to CSS code - with flash video to show dropdowns are working is here : http://jsbin.com/inare6/2 - no gap!
jsbin with no changes to Doctype, suggested changes to code and the flash insert to show z-index working is here: http://jsbin.com/iriya4
with the latter, code changes are detailed in the source, they have moved to the bottom of the snapshot CSS
I've tested the changed Doctype version as working in IE7, IE8, FF3.6.15, Safari4 (Win) and Chrome
Providing a test case which requires me to use Firefox and download an extension to view it is highly annoying.
I just did it anyway (purely because of the bounty), and the only change you need to make to your test case is:
On #navigationSecondary ul.base, add vertical-align: top.
The extra height is gone.
Here's a demo based on #clairesuzy's demo titled "jsbin (with original HTML5 doctype)".
(The only change was adding the aforementioned CSS rule):
http://jsbin.com/agihe5/3
The other answers may work (I didn't test them), but (providing I've understood the issue properly), this is by far the easiest fix.
Apparently #navigationSecondary has padding:0 0 3px; set in unnamed-1.css on line 2.
Everything inside ul.base has a height of 24px. Itself has a padding of 2px. So it's height is 26px. It's parent div.wrapper has a height of 29px, 3px extra. It's not caused by the 3px padding of div#navigationSecondary. Nothing is contributing the extra 3px so I'm suspecting a float issue. Anyway I managed to fix it by floating 2 divs.
Add float: left; width: 100%; to div.wrapper and div#navigationSecondary.
Remove display: inline-block; from ul.base.
Floating div.wrapper and div#navigationSecondary collapses them to their nearest floated child element, in this case li.base, and removes the extra 3px. 100% width brings back the stretch.
Hope this helps.
<body style="zoom:0.99; -moz-transform: scale(0.99); -moz-transform-origin: 0 0;">
adjust accordingly, and change hight and width around
Of course. This is simple. A very elementary element positioning issue.
inline-block default vertical-positioning
ul.base is an inline-block. which means that it has spacing calculated like a block, but positioned like an inline-element.
The default positioning of inline-element is to align on the baseline of text. However, text goes below the baseline for letters such as g, j, q etc. This is called "descenders".
The height of a box is always from the top of the font to the bottom of the descenders.
The wrapper takes on the height of its children. Which means that the inline-block ul.base, positioned on the baseline.
Your font at that particular size happens to have a 3-pixel descender. Voila. Your mysterious 3-pixel gap is merely the text's descenders. And your inline-block element is positioned on the baseline (i.e. on top of that 3 pixels).
Tests to confirm that this is right
Change font size. You'll see that 3-pixel changes. Change font size to small enough and it'll reduce to a 1px descender. Your so-called "gap" will shrink.
Change ul.base to something other than an inline-block (of course you have to add something to clear the floats inside). It will no longer have the 3 pixels at the bottom because a non-inline element is not positioned on the baseline.
Position ul.base on the absolute bottom instead of the default (baseline). That 3-pixel gap disappears. Use this CSS rule: vertical-align:bottom
Morale of the story
You always have to be careful with baseline positioning whenever you use inline-block display style.
Off topic
Handling font descenders is especially frustrating with Asian languages. As you know, CJK languages do not have characters that go below the baseline. However, they are typically placed on the baseline (so that they can inter-mix with other European languages, which have descenders). However, when one places a block of text with a background containing only Asian characters, the text will look like it is moved to the top, with an ugly empty gap on the bottom (the descender).