Bootstrap print CSS removes background color - html

When I use bootstrap, it removes the background color from everthing when I try to print my page.
Almost everything on my website is using bootstrap classes so I want to avoid a lot of manual CSS outside bootstrap.
I've found out that bootstrap uses #media print to remove the background color. I'm using a bootstrap theme as well (theme united) which is removing the background color as well.
theme-united.css
#media print
*, *:before, *:after {
background: rgba(0, 0, 0, 0) !important;
color: rgb(0, 0, 0) !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
text-shadow: none !important;
bootstrap.min.css
#media print
*, :after, :before {
color: rgb(0, 0, 0)!important;
text-shadow: none!important;
background: 0 0!important;
-webkit-box-shadow: none!important;
box-shadow: none!important;
Is there a way to make sure that the background color is not removed when printing without editing these 2 CSS files?
For example:
When I use .alert-danger, I want that alert danger printed as it is displayed on screen, so would be printed as a red box.
See JSFiddle:
http://jsfiddle.net/7mtk7wrh/

Unfortunately there is not a good answer to your question - but maybe if you understand the why's then you can choose a way forward.
Why?
It's true that Bootstrap uses the #media print { * { color: $fff; background: transparent; }} -- but there is a very solid reason. This bit of code is actually derived from the normalizer.css project (by a then college of #mdo 's, #necolas) - it's intent is to make all browsers behave the same. These guys chose to "normalise" the css for a very good reason:
With most browsers one can choose to include or exclude background color, so the behaviour is not standard across even the same browser. Imagine for a sec a website with very dark background with white text - when printing with backgrounds off, it will look like you're printing nothing - when actually you're printing white text on no (white) background.
There was no way to account for all the different uses of color, so they choose to go black (font) and white (background, actually 'transparent'). Even the choice of black was well thought of -- its a better print solution, as most color printers have more black "ink/toner" (more economical) and they don't need to mix color to make black (so faster).
Remember that Bootstrap is also a "framework" - so a starting point if you will - and kudos to #mdo and #necolas for having the foresight to think of this in terms of establishing a predictable baseline. (No, I don't know them.)
Nope...
So the thinking here is: "what if we could 'go back' and unset this. Unfortunately CSS does not work like that - yes browsers load the CSS declarations in a "queue" where the last declaration wins (LIFO, or last-in-first-out), but I'm not aware of a way to remove this stack. So CSS developers just add more to the end...
So one would assume that we can go back that way --- add a * { background-color: inherit }. Problem is that inherit reverts to the parent property, but * is the root, so it has nothing to revert to. Same goes for initial!
Maybe!
So we're left with 4 options, none of them is what you where hoping for, but it is what it is. In order of difficulty:
Download the BS (less or sass) source, edit the offending code, and then compile it. (You need to use a local copy, CDN's will not work.)
Download the CSS variant of your choice, search and delete the offending code. (No CDN's again.)
Use getbootstrap.com/customize to create a new variant - exclude "Print media styles" under "Common CSS". (Again, no CDN's)
Override the specific items who's color you want to print: e.g.
#media print {
.alert-danger {
color: yellow !important;
background-color: red !important;
}
}
CDN's copies of BS will now work, but then you have the problem of the user possibly not printing backgrounds and having the output white (yellow in the e.g.) on white!
Finally
Well I hope learning the why's was at the very least a way of you thinking of a workaround. General rule of thumb I follow is that when printing, the background is (should be) always white. When constrained that way you start thinking of novel ideas, like exclamation icons around the text that only "print" (#media only screen { .hidden-screen { display: none; }})

Despite !important usage being generally frowned upon, this is the offending code in bootstrap.css
.table td,
.table th {
background-color: #fff !important;
}
Let's assume you are trying to style the following HTML:
<table class="table">
<tr class="highlighted">
<th>Name</th>
<th>School</th>
<th>Height</th>
<th>Weight</th>
</tr>
</table>
To override this CSS, place the following (more specific) rule in your stylesheet:
#media print {
table tr.highlighted > th {
background-color: rgba(247, 202, 24, 0.3) !important;
}
}
This works because the rule is more specific than the bootstrap default.

You can get this working by removing those lines from bootstrap.css file, there might be a jquery solution to this but it is much more complicated than erasing a few lines. :/
Or you could use a plugin called html2canvas as presented in this jsfiddle

I ended up here with the same problem but found the Chrome comes with a show background graphics option on the print dialog under more settings that did exactly that! No modification of Bootstrap (4) required.

#Vino explained really well. I was also facing problem because bootstrap.css makes background transparent forcefully. Thus I have customized the specific element in my custom CSS file. Remember to change <.element> with element where you want the colorful background instead of transparent.
#media print {
.element{
background-color: white !important;
box-shadow: inset 0 0 0 1000px #fff !important; /* workaround for IE 11*/
}
}

i had also face the same problem.. i just remove the bootstrap.min.css from my code then it work for me.

just make the specificity-value more specific and you should be ok.
something like:
#media print {
tbody>tr:nth-child(even)>td {
background-color: rgb(230, 216, 216) !important;
}
}

Actually, there is a solution, but this is still a hack.
It was used for a pdf generation in puppeteer, so it was tested only in this case, but most probably should work in all modern browsers.
Keep in mind that BOOTSTRAP_PRINT_RULE can be different in a different version of Bootstrap.
const BOOTSTRAP_PRINT_RULE = `#media print {
*, ::after, ::before { color: rgb(0, 0, 0) !important; text-shadow: none !important; background: 0px 0px !important; box-shadow: none !important; }
a, a:visited { text-decoration: underline; }
a[href]::after { content: " (" attr(href) ")"; }
abbr[title]::after { content: " (" attr(title) ")"; }
a[href^="javascript:"]::after, a[href^="#"]::after { content: ""; }
blockquote, pre { border: 1px solid rgb(153, 153, 153); break-inside: avoid; }
thead { display: table-header-group; }
img, tr { break-inside: avoid; }
img { max-width: 100% !important; }
h2, h3, p { orphans: 3; widows: 3; }
h2, h3 { break-after: avoid; }
.navbar { display: none; }
.btn > .caret, .dropup > .btn > .caret { border-top-color: rgb(0, 0, 0) !important; }
.label { border: 1px solid rgb(0, 0, 0); }
.table { border-collapse: collapse !important; }
.table td, .table th { background-color: rgb(255, 255, 255) !important; }
.table-bordered td, .table-bordered th { border: 1px solid rgb(221, 221, 221) !important; }
}`
for (const styleSheet of document.styleSheets) {
for (const [index, rule] of Array.from(styleSheet.cssRules).entries()) {
if (rule.cssText && rule.cssText.includes(BOOTSTRAP_PRINT_RULE)) {
styleSheet.deleteRule(index)
return;
}
}
}

Since version 4 of Bootstrap with SASS you can actually set the following variable to false which will turn of this behavior:
$enable-print-styles: false
If this is not an option, there is the following script which brutally rips out all #media print annotations from the CSS. It assumes that Bootstrap is the first style sheet loaded and that it runs after Bootstrap has loaded.
var style = document.styleSheets[0];
[].forEach.call(style.cssRules || [], function (aRule, aIndex) {
if (aRule.cssText.indexOf("#media print") >= 0) {
style.deleteRule(aIndex);
}
});

You can use this (https://developer.mozilla.org/fr/docs/Web/CSS/print-color-adjust)
.your-selector {
-webkit-print-color-adjust: exact;
}
Warning: This is not standart, but might help you.

Related

How do I change the selection color of a dropcap?

I ran into what appears to be a weird bug in chrome.
.dropcap {
font-size: 150%;
}
section p::first-letter {
font-size: 150%;
/*#apply dropcap*/
}
*::-moz-selection, .dropcap::-moz-selection {
background: #f7941d !important;
}
*::selection, .dropcap::selection {
background: #f7941d !important;
}
/* *::-moz-selection {
background: #f7941d !important;
}
*::selection {
background: #f7941d !important;
} */
<section>
<p>hello world</p>
</section>
I've tried adding !important and targeting all elements *, targeting the dropcap class, etc. My setup is with tailwind and jekyll, but this bug appears in plain HTML, CSS & JS.
I'm wondering how to change the selection color (other than individually adding a dropcap class to every single starting character in every paragraph on the website)
Some more examples of this bug:
Chrome:
Firefox:
Deleting lines 5-8 (styles applied to first-letter) in chrome:
The dropcap is still a larger font-size, but the selection color now works. I'm wondering why this is and if I can somehow style dropcaps without screwing up the selection color or adding a span with a class to every single first character of every single paragraph on every single page of the website.

Chrome input:-internal-autofill-selected property hides my background-image when autofilling

I want to show # and password icon in my login fields using a background-image property, inside my input[type="email"] and input[type="password"]. Using this CSS :
input.InputText--icon {
padding-left: 32px;
&[type="email"], &[type="email"]:-internal-autofill-selected {
background-image: url("/ressources/img/email.svg") !important;
}
&[type="password"], &[type="password"]:-internal-autofill-selected {
background-image: url("/ressources/img/password.svg") !important;
}
}
But if credentials are add using autofilling through Chrome, the following background-image: none !important; property overrides it and I lose my background.
// chrome user agent stylesheet
input:-internal-autofill-selected {
background-color: rgb(232, 240, 254) !important;
background-image: none !important;
color: -internal-light-dark-color(black, white) !important;
}
Do you have any hacky ideas to go through this problem, so that my background-images always shows up. Even if :-internal-autofill-selected event is triggered.
I have seen this idea of using a wrapper (https://stackoverflow.com/a/35573069/7647916 ). But is it possible to do it without using a wrapper ?
Thank you !

Remove input[range] inner line

I would like to remove the inner line of the range-input (HTML5 Video Control). Is there any way?
Have a Look!
If this is simply an HTML <video> element then you are going to be rather limited as to how you can handle styling it. The appearance of these elements will differ from browser to browser as seen below :
Firefox
Google Chrome
Internet Explorer
Edge
These styles are extremely difficult and sometimes impossible to override (especially in any kind of consistent fashion) as they rely on styles that are browser-specific as seen below:
audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline {
-webkit-appearance: media-slider;
display: flex;
height: 8px;
background-color: transparent;
min-width: 25px;
color: inherit;
flex: 1 1 auto;
margin: 0px 15px 0px 0px;
padding: 0px;
border: initial;
}
or specifically for the range section :
input[type="range" i] {
color: rgb(196, 196, 196);
}
You could try to use a style that would explicitly override it, but your success may vary :
input[type="range" i] {
/* Attempt to hide this */
color: transparent!important;
}
If you are looking for something like that, you would probably be better off using a Javascript-based like JPlayer or MediaElement.js

Can I force text to print as white?

Suppose I have some text which is displayed over an image or some other printable colours. Is it possible to force this text to white when printing? The default behaviour is to force white to black or grey in most browsers. This clearly makes sense when you are printing text in containers with background colours/images which are removed, but doesn't make sense to force the text in the case where you are overlaying text on images.
I should probably mention that I am quite aware of the print stylesheet, it just so happens that regardless of setting the font colour, in IE/chrome/firefox, the font does not appear white regardless. It ends up black or grey depending on the browser. Please show an example of white text over an image if you think it's actually possible.
To illustrate see:
http://jsfiddle.net/NSwYE/
I personally don't think it's possible due to the way printing works. It's pretty annoying none-the-less.
This is not entirely in control of the web page author.
For example, this fiddle will print (at least it did for me on a Dell 1720 Laser Printer) white text on any of the three black backgrounds in
IE9
if the user has checked the box found next to:
Tools -> Print -> Page Setup -> "Print Background Colors and Images"
If that box is unchecked, then it will not print the black at all on the first two, but will on the last (since it is an img tag), but it prints the text as a grey, even over the img tag. Thus, it seems that the setting for "Print Background Colors and Images" affects how the browser interprets the text, and will allow a true white (knock-out effect) if checked, but not if unchecked.
Firefox
Checkbox found here (which seems to work):
File -> Page Setup -> "Print Background (colors & images)"
For Chrome? Web Page Author Controlled?
I have not yet verified whether the information from this post will do it or not (it does not work for me on my next fiddle, but it may be because it is in an iframe). For elements that should print in Chrome, try setting:
-webkit-print-color-adjust: exact;
Marked answer is wrong. You can control text color in every browser! You just need to output text in svg. Browsers don't change color in svg. Here's an example:
<svg height="40" width="200">
<text font-size="28px" y="25" x="30" fill="#ffffff" >
Some text
</text>
</svg>
print.css will help you, Eric meyer have a post about it.
For example html5boilerplate using this style on his css:
#media print {
* { background: transparent !important; color: black !important; box-shadow:none !important; text-shadow: none !important; } /* Black prints faster: h5bp.com/s */
a, a:visited { text-decoration: underline; }
a[href]:after { content: " (" attr(href) ")"; }
abbr[title]:after { content: " (" attr(title) ")"; }
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
thead { display: table-header-group; } /* h5bp.com/t */
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
#page { margin: 0.5cm; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3 { page-break-after: avoid; }
}
Update:
With your example html:
<img src="http://www.clipart.dk.co.uk/DKImages/Halloween/image_halloween002.jpg" alt="black cat">
<div id="sometext">Cat</div>
and my css:
#sometext {
position: absolute;
top: 125px;
left: 220px;
color: #FFF;
}
#media only print {
#sometext {
color: #FFF !important;
/* actually trick with white text-shadow not work ( */
text-shadow: 0 0 3px #FFF !important;
}
}
​
I get this demo. Is this an acceptable solution?
​
Solution:
#media print {
h1 {
color: rgba(0, 0, 0, 0);
text-shadow: 0 0 0 #fff;
}
#media print and (-webkit-min-device-pixel-ratio:0) {
h1 {
color: #fff;
-webkit-print-color-adjust: exact;
}
}
}
The example http://jsfiddle.net/NSwYE/ prints white text on top of the cat for me. But I'm using Firefox 3.6 and a Brother laser printer.
The behaviour of printers is entirely dependent on the printer driver and the application. My printer will print the example correctly using Firefox. It will print grey-scale text from Microsoft Publisher correctly. It will not print grey-scale text in Microsoft Word: text is always black.
Probably, if you use a print specific stylesheet that styles it as such.
e.g.
<link href="print.css" rel="stylesheet" media="print" />
It might be a bit overkill, but if this is something you need repeatedly, you might consider generating the content using either canvas or SVG (Raphael.js will provide IE support). Both canvas and SVG/VML elements will print with exact colours in major browsers.
/* Text color */
.element
{
color:transparent;
text-shadow:0 0 0 #fff;
}
/* Background color */
.element
{
box-shadow:0 0 0 1000px #000 inset;
}
In Internet Explorer, you need to enable background printing. Tested in Chrome 70, Firefox 60 (with disabled background printing also works) and IE11.
It doesn't need to calculate SVG width because SVG is not used.
Try adding an !important attribute to the css for it to print correctly, eg "color: white !important"

Grey Font Color Printing

Is there any way to ensure that my grey font colors do not turn black?
Firefox and Chrome seem to do this in order to prevent white text on black background from turning into white on white. I do not have a background color (except white), so this browser-level conversion is not useful, it only helps in preventing grey colors for no reason.
Is there a way to turn this off? Or should I just stick with techniques like opacity, browser detection, and coloring my grays...
Solution:
#media print {
h1 {
color: rgba(0, 0, 0, 0);
text-shadow: 0 0 0 #ccc;
}
#media print and (-webkit-min-device-pixel-ratio:0) {
h1 {
color: #ccc;
-webkit-print-color-adjust: exact;
}
}
}
I found had to :
Add !important to the css rule... and...
In the Firefox print dialog, tick the option for "Appearance: Print background colors"
I couldn't get it to work in Chrome.
Some browsers add more respect to your gray if you add color: Replace #777 with #778. Be wary of opacity. Sometimes, even if the print preview will show great results, it only actually works on select printers. Printers with unlucky firmware will fail to print your text at all if it is gray using opacity.
You just need to output your grey font in svg. Browsers don't change color in svg. Here's an example:
<svg height="40" width="200">
<text font-size="28px" y="25" x="30" fill="#ffffff" >
Some text
</text>
</svg>
I thought that is the only div on that page. Make the following change, it should work fine.
<style>
#media print {
div.red {
color: #cccccc !important;
}
</style>
And change the html of the div tag like below
I found that TEXT color is not inherited by "general purpose" stylesheet, but must be forced again in print css file.
In other words, even if text color is set in the general css file (one with media='all' attribute), it is ignored when printed, at least in Firefox and Chrome.
I found that writing again (redundant but..... necessary) text color in print css file (one with media='print' attribute), color now will be considered.
This solution working in all browsers:
.text{
color: transparent;
text-shadow: 2px 0 #red;
}
Give importance to color:
.bgcol{
background-color:skyblue !important;
}
.subject_content,h2,p{
color:rgba(255, 255, 255) !important;
margin: 25px auto;
}
<body class="bgcol">
<div class="subject_content">
<h2 class='text-center'>fhddfhnt area</h2>
<p>sdgdfghdfhdfh.</p>
</div>
Nothing above was working for me so I finally figured it out.
Always give colors to direct elements. Ex. Suppose your html is
<div class='div'><br/>
< h1>Text< /h1><br/>
</div>
and your CSS
.div {
color: #ccc;
}
This was my case. In this case no matter what you do the color won't show.
You have to do
.div h1 {
color: #ccc;
}
#media print {
.div h1 {
-webkit-print-color-adjust: exact;
}
}
Hope this helps you!!
Please reply if you find a better solution as this is what I could find after 2 hrs and it works for me.