Html anchor height issue with unitless line heights - overflow

Trying to conform to unitless line heights I have a problem with overflow: auto and anchor elements.
Consider the following simple page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>test</title>
</head>
<body style="font-family: arial; font-size: 12px; line-height: 1;">
<div id="wrapper" style="overflow: auto; background-color: #FFCCCC;">
<p>Blah blah blah</p>
Test
</div>
</body>
</html>
The combination of font-size: 12px and line-height: 1 should make the height of the paragraph and anchor (without padding, margin and border) 12 pixels.
The total height of the page should therefore be: 4 * 12 = 48 pixels (2 elements plus 2 * 12 pixels margin for the paragraph). However, almost every browser 'reserves' two or three extra pixels for underlining the anchor (even though I used text-decoration: none). Firefox 7, Chrome 14 and Opera 11.51 all show this behaviour, surprisingly IE9 works fine :).
With their respective developer toolbars, you can see that all browsers agree that the div element has a height of 48 pixels, but only IE thinks the anchors height is 12 pixels. Other browsers say 14 or 15 pixels, causing the scrollbar to appear.
When removing the overflow: auto is not an option (in my case the div is generated by a framework and sometimes just contains floating elements, so the overflow is used to extend the div to encapsulate its children), is there any proper solution to this? i.e. better than giving the anchor font-size: 15px or line-height: 1.2 or something.
Cheers,
Moolie

The issue only seems to happen if the a is touching the bottom of #wrapper directly. This means you can solve the problem in 3 ways:
put the link into a paragraph
set display block on the link and give it a margin
set a padding bottom on the wrapper
You'll have to decide if you find these more "clean".

Related

Is there a way to freeze a column in a vuetify data table?

I cannot find a good solution to this without using a vuetify fork, which isn't stable and appears to be the older version anyway. I will link to it in the comments.
The only way I can think to do this is to line up two data tables side by side, which creates problems in itself. I know there are other plugins/libraries that allow this, but I would really prefer to stick with vuetify. Has anyone had success with doing this?
My project is to create a grid that allows the user to set up a rotation. Each column (after the first one) is a dynamically created week (Friday's date is column header) that shows if there is an opening in a given organization. The struggle is to get enough weeks to show up on the screen at once. The first column is the organization. So, I want to know what organization my row is in for a given week as I scroll to the right. That's why I need to freeze the first column.
I'm open to other solutions - like a different way to show the header, perhaps, that would allow me to fit in 52 weeks worth of dates.
I am also searching for a solution to this. The nearest I have found is this complex bit of CSS Source
<style>
table > tbody > tr > td:nth-child(1),
table > thead > tr > th:nth-child(1) {
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
z-index: 9998;
background: white;
}
table > thead > tr > th:nth-child(1) {
z-index: 9999;
}
</style>
However, it doesn't quite work for my case.
I have something like this
Account Jan Feb Mar
123456 50 51 52
123458 38 39 32
123600 20 21 22
So what I am looking for is the Excel equivalent of putting a freeze panes on the Jan,123456 intersection, so that the months stay in place when scrolling down, and the Account column stays in place when scrolling to the right.
I set the fixed-header and :height property on the v-data-table so that the header does not scroll vertically and so that it has a vertical scroll bar. The horizontal scroll bar seems to happen automatically and is specific to the table rather than the page.
Without the CSS the vertical scrolling works, though obviously not the horizontal scrolling as the Account column scrolls off screen to the left.
With the CSS the account numbers stay in position, but the headings still scroll to the left, so eg Jan replaces Account. Also when scrolling down, the Account Numbers scroll up to overwrite Account. It is closer to a solution than the basics provided by Vuetify.
I also saw the example from someone who had cloned vuetify and modified it to include fixed columns and grouping. However, I was not sure whether that was vuetify 1.5 or 2 and I have already had issues with seeing examples on 1.5 and then finding that they don't work on vue 2 which I am using as there were so many breaking changes. Like you I am also wary of adopting something that may not be supported.
I am surprised that Vuetify did not include this. It must be a pretty common requirement. I have seen an enhancement request for Vuetify 3, but it is too early to adopt that and presumably it would also mean adopting Vue 3.
Regards
Paul Simon
I finally found an approach to this that works. Another approach
However, I cannot really claim it as an answer to the original question as it only works by abandoning the use of a v-data-table altogether. I ended up just putting a standard table in between v-spacer in my vuetify card. Any attempt to use even a v-simple-table added a second unnecessary horizontal scroll bar which ruined the effect.
The bit of CSS linked above does at least give fixed header(s) and fixed column(s) with none of the issues around scrolling up over the top left corner cell of other approaches I have seen.
It is also very easy to mark which headers you want fixed (usually all) and, in particular, which columns you want fixed. Note that the fixed columns should use 'th' rather than 'td'. This is ideal for my purpose since my data source is multi-dimensional and returns row headers and then cells with numbers eg
Actual Actual Budget Budget
Country Product Jan Feb Jan Feb
UK Widget1 50 60 70 20
UK Widget2 60 80 90 100
USA Widget1 90 80 10 90
In the example above all the following are 'th'
Actual, Budget, Jan, Feb
Country, Product
Only the number cells are 'td'
As you can see, all you need to do is to mark the 'th' in the html with class="fixed" so unlike other approaches it works for an arbitrary number of columns rather than just the left most column.
I am an expert in multi-dimensional modelling, and certainly not an expert in CSS, but I modified the CSS in the linked example a little. My CSS is as follows:
<style scoped>
.table {
background-color: white;
margin: auto;
width:90%;
max-width:100%;
border-collapse: separate;
display: block;
overflow-x: scroll;
}
thead,
tbody {
display: inline-block;
}
thead {
position: sticky;
top: 1px;
z-index: 2;
}
tbody {
height: 200px;
}
th {
background-color: lightgrey;
border-left: 1px;
border-right: 1px;
border-color: black;
}
td,
th {
min-width: 100px;
max-width: 100px;
word-wrap: break-word;
}
.fixed {
position: sticky;
width: 5em;
left: 0;
top: auto;
z-index: 1;
}
td:not(.fixed) {
z-index: 0;
}
</style>
Instead of giving a fixed width for the table, I used %. I know that not all browsers support this but this is going to be an internal application. It is not a shopping site.
I also took the z-indexes down from 9999,999,0 to 2,1,0 as without this it tended to wind up on top of the Vuetify footer when scrolling down.
Regards
Paul Simon

wkhtml2pdf rendering size issue

Taking care of removing any paddings or margins, I have created a basic html page containing a single table whose height is supposed to be 297mm (A4 paper height):
<!DOCTYPE html>
<html>
<head>
<style>
body
{
padding: 0; /* Padding for content */
margin: 0 auto; /* Margin from container */
}
table
{
padding: 2.5mm 5mm; /* Padding for content */
margin:0; /* Margin from container */
width:100%;
border-spacing:0;
background-color:yellow;
height:297mm;
}
</style>
</head>
<body>
<table>
<tr style="height:3%"><td style="background-color:RGB(235, 105, 11)">1</td></tr>
<tr style="height:30%"><td style="background-color:RGB(47,52,57)">2</td></tr>
<tr style="height:17%"><td style="background-color:RGB(94,98,102)">3</td></tr>
<tr style="height:auto"><td style="background-color:RGB(255,255,255)">4</td></tr>
<tr style="height:13%"><td style="background-color:RGB(47,52,57)">5</td></tr>
</table>
</body>
</html>
And I'm trying to render this in A4 PDF format using wkhtml2pdf utility (again taking care of removing any margin and/or padding:
wkhtmltopdf.exe --page-size A4 -L 0 -R 0 -T 0 -B 0 .\testsize.html testsize.pdf
Anyway rendered table height does not seem to be 297mm in PDF document. It appears to be smaller:
It is only when modifying table height to height: 371mm that I can have it to fill full A4 paper height in the PDF document (NB: 371mm/291mm is almost a x1.25 ratio).
Do you have any idea for where this ratio in rendering height comes from and how i may fix it ?
NB1: As far as I know wkhtml2pdf uses webkit as rendering engine
NB2: When displaying html code in chrome with zoom=x1, displayed height already doesn't match with A4 PDF document placed side-by-side and zoom also set to x1.
I'm not sure wkhtmltopdf respects the mm CSS unit. That said, you could try to adjust some command line options that modify the ratio between the HTML document sizes and the rendered PDF:
--zoom <float>: I think this one is the most important in your case. Try to set to --zoom 1.25, the ratio you estimated.
--disable-smart-shrinking: In my experience, this command often prevents element sizes to have unexpected values.
--dpi <number>: I'm not sure if this will change something, but try 300 or 600.

Compass sprites in IE8

I just started using Compass' sprite generator a few days ago and realized that my sprites are not showing up in IE8. I think that I traced my problem back to this previously reported issue: compass sprite is not working in ie8 and ie7
Santosh points out that IE8 breaks when pseudo classes like :not are used.
I can see that my selector is probably breaking because Compass is including the :checked and :before pseudo classes in the selector (from icons/global/*.png):
input[type="checkbox"]:checked + .btn-checkbox:before,
input[type="checkbox"].checked + .btn-checkbox:before,
input[type="radio"]:checked + .btn-checkbox:before,
input[type="radio"].checked + .btn-checkbox:before,
.segmented-checkbox .btn- checkbox.selected:before
{
background: url(/assets/rp-icons/global-s67c66a3554.png) no-repeat;
}
My question is how do I change the automatically generated selector or split it up so that the whole thing doesn't break in IE8?
This issue was also mentioned here, but the solution is not clear:
https://github.com/chriseppstein/compass/issues/1193
The problem is:
IE8 can't understand :checked, thus making the entire declaration invalid.
You have two options:
#1 Make the sprite twice
First use conditional comment to add the class .ie to html or body
<!--[if lt IE 9]> <html class="ie"> <![endif]-->
<!--[if gt IE 8]><!--> <html> <!--<![endif]-->
First line is 'lower than IE 9', so IE8 or below get class ie. The second is 'greater than IE8' so IE9+ and other browsers (note the <!-->).
So now split your sprite in two, one for :checked and another to .checked, importing twice, so the final css is:
/*this will be invalid for IE<8, valid for all others*/
input[type="checkbox"]:checked + .btn-checkbox:before,
input[type="radio"]:checked + .btn-checkbox:before,
.segmented-checkbox .btn-checkbox.selected:before
{
background: url(/assets/rp-icons/global-{hash}.png) no-repeat;
}
/*this would be valid for everyone, but since we added .ie, just IE will apply*/
.ie input[type="checkbox"].checked + .btn-checkbox:before,
.ie input[type="radio"].checked + .btn-checkbox:before,
.ie .segmented-checkbox .btn-checkbox.selected:before
{
background: url(/assets/rp-icons/global-{hash}.png) no-repeat;
}
Then create a handler with javascript that when the input is clicked, if it is checked you add checked class;
#2 Try see if a polyfill will fix for you:
You can try http://selectivizr.com/, it have polyfill for :checked on all supported frameworks! so it will make IE8 accept your :checked. Read 'You need to know' at the end of page to know its limitations

line-height 2px lower in firefox vs webkit

I have the following css:
.btn_container {
cursor: pointer;
font-family: Tahoma,Verdana,Arial;
font-size: 11px;
padding: 0;
width: auto;
}
.btn_center {
background: blue;
color: #FFFFFF !important;
display: block;
float: left;
font-weight: bold;
height: 32px;
line-height: 32px;
padding: 0 10px;
}
line-height of 30 lines up center in firefox, but 32 in webkit.
I know browsers will render things differently, but i've never had a problem getting text to center properly.
In the following example you can see that it drops a couple px lower in firefox:
http://jsfiddle.net/mstefanko/EGzEB/5/
I've done heavy testing of this in the past. I call it text jiggle. It's not something you can control. All you can do to minimize it is apply an explicit line-height (especially one in px) to every text element.
The default line-height varies by a wide margin in different browsers, and for different font families at different font sizes. Setting an explicit line-height addresses that.
But within that, the exact placement of the text within the line-height space will vary slightly browser-to-browser no matter what you do. For some combinations of font-size and line-height, all browsers match up. For instance, Arial at font-size:11px and line-height:14px renders the same in FF, Webkit, and IE. But change the line-height to 13px or 15px, and it varies by 1px browser-to-browser.
There's no standard or defined behavior for it. It's the result of how that particular font-family, font-size, and line-height happens to be rendered by the browser on that operating system. Arial, for instance, is a relatively consistent font, generally not varying by more than 1px as long as an explicit line-height is defined, while Helvetica varies by as many as 4 to 6 pixels.
I had the opposite experience actually. I noted that some header elements were positioned higher in IE7/compatibility mode as well as Chrome/Safari. So after much trouble I inspected with chrome and saw -webkit-margin-before: 1.6em or something added to the headers. Adding that value and tweaking it didn't work because it effected the height of the header which pushed some elements down but the padding option worked well for me ...
I found that this worked for me:
H1, H2, H3, H4, H5, a.mainTab div {
-webkit-padding-before: 1px;
}
a.mainTab div had spans which wouldn't respond to the padding/margin so wrapped them in a div ... this may work for li span span headers as well.

Fixed positioned div with a fixed height and relative or absolute divs inside it with greater height

I have a problem with IE.
I have a fixed div like this:
#fixed {
position: fixed;
top: 0px;
left: 0px;
z-index: 9998;
width: 100%;
height: 40px;
}
Inside this div I want to place another div that has a height that is higher than its holder (higher than 40px). So I put a relative or an absolute div inside it and it works splendid in all browsers except IE, at least IE8.
But in IE8 the child div gets cut because of the height of 40px specified for it's holder.
Is there any workaround to this problem? I'm starting to get gray hairs..
Quick reply: have you tried setting the clip property of the contained div to it's own size?
Another workaround would be (if, say you have a container div with left/right margins auto and position: relative) to have the second div outside the fixed div in your HTML, then position it fixed within the container div instead - since it's also fixed, you can then set top/bottom and left/right positions to suit.

Resources