Pretty straightforward problem. Have scroll-able ion-content in my Ionic4 application. I want to be able to print it gracefully by applying #media only print styles. I'm almost there, but I have one major problem. I cannot get the vertical scrollbar to disappear for printing. Additionally, I only ever get one page printed, containing only the content that is in view when I print the page. I've scoured the web for solutions, and come across and tried various suggestions in the context of Ionic3 and earlier, but I haven't found the magic bullet for Ionic4 yet. Has anyone encountered and gotten to the bottom of this yet?
I have been through the ringer on trying to print content in Ionic 4. Some of the steps i followed to print multiple pages.
remove any flex-box styled lists. They just will not print how you want them to across pages, though they have worked fine for me if the content fits in a page.
for items you want to be seperated by page, its best if they are a display: block; styled item, so that that in the print style sheet you can use one of the page-break properties on it
on the item containing your list, the ion-content for example, make sure you remove any max-height attributes from it or any of its ancestor or child elements, as well as removing the overflow: scroll from these elements as well so that it allows your content to go from page to page. for example on my stylesheet for printing (cant share it because of NDAs) I had a lot of overflow-y: visible on elements just to make sure it shows. if you find an element thats cutting off your html, it should be the primary target for experimentation.
you can simulate a print in the dev tools, i found it useful, it's good for iteration here's a link
some other things that may help, but i am not sure as I did so much testing across browsers, and only vaguely remember what impact that css property had is to have the body with a static position, as well as having contain: none on the body to say that the browser should render as normal, little more explanation here
i do not know the specifics of your use case, but if you don't mind foregoing the native print button, and just giving the user a button to click to trigger the print, then that would be more manageable as you do not have to account for all the scaffolding around that specific element that you want to print (the ion-router, ion-page, and all the ancestors)
If you did that then you could put all your items you want to print into a div with an id of printSection or what you prefer, and then the javascript that is responsible for that page you can create your own print function. In my example i will use angular, if you are not using that then preform whatever DOM selecting you need to to get the native html out of your template.
#Component({ ... })
export class Page {
// select the item holding your print content by `#property` you gave it
#ViewChild('printSection', { read: ElementRef }) printSection: ElementRef;
...
customPrint() {
const printContent = this.printSection.nativeElement;
const WindowPrt = window.open('', '', 'left=0,top=0,width=900,height=900,toolbar=0,scrollbars=0,status=0');
WindowPrt.document.write(printContent.innerHTML); // pass in the native html you got
/**
* you should probably use an observable instead of an interval for this,
* but this is just to illustrate a bug where the print would be fired before
* all the content was written
*/
const interval = setInterval(
() => {
if (document.readyState === 'complete') {
WindowPrt.document.close();
WindowPrt.focus();
WindowPrt.print();
clearInterval(interval);
}
},
200);
}
}
I Solved it following this process
First, remove the content to be printed from ion-content. Use a div instead of ion-content(shadow-dom is implemented with ion-content which blocks your CSS classes)
You also need to force the CSS below on ion-page when printing (it is initially set to position: absolute, by default)
In my case I was printing from a modal component which has a default class "show-modal". I was able to print on multiple pages by target that class this way
#media print {
.ion-page {
left: 0;
right: 0;
top: 0;
bottom: 0;
display: block;
position: relative;
flex-direction: column;
justify-content: space-between;
contain: none;
overflow: visible;
z-index: 0;
}
.scroll-content,
ion-modal.show-modal,
ion-modal.show-modal .modal-wrapper,
ion-modal.show-modal .ion-page.show-modal,
ion-modal.show-modal .ion-page.show-modal > ion-content,
.ion-page.show-modal,
.ion-page.show-modal > ion-content,
ion-tab,
ion-tabs,
.app-root,
body {
contain: none;
position: relative !important;
height: auto;
overflow: visible;
}
}
I'm also trying to solve this same issue. I've scoured the Internet, and tried many an idea, but none has worked so far.
Perhaps we could solve this collaboratively. I'd put this as a comment, but I don't have enough rating points, so the system will not let me.
This is what I've found so far. In Chrome Developer Tools, you can click on a settings icon, then scroll to "Rendering," and on "Emulate CSS media type," select "print."
When I do that, it shows what the print view is. I created a separate css file, let's call it print.css, and in it, there is
#media print {
/* add your css styles for print here */
}
I know my print.css is being processed because I've
display: none
for ion-header and some tabs at the bottom, and they do disappear when I select "print" emulation in Chrome.
What is interesting is, I'm seeing the whole page -- scrollable and all -- on the screen in this print mode. However, every time I try to print it, only one page shows up.
That page, however, doesn't always start at the top. It includes the current viewport.
Which is why, I'm wondering if there is something in the css that is trying to keep the whole thing as a page. i.e., preventing a page break?
I'm experimenting with things like this:
ion-content, .foo, .bar, ion-list, ion-tabs, ion-item {
break-inside : auto !important;
break-after : auto !important;
break-before : auto !important;
}
(where foo and bar are classes you might have of your own.)
This above one breaks things. Removing ion-tabs, ion-list, and ion-item shows the full page.
I'm also experimenting with the following. None has worked so far, but that is probably because I haven't selected the right tag or class.
display: block !important;
height: 100%;
overflow-y: visible !important;
max-height: unset !important;
contain: none;
You may want to experiment with the tag in question that might be preventing a page break. Some people are suggesting it's flexbox or grid that's the root cause. I'd love to know how to find the root cause.
Good luck! If something works, let us know, so I'll also try it in my code.
I was able to change color of comment content with
atom-text-editor::shadow .comment {
color: #E4F4FD;
}
But the color of comment marker stayed unchanged:
How do I change the color of comment marker?
If you place your cursor immediately to the left of the character you want to style and then press Ctrl-Alt-Shift-P all of the scopes for that character will be displayed in an information box:
You can then incorporate this into your stylesheet as you have with the body of the comment:
atom-text-editor::shadow {
.comment {
color: #E4F4FD;
}
.punctuation.definition.comment {
color: #E4F4FD;
}
}
Because it is LESS, it is possible to nest classes which will make your style sheet much cleaner.
Using ATOM version 1.58.0 on Windows 10, I get a depreciation warning. The short version is:
Starting from Atom v1.13.0, the contents of atom-text-editor elements are no longer encapsulated within a shadow DOM boundary. This means you should stop using :host and ::shadow pseudo-selectors, and prepend all your syntax selectors with syntax--.
I had to use:
// Change the color of the comments
atom-text-editor .syntax--comment{ color:#9DA5B3; }
atom-text-editor .syntax--punctuation.syntax--definition.syntax--comment{ color:#9DA5B3; }
I use fine DataTables for my website.
In a few rows it can happens that the string is very very long (e.g. 500 to 1000 chars).
How to cut that at 20 signs, add "..." and put that in a tooltip?
(of course I know substring and know how to add a tooltip, I just want to know if there is a feature / option for me on datatables or on which event I can get the data and cut it and add a tooltip to the cell)
I know that the question is already answered, but i would like to add this
datatable plugin as an option for this exactly problem. There's a very good explanation of how it works and how to use it in this blog post.
It's very simple to use, suppose that you need the text to get cut and only show 20 characters, you can use like this:
$("#yourTableSelector").dataTable({
... // other configurations
columnDefs: [{
targets: 0, // the target for this configuration, 0 it's the first column
render: $.fn.dataTable.render.ellipsis(20)
}]
});
Just to clarify, this plugins requires DataTables 1.10+
I don't know of a pure DataTables solution but this can be achieved by a setting fixed column width (via CSS or DataTables options) combined with text-overflow: ellipsis on your table cells.
For text-overflow to work you also need to specify a fixed width, set overflow: hidden and white-space: nowrap:
.limited{
white-space: nowrap;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
To see the full cell content add it to the cell's title attribute:
<td class='limited'
title='Very long cell content which is to long for the cell but shown as a tooltip'>
Very long cell content which is to long for the cell but shown as a tooltip
</td>
Which could look something like this:
See the MDN article on text-overflow for more details.
Another option would be using DataTables orthogonal data feature. In contrast to just using substring to limit the cell content, this would allow you to keep the complete cell content searchable:
<td data-search='Very long cell content which is to long for the cell but shown as a tooltip'
title='Very long cell content which is to long for the cell but shown as a tooltip'>
Very long cell content...
</td>
The output would be the same es above.
In some cases is common to use same values in different properties, for example (is just an example to show purpose) the following nested rule:
.button-link
{
height:40px;
a
{
line-height:40px;
}
}
The idea is that to vertically center button text line-height and height should be equal.
Is there a way in LESS to "assign a value taken from a diffent property"?
I know that I should use a LESS #variable but in this case is not the same thing and need extra code. Instead should very interesting and useful if I should edit only button's height and then LESS will replaced the same value to line-height
UPDATE:
Another example could be the following:
.button-link
{
color:white;
background:black;
&:hover
{
color:black;
background:white;
}
}
In which "hover" status should invert color and background-color comparing to default state.
This is possible starting with v3 of LESS! Here is the documentation on it.
The example use case they provide ends up with the background-color getting the same value as the color property when compiled:
.widget {
color: #efefef;
background-color: $color;
}
You can´t :(. What i usually do is:
#buttom-height = 100px;
#a-link-height: #buttom-height;
and use that variables in your less declarations. Its a dummy example, i know, but imagine calculated data values from other variables or complex dependencies, proportional paddings/margins... that´s the way i learnt from Bootstrap LESS code.
I've created a NestedList with some data inside .. everything works as expected. But there is one weird thing..
The last 2 characters of the title are always replaced with dots - I don't know why ...
Any explanations?
According to http://www.sencha.com/forum/showthread.php?228621-Short-titles-in-title-bar-also-gets-clipped-with-text-ellipsis it it fixed in 2.1.0-b2
As far as I judge it is CSS issue, because on the real device (iPhone test) no such quirks
Cheers, Oleg
This can be fixed with this solution, which only shows dots when necessary:
.x-title .x-innerhtml:after {
content: '';
display: inline-block;
width: .3em; /* equal to the amount of padding on the element */
}