Images not displaying when Print Preview (Or Print) in IE/Chrome/Firefox - css

I'm Web Developer and almost never work with design but have been given this bug which I'm struggling to rectify.
Some images appear correctly when I print/display the print preview page, however others don't. The key difference that I can see is that the images that don't appear are span tags with the image applied in css whilst the working images use the img tag.
Here are examples of the html:
Span with "icon" birth does not display:
<li class="media">
<div class="img">
<div class="h2 mtm">1889</div>
<span class="timeline-icon icon-birth"></span>
</div>
<div class="bd">
<h3 class="profile-subtitle mts">Born in ?</h3>
<p class="deemphasis mbn">
Search for Birth Record
</p>
</div>
</li>
Image.gif does display:
<li class="media">
<div class="img">
<div class="h6">
<strong>Spouse</strong></div>
<img src="image.gif" alt="" class="person-thumb dropshadow" />
</div>
<div class="bd">
<p class="mbn">Husband</p>
<h3 class="profile-subtitle">
Thomas <strong>Name</strong>
</h3>
<p class="mbn">?-?</p>
</div>
</li>
In some browsers it looks ok in the preview but does not print, in others it doesn't and still does not print.
Thankyou in advance!

I had the same problem over two months ago. I had a button that redirected users to a printer-friendly page and then I triggered print dialog using Javascript.
The problem was that browsers did not wait till images specified in CSS background were downloaded.
I put timeout before triggering the print dialog to give browser time to download images. This approach is not reliable since nobody has constant download speed and it would open the print dialog before the images are downloaded to users with very slow Internet connection.
In the end, I used HTML img tags to embed images on my page and jQuery to trigger the print dialog when the last image is downloaded.

You need to put delay before print. There is a native bug in chrome. Code would as under :-
function PrintDiv(data) {
var mywindow = window.open();
var is_chrome = Boolean(mywindow.chrome);
mywindow.document.write(data);
if (is_chrome) {
setTimeout(function() { // wait until all resources loaded
mywindow.document.close(); // necessary for IE >= 10
mywindow.focus(); // necessary for IE >= 10
mywindow.print(); // change window to winPrint
mywindow.close(); // change window to winPrint
}, 250);
} else {
mywindow.document.close(); // necessary for IE >= 10
mywindow.focus(); // necessary for IE >= 10
mywindow.print();
mywindow.close();
}
return true;
}

Just add the below styles to make it work img{max-width:100%;height:auto;}
Its the width of the image being set to 0 in the print which is causing the issue.

make a print stylesheet, set your span to display:block

Related

How can I render contentful images dynamically in my gatsby portfolio website

I have been struggling to render images from contentful in my gatsby site. I have used gatsby-plugin-image to render the image from contentful. I cannot dynamically render the images. please help me.
I import
import { GatsbyImage, getImage } from "gatsby-plugin-image"
my graphQL query is.
const data = useStaticQuery(graphql`
query {
allContentfulBooks(sort: { bookTitle: ASC }) {
edges {
node {
bookTitle
author
date(formatString: "MMMM Do, YYYY")
type
bookCover {
gatsbyImageData(
width: 300
placeholder: NONE
quality: 75
layout: CONSTRAINED
)
}
slug
summary
}
}
}
contentfulBookHeading {
heading
mainText {
raw
}
}
}
`)
I try to render the book Cover here
<ol>
{data.allContentfulBooks.edges.map((edge) => {
const image = getImage(edge.node.bookCover.gatsbyImageData)
return (
<li className={bookStyles.books}>
<div className={bookStyles.bookThumbnail}>
<div className={bookStyles.bookCover}>
<GatsbyImage src={image} alt="Book Cover" />
</div>
<div>
<Link to={`/book/${edge.node.slug}`}>
<h3 className={bookStyles.title}>{edge.node.bookTitle}</h3>
</Link>
<h5 className={bookStyles.author}>
Author: {edge.node.author}
</h5>
<h6 className={bookStyles.type}>Type: {edge.node.type}</h6>
<p className={bookStyles.date}>Date Read: {edge.node.date}</p>
<p className={bookStyles.summary}> {edge.node.summary}</p>
<Link to={`/book/${edge.node.slug}`}>
<p className={bookStyles.fullnotes}>Read full book notes</p>
</Link>
</div>
</div>
<hr />
</li>
)
})}
</ol>
I tried to render the book cover image from contentful. but it's not working
My first thought when reading your ask was that you are looking to load data dynamically, as in at load time, my original answer would work for that. After rereading your question, I believe you are not having difficulty loading data dynamically at load time but, rather you are not seeing the images display using the useStaticQuery and loading the data at build time.
Steps to ensure you should see the media:
open http://localhost:8000/___graphql in a browser and run your query, ensure you see the media you are expecting.
If you do not see the media:
First, check Contentful and ensure that the media is published.
Next, try stopping your app and restarting it, ctrl c should cancel the running command, then start the site back up. This will ensure that you content is pulled in and ready to render.
If you see the media in graphical, my next suggestion is to debug your site and console.log the data. Try putting in console logs
console.log("gatsbyImageData", edge.node.bookCover.gatsbyImageData)
const image = getImage(edge.node.bookCover.gatsbyImageData)
console.log("image", image)
next open up the developer menu in your browser and click on console
reload the page and verify the output of the console logs. This should help you ensure that data is present.
If you are having a dynamic rendering issue the answer is, useStaticQuery, grabs all of your Contentful data at build time. This is by design and is part of why Gatsby is so fast. You will need to use something like Apollo in order to grab dynamic data in Gatsby. Check out this article that provides more details and a possible solution.

angularjs delay route change upon click as long new background image does not load

My web app shows body background for a second then it loads the dynamic background when i route from one page to another. I am trying to remove that white flash by adding a splash screen using AngularJS. I looked at some tutorials but were not able to find exact solution.
how do i avoid showing the white body background before my div background loads?
any suggestions?
HTML
<body class="hold-transition skin-blue sidebar-mini sidebar-collapse">
<div class="wrapper" ng-style="{'background': backgroundImg}" >
<div class="content-wrapper">
<section class="content">
<div ng-view></div>
</section>
</div>
</body>
my route
$routeProvider.when('/about',{
templateUrl:'partials/about.php',
controller: 'pageController'
});
My controller
app.controller("pageController",function($scope, $rootScope){
$scope.title = "About Us";
$rootScope.backgroundImg="url('http://abounde.com/uploads/images/abt-min.jpg')"; //abt bg
$scope.$on('$viewContentLoaded', function() {
console.log("about page loaded");
});
});
From what I understand, the pb is that when you route to another page then you launch a new request to download your background with your url(...). Because this request can take time then you have your white screen.
So a solution could be to "preload" all background images when you open your app. So before displaying anything on your app you can display a "loading..." div. In background download all your backgrounds.
Once this is done, when changing route then simply change the css class of your wrapper div to the css class containing the correct background image.
On this particular page, you could have a div that wraps the entire document.
Give this div a class with css ie .document-wrapper-invisible
in your css give .display-none class a display property of none
.dislay-none {
display: none;
}
When your view content loaded function runs, remove this class. You can simply set a variable to be true and use ng-class to conditionally remove the class. ie
<div ng-class="{display-none: !documentLoaded}">
// your page content
</div>
in your controller
$rootScope.$on('$viewContentLoaded', function() {
console.log("about page loaded");
$scope.documentLoaded = true;
});
Something along these lines should work (I've only ever used rootScope for the viewContentLoaded event, if $scope works on it's own then great)

'Mobile first' image loading for Wordpress sider

All the image slider plugins I have used so far for Wordpress sites have had no way, as far as I could tell, to swap out different sized images at various screen sizes to enable an 'mobile first' experience.
For example: http://www.akqa.com/
They have changed which image is displayed depending on certain breakpoints and it allows control over which part of the image is displayed.
If there is no plugin to automate this, could it at least be achieved through CSS alone?
Thank you
You can do this by HTML picture tag or Jquery .data()
Jquery Example
orignalImg = $(".test").attr("src"); // get orignal image
mobileImg = $(".test").data("mobile"); // get mobile image
brakpoint = 768; //what ever your brakpoint
//do magic
function changeImg() {
$(".test").each(function() {
if ($(window).width() <= brakpoint) {
$(this).attr("src", mobileImg);
}else {
$(this).attr("src", orignalImg);
}
});
}
// call magic
changeImg();
//change image if viewport change
$(window).on('resize', function() {
changeImg()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Resize your window </h1>
<img class="test" src="http://placehold.it/600x300" data-mobile="http://placehold.it/300x600">
HTML Example
<picture>
<source srcset="http://placehold.it/600x300" media="(min-width:768px)">
<img src="http://placehold.it/300x600" alt="img">
</picture>
In your example link they are also using this <picture> tag. This is a simple solution but might be you will face browser compatibility issue

Prevent Bootstrap from preloading all the hidden-* images

I'm running Twitter Bootstrap 3.2.
My page has a banner image for every breakpoint. That means code like this:
<img class="visible-xs img-responsive" src="headline-768px.jpg"> (128kb)
<img class="visible-sm img-responsive" src="headline-992px.jpg"> (144kb)
<img class="visible-md img-responsive" src="headline-1200px.jpg"> (264kb)
<img class="visible-lg img-responsive" src="headline-2000px.jpg"> (380kb)
The main purpose of having 4 different images is so that mobile devices don't need to download the larger versions. But Bootstrap preloads all the versions regardless of screen size, even if they're hidden at the current breakpoint. This amounts to hundreds of unnecessary kb for every viewer.
Is there a way around this?
Demo of the Problem:
Not all browsers react the same, but typically browser's will load content from a src attribute, regardless of whether some other CSS rule renders that element as invisible.
Here's a baseline example:
<img class="visible-xs img-responsive" src="http://placehold.it/768x150" />
<img class="visible-sm img-responsive" src="http://placehold.it/992x150" />
<img class="visible-md img-responsive" src="http://placehold.it/1200x150"/>
<img class="visible-lg img-responsive" src="http://placehold.it/2000x150"/>
Demo in jsFiddle
Whenever I refresh the page, the browser loads all images, even ones that are initially invisible:
Background Image + Media Queries
This tutorial on Simple Responsive Images With CSS Background Images goes into more depth, but the basic solution works like this:
Create a simple div:
<div class="responsiveBackgroundImage" id="myImage" ></div>
And then sub in the correct background image depending on the screen size:
We'll probably want all the background images to share a couple basic properties like this:
.responsiveBackgroundImage {
width:100%;
background-size: 100%;
background-position: 50% 0%;
background-repeat: no-repeat;
}
Then replace the background-image property for this particular element at each resolution:
#myImage {background-image: url(http://placehold.it/768x150); }
#media (min-width: 768px) { #myImage { background-image: url(http://placehold.it/992x150); }}
#media (min-width: 992px) { #myImage { background-image: url(http://placehold.it/1200x150);}}
#media (min-width: 1200px) { #myImage { background-image: url(http://placehold.it/2000x150);}}
Demo in jsFiddle
Replacing Images with Javascript
Due to limitations with using background images, you might decide to use a real img element and then just dynamically load the images. Rather than loading the element itself, you can do something similar to what angular does with ng-src when evaluating an expression that resolves to a url. When the browser loads each element, it wouldn't be able to find the file location of src="{{personImageUrl}}". Instead, Angular saves the intended url as a data attribute and then loads when appropriate.
First, take each of your images and prefix the src attribute with data-. Now the browser won't automatically start implementing anything, but we still have the information to work with.
<img class="visible-xs img-responsive" data-src="http://placehold.it/768x150"/>
Then query for all the dynamic images we'll eventually want to load.
$dynamicImages = $("[data-src]");
Next, we're going to want to capture window resize events, and on the very first page load, we'll trigger one just so we can make use of the same code. Use a function like this:
$(window).resize(function() {
// Code Goes Here
}).resize();
Then check if each dynamic image is visible. If so, load the image from the data attribute and remove it from the array so we don't have to keep checking and loading it.
$dynamicImages.each(function(index) {
if ($(this).css('display') !== 'none') {
this.src = $(this).data('src');
$dynamicImages.splice(index, 1)
}
});
Demo in jsFiddle
it is not bootstrap, but the browser. You should use background images (instead of <img> tags) together with media queries.
A proper browser will load only the css background image matching the media query, but it makes sense for it to load all images in the markup regardless of their css styling
(Necessary pain until <picture> will be widely supported)
I did it with jQuery in the end.
HTML:
<div id="billboard">
</div>
Javascript:
$(document).ready(function(){
var viewportWidth = $(window).width();
var adaptiveBillboard = function($showTheRightSizeBilboard){
if(viewportWidth<641){
$('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/ISYNyCw.png">');
}else if(viewportWidth<721){
$('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/OQeEwOq.png">');
}else if(viewportWidth<769){
$('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/3WqOdgo.png">');
}else if(viewportWidth<993){
$('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/KpNKYLq.png">');
}else if(viewportWidth<1201){
$('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/F00kkbv.png">');
}else{
$('#billboard a').html('<img class="img-responsive" src="http//i.imgur.com/FK5ZMoo.png">');
};
};
//try things once on pageload
$(adaptiveBillboard);
//try things again on every viewport resize
$(window).resize(function(){
viewportWidth = $(window).width();
setTimeout(adaptiveBillboard,100);
});
});
I have used (in combination with bootstrap hidden-xs):
$dynamicLoadImages = $("img.hidden-xs[data-src]");
$(window).resize(function(index) {
for (var i = 0; i < $dynamicLoadImages.length; i++) {
el = $dynamicLoadImages[i];
if ($(el).css('display') !== 'none') {
el.src = $(el).data('src');
$dynamicLoadImages.splice(i, 1);
i--;
}
};
}).resize();
The current top solution works only for every odd element because of the splice method modifying the underlying object and then skipping the next element.

bootstrap fixed header when scrolling down

I am working within bootstrap's core admin structure and have a main header at the top of the page and then a sub header beneath it. I am trying to allow that sub header to fix to the top of the page when the user scrolls down so they can always see that information, but I am having a bit of trouble.
The section I would like to stick to the top looks like this.
<div class="area-top clearfix" >
<div class="pull-left header">
<h3 class="title"><i class="icon-group"></i>Dashbord</h3>
</div><!--.header-->
<ul class="inline pull-right sparkline-box">
<li class="sparkline-row">
<h4 class="blue"><span> Cover Designs</span> 4</h5>
</li>
<li class="sparkline-row">
<h4 class="green"><span> Video Trailers</span> 5</h5>
</li>
<li class="sparkline-row">
<h4 class="purple"><span> Web Banners</span> 5</h5>
</li>
</ul>
</div><!--.area-top-->
and I have tried so far to wrap that in another div with the navbar navbar-fixed-top classes. But that shot it to the top right away and overlapped content that needs to be seen.
I have also tried using plain css by adding position:fixed; to the current div, but that messes up the breadcrubms I have laying underneath it because it takes it out of the flow.
Is there anyway to accomplish this with just css. I know I can do a hack with jquery, but in my team I am only in charge of the css.
you can use below css to the sub header navbar.
css:
.sticky-top {
position: -webkit-sticky;
position: sticky;
top: 0;
z-index: 1020;
}
Add 'sticky-top' class to sub header.
for eg: you can see the fiddle below which is similar to the question.Here second menu fixed to top when user scrolls.
https://jsfiddle.net/raj_mutant/awknd20r/6/
position:fixed is the way to go here. Can you apply a height to the div you want to be fixed and apply a margin to the breadcrumbs?
.area-top{ position:fixed; height:2em; }
.breadcrumbs { margin-top: 2.2em; }
My point of view is the following. When you ask for this :
to fix to the top of the page when the user scrolls down
It means that you need to detect when users are scrolling. Furthermore, there is no other way than js / jQuery to detect this kind of action. CSS can be a part of solution by creating a class for exemple which will stick your menu, but you'll always need a bit of js to detect when to put and to remove the class.
Here is an exemple on how to do this in jQuery :
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script type="text/javascript">
$(window).scroll(function(){
var offset = $('.area-top').offset().top;
var top = $(document).scrollTop();
if(top >= offset){
// this is where you should fix you menu
$('.area-top').addClass('fixed'); // if you have a css class which fix the element.
$('.area-top').css('position', 'fixed'); // if you don't have css class
}else{
// this is where you should unfix your menu
$('.area-top').removeClass('fixed'); // if you have a css class which fix the element.
$('.area-top').css('position', 'inherit'); // if you don't have css class
}
});
</script>
Don't forget that every "advanced" action which need to detect a change in the DOM or which need an user interaction will require some JS or PHP to deal with it. By "advanced", i'm meaning all the things that can't be natively handle in HTML.

Resources