How can I get wkhtmltopdf to display th and td background gradients? - css

I need to add background gradients to some td and th elements in page which gets converted to PDF, however I'm getting some very strange behavior from wkhtmltopdf, so when I do this:
table {
width: 100%;
border-collapse: collapse;
}
th {
height: 60px;
border: 1px solid Black;
}
td {
height: 100px;
background: -webkit-linear-gradient(top, #ccc 0%, #888 100%);
border: 1px solid Black;
}
<table>
<tr>
<th></th>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
</table>
The height of the th seems to encroach on each subsequent td somehow. All is well if I remove the th or set its height to a whole multiple of the td height.
Anyone got any insight into what's going on here? My HTML is hard to change so I'm hoping to be able to get this working using CSS alone, or wkhtmltopdf settings.
Edit:
Some screenshots before the bounty expires:
Here's how it looks in a webkit browser:
Here's what wkhtmltopdf does to it:
And one further observation: it doesn't have to be a th to cause the problem, as changing it to a similarly targeted <td class='th'> will cause the same effect.

wkhtmltopdf still uses the old (deprecated) webkit gradient syntax. Try this:
-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#888));

For me it was as simple as adding
background-repeat: no-repeat !important;

What you think about this?
<style>
.table {
width: 100%;
display:table;
border-collapse: collapse;
}
.tr {
height: 60px;
display:table-row;
border: 1px solid Black;
}
.td, .th{
height: 60px;
border: 1px solid Black;
display:table-cell;
background: -webkit-linear-gradient(top, #ccc 0%, #888 100%);
}
</style>
<div class="table">
<div class="tr">
<div class="th"></div>
</div>
<div class="tr">
<div class="td"></div>
</div>
<div class="tr">
<div class="td"></div>
</div>
</div>
Is better to use DIV instead of the tables. You can do same thing with small changes.
And is better for you to add CSS inline to HTML if you work PDF or send on email like template.
UPDATE:
You can do this:
<style>
table {
width: 100%;
border-collapse: collapse;
}
th {
height: 60px;
}
td{height: 100px;}
td, th {
background: -webkit-linear-gradient(top, #ccc 0%, #888 100%);
border: 1px solid Black;
}
</style>
<table>
<tr>
<th></th>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
</table>
or jQuery to replace tables with nested divs:
<style>
.table {
width: 100%;
display:table;
border-collapse: collapse;
}
.table .tr{
display:table-row;
}
.table .th{
height: 60px;
font-weight:bold;
}
.table .td{height: 100px;}
.table .th,
.table .td {
border: 1px solid Black;
display:table-cell;
background: -webkit-linear-gradient(top, #ccc 0%, #888 100%);
}
</style>
<table>
<tr>
<th>a</th>
</tr>
<tr>
<td>b</td>
</tr>
<tr>
<td>c</td>
</tr>
</table>
<script>
$(document).ready(function(){
$("table").each(function(a,table){
var i=a;
$(table).after('<div class="table" id="table-'+i+'"></div>');
var currentTH = $(this).parent().find('th');
$(currentTH).each(function(){
var content=$(this).html();
$('#table-'+i).append(' <div class="tr"><div class="th">'+content+'</div></div>');
});
var currentTD = $(this).parent().find('td');
$(currentTD).each(function(){
var content=$(this).html();
$('#table-'+i).append(' <div class="tr"><div class="td">'+content+'</div></div>');
});
$(this).remove();
});
});
</script>

We had to upgrade wkhtmltopdf due to security reasons and we experienced the same problem, however after struggling with CSS I managed to find a solution that worked for us, for example, the following CSS:
.TableRecords_Header {
color:#EAEAEA;
font-weight: normal;
background: #0F5D85 url(/RichWidgets/img/bar_gradient.png);
white-space: nowrap;
line-height: 18px;
padding: 4px 6px 4px 6px;
border-right: 1px solid white;
font-size: 14px;
}
Applied to any table <th> or <tr> cells, renders something like this:
Gradient Bug
It turns out that this version of webkit has problems handling "repeat-x" CSS property, so, to solve this issue I have used this CSS3 Equivalent:
.TableRecords_Header {
background-repeat: no-repeat !important;
background-size: 100% 23px !important;
}
Where background-repeat: no-repeat !important; tells webkit not to use background repetition eliminating the problem.
As for background-size, the value 100% does the same as the original repeat-x, and the 23px is the height of the image that produces your gradient. in this case is the height of /RichWidgets/img/bar_gradient.png.
When we added this CSS3 style the PDF rendered correctly as shown in the following image:
Gradient problem solved
Best Regards,
Nuno Guedes

Use inline css for this page which convert to pdf.

Related

IE11 not recognizing z-index: -1

I have a table that uses box-shadow when hovering on rows to display some styling. This was working fine until I discovered that in IE11 it not working.
The problem seems to be that using a z-index: -1 to avoid the td being above tr is not working as expected in IE11.
table td {
position:relative;
background-color: #EFEFEF;
z-index: -1;
}
I have created a fiddle that works in chrome but not in IE11: https://jsfiddle.net/pjz43a52/8/
So my questions are:
Is there any known issue with IE11 and z-index: -1? I found things related to z-index but not to this case specifically.
How can I solve this? I tried different things but none of them working without breaking the current behavior which is to have the box-shadow on top of the td.
Any ideas?
<table> is cancer...
Although I don't know WHY exactly such behaviors happen... But yeah - that's compatibility issues and we've to hack around it, so if we re-use the same code you wrote before, but instead of using a <table> we will use only <div>, the result will be the same, but it will work on IE11 - I tested it for you!
.container {
background-color: #fafafa;
z-index: 0;
}
.table {
position: relative;
width: 100px;
z-index: 1;
border-spacing: 0px;
border-bottom: 1px solid black;
}
.table .col {
position:relative;
background-color: #EFEFEF;
z-index: -1;
border-top: 1px solid black;
border-right: 1px solid black;
border-left: 1px solid black;
}
.table .row:hover {
position: relative;
box-shadow:
inset 5px 0 0 #dadce0,
inset -3px 0 0 #dadce0,
0 5px 2px 0 rgba(60,64,67,.3),
0 5px 3px 1px rgba(60,64,67,.15);
}
<div class="container">
<div class="table">
<div class="row">
<div class="col">Some Value</div>
</div>
<div class="row">
<div class="col">Some Value</div>
</div>
<div class="row">
<div class="col">Some Value</div>
</div>
</div>
</div>
Since you are setting the Z-Index property, when you using F12 developer tools (using IE 11) to select the elements, you can only select the table elements, instead of the tr, so, it will not trigger the hover action. Screenshot as below:
To solve this issue, you could add the following CSS style:
table tr{
display:block;
}
Then, when using F12 developer tools to select elements, we could select the table row. Thus, it will trigger the hover action.
The test sample as below:
<style type="text/css">
table {
position: relative;
z-index: 1;
border-spacing: 0px;
border-bottom: 1px solid black;
}
table td {
border-top: 1px solid black;
border-right: 1px solid black;
border-left: 1px solid black;
}
table tr{
display:block;
}
.container {
background-color: #fafafa;
z-index: 0;
}
table td {
position: relative;
background-color: #EFEFEF;
z-index: -1;
}
table tr:hover {
position: relative;
box-shadow: inset 5px 0 0 #dadce0, inset -3px 0 0 #dadce0, 0 5px 2px 0 rgba(60,64,67,.3), 0 5px 3px 1px rgba(60,64,67,.15);
}
</style>
<div class="container">
<table>
<tbody>
<tr>
<td>Some Value</td>
</tr>
<tr>
<td>Some Value</td>
</tr>
<tr>
<td>Some Value</td>
</tr>
</tbody>
</table>
</div>
The result:
Is there any known issue with IE11 and z-index: -1?
This is likely not related to z-index directly, but due to the fact that CSS 2.1 specified that,
The effect of position:relative on table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption elements is undefined. (https://www.w3.org/TR/CSS2/visuren.html#propdef-position)
This restriction has been lifted with the CSS 3 Positioning Module - but that doesn’t necessary mean, IE has kept up.
If you nest an additional element into your table cells and apply position, z-index and background to that, you should be able to get this basically working, https://jsfiddle.net/pjz43a52/10

stacking context on table element(head and body)

I was stuck with one CSS stacking context issue, I simplified it to following simple case.
A simple table as following code, I translated header in order to achieve scrolling effect, while the header was always covered by those translated td cells.
I have read several articles, including that famous one "What No One Told You About Z-Index", and try to add both translate and z-index css properties on thead and tbody, and I 'guess' they should be in the same stacking context, so z-index will work, while I failed, does the failure due to table has some special constraints on stacking context? The only solution I can find now is switching thead and tbody position in the html by putting thead after tbody tag.
Full Case is here.
.m-table {
width: 40%;
font-size: 14px;
text-align: center;
border: 1px solid #e6eaf9;
background: #fafbff;
transform: translateY(0);
}
.m-table th,
.m-table td {
padding: 16px;
border: 1px solid #ddd;
background: #effff0;
}
.m-table th {
background: #e6eaf9;
}
.m-table thead {
transform: translateY(25px);
margin-bottom: 10px;
}
td label.u-angle {
display: inline-block;
width: 10px;
height: 10px;
background: #79c5ff;
transform: rotate(45deg);
}
<table class="m-table">
<thead>
<tr>
<th>Price</th>
<th>Algorithm Factor</th>
<th>Links</th>
</tr>
</thead>
<tbody>
<tr>
<td>$1,326</td>
<td>
<label class="u-angle"></label>
</td>
<td>
Detail
</td>
</tr>
</tbody>
</table>

<td style="width"> attribute works inline but not in external stylesheet

I'm trying to use external css to format a 3-column table with 100% width and column widths of 10%, 80%, and 10% respectively. All my td attributes work from the external stylesheet except width.
<td style="width:10%">
works in inline css, but not as an internal style or from the external stylesheet.
It will read td widths from the external css if I remove the 100% width attribute from the table, but then the width of my table changes depending on the amount of text in it.
I have tried using
table-layout: fixed;
with no success. I've also tried removing width from one column at a time with no effect. All the examples I can find use pixels instead of % widths.
Have I missed something simple about table design?
Here's the relevant part of my external css:
table.border td {
border-width: 5px;
padding: 10px;
border-style: ridge;
border-color: white;
border-collapse: collapse;
-moz-border-radius: 0px 0px 0px 0px;
vertical-align: top;
width: 100%;
}
td.edge {
background-color: green;
width: 10%;
}
td.center{
width: 80%;
background-color: pink;
}
and here's the table's html:
<table class="border" >
<tr>
<td class="edge"> hi there</td>
<td class="center">it's me</td>
<td class="edge"> bye there</td>
</tr>
</table>
The table it gives me has a wide first column and narrow second and third columns.
Correct the CSS as follows (just removing "td" from this line: "table.border td") and it will work as expected:
table.border{
border-width: 5px;
padding: 10px;
border-style: ridge;
border-color: white;
border-collapse: collapse;
-moz-border-radius: 0px 0px 0px 0px;
vertical-align: top;
width: 100%;
}
td.edge {
background-color: green;
width: 10%;
}
td.center{
width: 80%;
background-color: pink;
}
This is jsfiddle example: https://jsfiddle.net/r281bv1z/
Hope this may help.

Two different table in parallel in a asp.net web

i have a table in asp.net web the code is as under
<table class="gridtable">
<tr>
<th>Info Header 1</th><th>Info Header 2</th><th>Info Header 3</th>
</tr>
<tr>
<td>Text 1A</td><td>Text 1B</td><td>Text 1C</td>
</tr>
<tr>
<td>Text 2A</td><td>Text 2B</td><td>Text 2C</td>
</tr>
</table>
style is as under
<style type="text/css">
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
}
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}
</style>
now i want two different tables which is displayed in parallel but different table the formatting also will be different
one table displays here in web page and the second table displays here on the web
how can i do that.
(1) side-by-side tables:
Add float:left to your table.gridtable { css.
(2) gap between them:
Add margin: 0px 2px to table.gridtable { css. This will give a gap of 2 pixels.
See this fiddle: http://jsfiddle.net/8kKhL/1/
Note: Make sure the cumulative widths of your tables do not exceed the page width to avoid ugly horizontal scroll or wrapping.

All borders are not displaying on table in ie7 compatible view

No sure why the borders are not displaying correctly. I tried:
/* ------ global ------ */
body {
margin: 0 auto;
padding:0 0;
font-family:Arial, Helvetica, sans-serif;
text-align:center;
color:#000;
}
/* ------ Content Wrapper ------ */
#wrapper {
margin: 0 auto;
width:760px;
text-align:left;
}
#content table {
font-size:.8em;
border-collapse:collapse;
text-align:left;
width:100%;
}
#content table td {
border:solid 1px black;
}
Do I need to list all the CSS border properties to get the borders on the whole table, like this:
border-top: 1px solid #000;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
border-left: 1px solid #000;
or more ......
I haven't done this yet, but I have had to do this in the past with some tables to get the borders on all sides for lte IE7. It was just as a last resort since I didn't know what else to do.
Consider the following jsFiddle, which works correctly in IE7 by showing a 1 pixel solid black border on table cells.
I didn't change any of your code, but added a rule to include borders on table header cells table th as well as table data cells table td.
HTML:
<div id="content">
<table>
<tr>
<th scope="col">Column</th>
<th scope="col">Column</th>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</table>
</div>
CSS:
#content table {
font-size: 0.8em;
border-collapse: collapse;
text-align: left;
width: 100%;
}
#content table th,
#content table td {
border: solid 1px black;
padding: 5px 10px;
}
If your table cells still aren't showing any borders, you might have one or more rules in your stylesheet that appear later — or have more CSS Specificity — that are overriding your styles.
Try using border-collapse:separate for IE7 like this:
#content table {
font-size:.8em;
border-collapse:collapse;
text-align:left;
width:100%;
*border-collapse:separate;
}
apply border-collapse: collapse to the table, it should fix it :)

Resources