Can I use CSS to override table cell widths? - css-paged-media

I've got an HTML where the width of table cells is defined in mm (in the #style attribute). This is designed to fit on an A4 page (210 mm page width). I'm using CSS Paged Media.
<?xml version="1.0" encoding="UTF-8"?>
<html lang="en">
<head>
<title>A5 Test</title>
<link rel="stylesheet" type="text/css" href="booktemplatea5test.css"/>
</head>
<body>
<table data-ait-rows="2" data-ait-cols="2" style="width:170mm;" data-ait-tabletype="warning">
<tbody>
<tr style="height:12mm;">
<td colspan="2" style="width:100%;border-width:3pt;border-color:#000000;background-color:#FFB2B2;" >
<p class="warning">Possible hazard. Risk of personal injury.</p>
</td>
</tr>
<tr style="height:12.4mm;">
<td style="width:40.2mm;border-left-width:0.40pt;border-right-width:0.40pt;border-top-width:0.00pt;border-bottom-width:0.40pt;border-color:#010101;">
<p class="body">text</p>
</td>
<td style="width:128.1mm;border-left-width:0.00pt;border-right-width:0.40pt;border-top-width:0.00pt;border-bottom-width:0.40pt;border-color:#010101;vertical-align: middle;">
<p class="body" >A warning is used</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Now I want to use the same table for a different output that uses A5 (width 148.5mm), so I want the CSS to resize the table to fit.
#page {
size: A5 portrait;
margin-start: 1cm;
margin-end: 1cm;
margin-top: 2cm;
margin-bottom: 2cm;
}
table, tr, td {
max-width: 100mm;
}
This CSS works for very simple tables (one cell). As soon as the table becomes more complex (like the example above), the max-width instruction is ignored.
Is there a way to achieve what I want (make the table fit on A5) in CSS? Or do I have to process the HTML and calculate new cell widths?

Use !important to override properties in the style attributes:
table, td {
width: auto !important;
}
From https://www.w3.org/TR/css-style-attr/#interpret:
The declarations in a style attribute apply to the element to which the attribute belongs. In the cascade, these declarations are considered to have author origin and a specificity higher than any selector.
From https://drafts.csswg.org/css-cascade-3/#cascade-sort, property declarations with !important have a higher importance than 'normal author declarations', and importance has higher priority than specificity.

Related

Unloaded Heading Tag Causing Flicker

I have the following code:
<div ng-cloak ng-init="viewAlbum()" class="ng-cloak">
<h3 ng-cloak class="ng-cloak" ng-bind="album.Title"></h3>
<table ng-cloak class="ng-cloak">
<tr>
<td class="label-col"><span class="album-label">Composer</span></td>
<td class="value-col">{{album.Composer}}</td>
</tr>
<tr>
<td class="label-col"><span class="album-label">Release Year</span></td>
<td class="value-col">{{album.ReleaseYear}}</td>
</tr>
<tr>
<td class="label-col"><span class="album-label">Rating</span></td>
<td class="value-col">{{album.Rating}}</td>
</tr>
<tr>
<td class="label-col"><span class="album-label">Reviews</span></td>
<td class="value-col">
<ol>
<li ng-repeat="review in album.Reviews">{{review.Text}}</li>
</ol>
</td>
</tr>
</table>
The problem is that I am seeing a quick flicker when the page load. I'm am not seeing raw unprocessed angular code. Instead, the entire table flickers including the static text such as the labels.
I did some experimenting - when I remove the H3 tag, I no longer see the flicker. So, I believe what is happening is the H3 tag is initially rendered with no value and therefore takes up no vertical space. When the value of the album title is rendered, the table is pushed down, and it is this "pushing down" that is causing the flicker. My theory could be wrong however.
The ng-clock attributes don't mitigate this. I tried a verbose option of surrounding the H3 tag in a container DIV and setting the height and min-height of that DIV in the css but that also isn't preventing the flicker.
As I said, if I remove the H3 tag, there is no flicker. Any suggestions please?
As mentioned in the below link you can Just wrap your h2/h3 tag in a div with display: inline-block; like this:
<div class="header2"><h3></h3></div>
and then add this to your css:
.header2 { min-width: 100px; width: auto; min-height:45px; background-color:#333; color:#FFF; display:inline-block; padding:10px; }
Here's a jsfiddle of two h2 tags with the above properties: https://jsfiddle.net/AndrewL32/e0d8my79/21/
Check :How do I make an inline element take up space when empty?
I recommend you also to use ng-bind for all your doms and remove the ng-cloak too

Bootstrap + AngularJS - Multiple page print job with common header/footer

I am using bootstrap with AngularJS and trying to ng-repeat out a table within the template I purchased and when over a certain amount is put into the orderInformation.items array I run into issues with how the print looks.
I want to be able to hit print and have a defined page heading and a defined page footer that will not change and should nest in the top and bottom of the print preview across all pages. The only content that will change is the items that AngularJS is doing an ng-repeat on.
How can this be done? I've been searching for days and days and nothing out there seems to work.
<div class="row">
<div class="col-md-12 card-box">
<table id="invoice-contents" style="width: 100%">
<thead>
<!-- This is where logo, company details, barcode go -->
</thead>
<tbody>
<table id="item-table" class="table m-t-30" style="border-bottom: 1px solid rgba(0,0,0,.1)">
<thead>
<!-- Invoice Item headers -->
</thead>
<tbody>
<tr ng-repeat="item in orderInformation.items">
<td style="text-align: center">{{$index + 1}}</td>
<td style="text-align: center">{{item.qty.ordered}}</td>
<td style="text-align: center">{{item.qty.shipped}}</td>
<td style="text-align: center">{{item.qty.backordered}}</td>
<td style="text-align: center">{{item.binLocation}}</td>
<td style="text-align: center">{{item.partNumber}} - {{item.description}}</td>
<td style="text-align: center">{{item.price.current * item.qty.shipped | number: 2}}</td>
<td style="text-align: right">{{item.price.extended * item.qty.shipped | number: 2}}</td>
</tr>
</tbody>
</table>
</tbody>
<tfoot>
<!-- Special order notes, totals, taxes, terms -->
</tfoot>
</table>
</div>
</div> <!-- end container -->
This doesn't work when I use the recommended CSS that I have found around:
thead { display: table-header-group; }
tbody { display: table-row-group; }
tfoot { display: table-footer-group; }
The documentation says a table can't have two thead so I know the problem lies there, but I can't find any other way to get a block to print top and bottom on all pages other than table-header-group.
A way round this through much trial and error was to product an onscreen display of a single invoice page with how ever many rows of data and then use display:none to hide a view that would only show during print with CSS #media print. I had to calculate how many rows would show on each page and use .splice() and nested ng-repeats to get it displaying properly.

Table styling with LESS

This question is about styling a table which is created inside an AngularJS directive. I have an array of objects passed to the directive from HTML file. The directive creates a table and shows each object of the array in a row.
Now my question: There is a self-defined JSON field in each object called name. Styling is done by LESS technology and I want to have a thick separating line behind each row when 'name == david'. Please consider this condition can be different for example when 'rowID%3 ==0' and etc. My general question is how can I access this objects in LESS file and how can I make conditional styling inside LESS.
I'm making a lot of assumptions since you didn't include any code or markup, but in Angular this is a very basic, simple problem, and is independent of whether you are using LESS, Sass, or just plain CSS:
<table>
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in vm.items track by $index" ng-class="{'thick-separator': isNameDavid(item) || $index%3 == 0}">
<td>{{item.propOne}}</td>
<td>{{item.propTwo}}</td>
<td>{{item.propThree}}</td>
</tr>
</tbody>
</table>
In your controller:
$scope.isNameDavid = function(item) {
return item.name == 'david';
};
Using the ngClass directive and the $index scope variable that is introduced by the ngRepeat directive, you can easily assign a thick-separator class to table rows, conditionally.
Now, it makes no difference if you are using LESS, Sass, or plain CSS:
.thick-seperator {
border-top: 5px solid black;
}
If, however, you are trying to say that you can't change the Angular code and you need to be able to style purely with LESS, then you can style using attribute and nth-child selectors. Note that these are available in plain CSS and LESS is not needed:
table tbody tr:nth-child(3n+3), table tbody tr[data-name="david"] {
border-top: 5px solid black;
}

How to position a column under another column?

I am currently working on a website that is mobile friendly. In this case I have to use the same HTML. I can make do some minor adjustments but it MUST look like the same when I change it back to this default CSS.
#explain{
position:absolute;
top:100px;
left:20px;
width:95%;
min-width:0;
margin:auto;
column-count:1;
}#explain th{
margin:0px;
}#explain_icon img{
width:130px;}
<html>
<head>
</head>
<body>
<table id="explain" cellspacing="15px">
<tr id="explain_icon">
<td><img src="IMG/group.png" alt="Image has failed to load"></td>
<td><img src="IMG/Bell.png" alt="Image has failed to load"></td>
<td><img src="IMG/Warrenty.png" alt="Image has failed to load"></td>
</tr><tr>
<th>Japan</th>
<th>is a</th>
<th>smaller china</th>
</tr><tr>
<td><b>The
</b></td>
<td><b>Human
</b></td>
<td><b>Esophagus
</b></td>
</tr></table>
</body>
<html>
Use Bootstrap. Integrate Bootstrap in your website and just divide your html page in row and column classes. This is perfect way to make any website mobile friendly.
I solved my problem by changing the table into a divider format. I also made a list for the individual objects within the code. I went into the CSS and changed it so that the display would go into "table" which basically made everything columns.

How to display icons in a table depending on model in AngularJS?

I am new to AngularJS (and Javascript as well) and I try to display different icons in a table depending on a value in a field from my model.
Let's say this is my model:
$scope.MyList = [{ name: "Production", status: "Running"},
{ name: "Test", status: "Stopped"}];
This is a table for displaying the model in one of my views:
<table class="table table-striped">
<thead>
<tr>
<td>Name</td>
<td>Status</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in MyList">
<td>{{instance.name}}</td>
<td>{{instance.status}}</td>
</tr>
</tbody>
</table>
I would like to display the status using both one icon and the text. What is the recommended way of doing it? I would like to use something that feels natural with AngularJS.
Thank you.
The answer from dolgishev pointed me into the right direction.
I initialice my table elements like this:
<tr ng-repeat="item in itemList">
<td>{{item.name}}</td>
<td class="{{item.status}}">{{item.status}}</td>
</tr>
and then I use CSS for displaying the icon using a font from FontAwesome. This is for example the CSS for the state 'Running':
.Running:before {
font-family: 'FontAwesome';
font-size:1.3em;
color:green;
content: '\f00c'; /* the ok icon */
padding-right: 4px; /* plus 4px spacing */
}
This will display the ok icon in green, then 4 pixel padding and then the text for the state "Running". It is looking great!
For solve this you can use Angular's directive ng-class. It allows you to set class of element depend on expression.
Also you can do this without directive, in this way:
<div class="{{MyList.name}}">

Resources