Viewport doesn't scale to center - php

I am using this on the site
<meta name="viewport" content="width=200px, initial-scale=0.5, user-scalable=no">
In my CSS file I have this for repositioning some elements
#media screen and (max-width: 767px) {
#wb_element_instance3{display: none}
#wb_element_instance11 {left: 280px}
#wb_element_instance12 {left: 570px}
#wb_element_instance13 {left: 655px}
#wb_element_instance14 {left: 705px}
}
And now my problem. When I access my website with my phone the stuff in "#media" works fine but the viewport scales a bit offset that to the center of the site.
So, is there a way to center it somehow?
Thank you very much!

You've given very little information to help solve the issue, but some general pointers apply.
1) Absolute positioning (using top/left etc.) is not a good idea, especially if you're coding with a view to centering on devices of multiple sizes.
2) You could cater better for different size devices by adding other media queries.
e.g. #media only screen and (min-width:480px) and (max-width:640px){
} or
#media only screen and (max-width:480px){/*your css here*/}
etc.
Centering can usually done by using the margin property or text-align. Bear in mind that some css can affect other css properties. If you are centering an image, assign it a width (in percentage) and then you could use margin: 0 auto or margin-left:auto; and margin-right:auto;
Example of (text-align) centering:
.wb_example{
text-align:center;
}
<body>
<p class="wb_example">Hello</p>
</body>

Related

Responsively show different background images on different screen sizes using attr()

The challenge is that from my CMS (let's say WordPress for arguments sake) I can get different crop sizes of a background image for the banner on my page. These crop sizes are generated for different screen sizes (based on mobile, tablet, laptop, etc).
I would like to be able to render all of the different crop size image URLs as attributes onto the banner DOM element and then in an external CSS document use media queries to pick the correct one to display. The reason I want to do this is that I can write the PHP to dynamically provide the cropped images on different pages.
Something like, HTML:
<div style="background-image:url('/img/sm-background-image.jpg')"
md-background-image="url('/img/md-background-image.jpg')"> ...
CSS:
#media (min-width: 768px) {
.background-image-style {
background-image: attr('md-background-image')!important; /* All screen sizes above the smallest and default size */
}
}
So, all screen width of 768px or bigger would display the image provided in md-background-image attribute and anything below this size would show the default background-image defined in the style attribute.
I can see that attr() is not supported for background-image currently and although there is some future scope for this, I can't use it now.
I achieved the desired affect by using a combination of the CSS var() method and style attribute.
My PHP code looks something like this:
<div class="banner-image" style="
--xl-background-image:url('<?php echo $image['sizes']['xl_header_banner_wide']; ?>');
--lg-background-image:url('<?php echo $image['sizes']['lg_header_banner_wide']; ?>');
--md-background-image:url('<?php echo $image['sizes']['md_header_banner_wide']; ?>');
background-image:url('<?php echo $image['sizes']['sm_header_banner_wide']; ?>')">
Which renders the HTML:
<div class="banner-image" style="
--xl-background-image:url('/wp-content/uploads/2019/02/Products-Header-1489x600.jpg');
--lg-background-image:url('/wp-content/uploads/2019/02/Products-Header-1400x564.jpg');
--md-background-image:url('/wp-content/uploads/2019/02/Products-Header-1024x413.jpg');
background-image:url('/wp-content/uploads/2019/02/Products-Header-768x309.jpg')">
I can therefore use the following CSS and media query combination to show the different images based on the client's screen size in my external style.css file:
#media (min-width: 768px){
.banner-image {
background-image: var(--md-background-image)!important;
}
}
#media (min-width: 992px){
.banner-image {
background-image: var(--lg-background-image)!important;
}
}
#media (min-width: 1200px){
.banner-image {
background-image: var(--xl-background-image)!important;
}
}
I've checked this on Chrome & FireFox (on Windows) and Safari (on Mac) with developer tools and I haven't noticed any comparability issue.
Alternative approach:
Alternatively, I realised as I was writing my above solution, that a less risky approach might be to render my styles directly into the page. I guess it's just a questions of compatibility and/or coding standards that separate the two possibilities.
<style type="text/css">
#media (min-width: 768px){
.banner-image {
background-image: '<?php echo $image['sizes']['md_header_banner_wide']; ?>'!important;
}
}
#media (min-width: 992px){
.banner-image {
background-image: url('<?php echo $image['sizes']['lg_header_banner_wide']; ?>')!important;
}
}
#media (min-width: 1200px){
.banner-image {
background-image: url('<?php echo $image['sizes']['xl_header_banner_wide']; ?>')!important;
}
}
</style>

Preloading Images working on Chrome, not Firefox or Safari [duplicate]

Every responsive website development tutorial recommends using the display:none CSS property to hide content from loading on mobile browsers so the website loads faster. Is it true? Does display:none not load the images or does it still load the content on mobile browser? Is there any way to prevent loading unnecessary content on mobile browsers?
Browsers are getting smarter. Today your browser (depending on the version) might skip the image loading if it can determine it's not useful.
The image has a display:none style but its size may be read by the script.
Chrome v68.0 does not load images if the parent is hidden.
You may check it there : http://jsfiddle.net/tnk3j08s/
You could also have checked it by looking at the "network" tab of your browser's developer tools.
Note that if the browser is on a small CPU computer, not having to render the image (and layout the page) will make the whole rendering operation faster but I doubt this is something that really makes sense today.
If you want to prevent the image from loading you may simply not add the IMG element to your document (or set the IMG src attribute to "data:" or "about:blank").
If you make the image a background-image of a div in CSS, when that div is set to "display: none", the image will not load. When CSS is disabled, it still will not load, because, well, CSS is disabled.
The answer is not as easy as a simple yes or no. Check out the results of a test I recently did:
In Chrome: All 8 screenshot-* images loaded (img 1)
In Firefox: Only the 1 screenshot-* image loaded that is currently being displayed (img 2)
So after digging further I found this, which explains how each browser handles loading img assets based on css display: none;
Excerpt from the blog post:
Chrome and Safari (WebKit): WebKit downloads the file every time except when a background is applied through a non-matching
media-query.
Firefox: Firefox won't download the image called with background image if the styles are hidden but they will still download assets
from img tags.
Opera: Like Firefox does, Opera won't load useless background-images.
Internet Explorer: IE, like WebKit will download background-images even if they have display: none;
Something odd appears with IE6 : Elements with a background-image and display: none set inline won't be downloaded... But they will be
if those styles aren't applied inline.
HTML5 <picture> tag will help you to resolve the right image source depending on the screen width
Apparently the browsers behaviour hasn't changed much over the past 5 years and many would still download the hidden images, even if there was a display: none property set on them.
Even though there's a media queries workaround, it could only be useful when the image was set as a background in the CSS.
While I was thinking that there's just a JS solution to the problem (lazy load, picturefill, etc.), it appeared that there's a nice pure HTML solution that comes out of the box with HTML5.
And that is the <picture> tag.
Here's how MDN describes it:
The HTML <picture> element is a container used to specify multiple <source> elements for a specific <img> contained in it. The browser will choose the most suitable source according to the current layout of the page (the constraints of the box the image will appear in) and the device it will be displayed on (e.g. a normal or hiDPI device.)
And here's how to use it:
<picture>
<source srcset="mdn-logo-wide.png" media="(min-width: 600px)">
<img src="mdn-logo-narrow.png" alt="MDN">
</picture>
The logic behind
The browser would load the source of the img tag, only if none of the media rules applies. When the <picture> element is not supported by the browser, it will again fallback to showing the img tag.
Normally you'd put the smallest image as the source of the <img> and thus not load the heavy images for larger screens. Vice versa, if a media rule applies, the source of the <img> will not be downloaded, instead it will download the url's contents of the corresponding <source> tag.
Only pitfall here is that if the element is not supported by the browser, it will only load the small image.
On the other hand in 2017 we ought to think and code in the mobile first approach.
And before someone got too exited, here's the current browser support for <picture>:
Desktop browsers
Mobile browsers
More about the browser support you can find on Can I use.
The good thing is that html5please's sentence is to use it with a fallback. And I personally intend to take their advise.
More about the tag you can find in the W3C's specification. There's a disclaimer there, which I find important to mention:
The picture element is somewhat different from the similar-looking video and audio elements. While all of them contain source elements, the source element’s src attribute has no meaning when the element is nested within a picture element, and the resource selection algorithm is different. As well, the picture element itself does not display anything; it merely provides a context for its contained img element that enables it to choose from multiple URLs.
So what it says is that it only helps you improve the performance when loading an image, by providing some context to it.
And you can still use some CSS magic in order to hide the image on small devices:
<style>
picture { display: none; }
#media (min-width: 600px) {
picture {
display: block;
}
}
</style>
<picture>
<source srcset="the-real-image-source" media="(min-width: 600px)">
<img src="a-1x1-pixel-image-that-will-be-hidden-in-the-css" alt="MDN">
</picture>
Thus the browser will not display the actual image and will only download the 1x1 pixel image (which can be cached if you use it more than once). Be aware, though, that if the <picture> tag is not supported by the browser, even on descktop screens the actual image won't be displayed (so you'll definitely need a polyfill backup there).
** 2019 Answer **
In a normal situation display:none doesn't prevent the image to be downloaded
/*will be downloaded*/
#element1 {
display: none;
background-image: url('https://picsum.photos/id/237/100');
}
But if an ancestor element has display:none then the descendant's images will not be downloaded
/* Markup */
<div id="father">
<div id="son"></div>
</div>
/* Styles */
#father {
display: none;
}
/* #son will not be downloaded because the #father div has display:none; */
#son {
background-image: url('https://picsum.photos/id/234/500');
}
Other situations that prevent the image to be downloaded:
1- The target element doesn't exist
/* never will be downloaded because the target element doesn't exist */
#element-dont-exist {
background-image: url('https://picsum.photos/id/240/400');
}
2- Two equal classes loading different images
/* The first image of #element2 will never be downloaded because the other #element2 class */
#element2 {
background-image: url('https://picsum.photos/id/238/200');
}
/* The second image of #element2 will be downloaded */
#element2 {
background-image: url('https://picsum.photos/id/239/300');
}
You can watch for yourself here: https://codepen.io/juanmamenendez15/pen/dLQPmX
It seems browsers still download images even though they are directly or indirectly hidden with display: none property.
The only standard way to prevent this from happening I found is using loading attribute of the img tag:
<img src="https://cdn.test/img.jpg" loading="lazy">
All latest browsers support it except Safari and Firefox Android.
MDN img loading attribute specification.
Yes it will render faster, slightly, only because it doesn't have to render the image and is one less element to sort on the screen.
If you don't want it loaded, leave a DIV empty where you can load html into it later containing an <img> tag.
Try using firebug or wireshark as I've mentioned before and you'll see that the files DO get transferred even if display:none is present.
Opera is the only browser which will not load the image if the display is set to none. Opera has now moved to webkit and will render all images even if their display is set to none.
Here is a testing page that will prove it:
http://www.quirksmode.org/css/displayimg.html
Quirks Mode: images and display: none
When image has display: none or is inside an element with
display:none, the browser may opt not to download the image until the display
is set to another value.
Only Opera downloads the image when you switch the display to block.
All other browsers download it immediately.
The background-image of a div element will load if the div is set do 'display:none'.
Anyway, if that same div has a parent and that parent is set to 'display:none', the background-image of the child element will not load. :)
Example using bootstrap:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="col-xs-12 visible-lg">
<div style="background-image: url('http://via.placeholder.com/300x300'); background-repeat:no-repeat; height: 300px;">lg</div>
</div>
<div class="col-xs-12 visible-md">
<div style="background-image: url('http://via.placeholder.com/200x200'); background-repeat:no-repeat; height: 200px;">md</div>
</div>
<div class="col-xs-12 visible-sm">
<div style="background-image: url('http://via.placeholder.com/100x100'); background-repeat:no-repeat; height: 100px">sm</div>
</div>
<div class="col-xs-12 visible-xs">
<div style="background-image: url('http://via.placeholder.com/50x50'); background-repeat:no-repeat; height: 50px">xs</div>
</div>
If you make the image a background-image of a div in CSS, when that div is set to 'display: none', the image will not load.
Just expanding on Brent's solution.
You can do the following for a pure CSS solution, it also makes the img box actually behave like an img box in a responsive design setting (that's what the transparent png is for), which is especially useful if your design uses responsive-dynamically-resizing images.
<img style="display: none; height: auto; width:100%; background-image:
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block
visible-lg-block" src="img/400x186_trans.png" alt="pic 1 mofo">
The image will only be loaded when the media query tied to visible-lg-block is triggered and display:none is changed to display:block. The transparent png is used to allow the browser to set appropriate height:width ratios for your <img> block (and thus the background-image) in a fluid design (height: auto; width: 100%).
1078/501 = ~2.15 (large screen)
400/186 = ~2.15 (small screen)
So you end up with something like the following, for 3 different viewports:
<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">
And only your default media viewport size images load during the initial load, then afterwards, depending on your viewport, images will dynamically load.
And no javascript!
If so is there a way to not load the unnecessary content on mobile
browsers?
use <img src="" srcset="">
http://www.webdesignerdepot.com/2015/08/the-state-of-responsive-images/
https://caniuse.com/#feat=srcset
To prevent fetching resources, use the <template> element of Web Components.
Use #media query CSS, basically we just release a project where we had an enormous image of a tree on desktop at the side but not showing in table/mobile screens. So prevent image from loading its quite easy
Here is a small snippet:
.tree {
background: none top left no-repeat;
}
#media only screen and (min-width: 1200px) {
.tree {
background: url(enormous-tree.png) top left no-repeat;
}
}
You can use the same CSS to show and hide with display/visibility/opacity but image was still loading, this was the most fail safe code we came up with.
Hi guys I was struggling with the same issue, how to not load an image on mobile.
But I figured out a good solution. First make an img tag and then load a blank svg in the src attribute. Now you can set your URL to the image as an inline style with content: url('link to your image');. Now wrap your img tag in a wrapper of your choice.
<div class="test">
<img src="data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/‌​svg%22/%3E" style="content:url('https://blog.prepscholar.com/hubfs/body_testinprogress.gif?t=1495225010554')">
</div>
#media only screen and (max-width: 800px) {
.test{
display: none;
}
}
Set the wrapper to display none on the breakpoint where you dont want to load the image. The inline css of the img tag is now ignored since the style of an element wrapped in a wrapper with display none will be ignored, therefore the image is not loaded, until you reach a breakpoint where the wrapper has display block.
There you go, really easy way not to load an img on mobile breakpoint :)
Check out this codepen, for a working example: http://codepen.io/fennefoss/pen/jmXjvo
No.The image will be loaded as usual and will still use the user’s bandwidth if you are considering the mobile phone user bandwidth saving.What u can do is to use media query and filter the devices that you want your image to be loaded.Your image must be set as a background image of a div,etc and NOT an tag since the the image tag will load the image regardless if the screen size and the media query set.
we're talking about images not loading on mobile, right? so what if you just did an #media (min-width: 400px){background-image:thing.jpg}
wouldn't it then only look for the image at above a certain screen width?
Another possibility is using a <noscript> tag and placing the image inside the <noscript> tag. Then use javascript to remove the noscript tag as you need the image. In this way you can load images on demand using progressive enhancement.
Use this polyfill I wrote to read the contents of <noscript> tags in IE8
https://github.com/jameswestgate/noscript-textcontent
The trick to using display:none with images is to assign them an id. This was there is not a lot of code needed to make it work. Here is an example using media queries and 3 stylesheets. One for phone, one for tablet, and one for desktop. I have 3 images, image of a phone, a tablet, and a desktop. On a phone screen only an image of the phone will display, a tablet will display only the tablet image, a desktop displays on the desktop computer image.
Here is a code example to make it work:
Source code:
<div id="content">
<img id="phone" src="images/phone.png" />
<img id="tablet" src="images/tablet.png" />
<img id="desktop" src="images/desktop.png" />
</div>
The phone CSS which doesn't need a media query. Its the img#phone that makes it work:
img#phone {
display: block;
margin: 6em auto 0 auto;
width: 70%;
}
img#tablet {display: none;}
img#desktop {display: none;}
The tablet css:
#media only screen and (min-width: 641px) {
img#phone {display: none;}
img#tablet {
display: block;
margin: 6em auto 0 auto;
width: 70%;
}
}
And the desktop css:
#media only screen and (min-width: 1141px) {
img#tablet {display: none;}
img#desktop {
display: block;
margin: 6em auto 0 auto;
width: 80%;
}
}
Good luck and let me know how it works for you.

CSS adaptive title element not full width

I have a fairly simplistic website that I have setup for a phone, tablet, and desktop. Using media queries to format the CSS accordingly. Challenge is the site is PHP based, dynamic, and doesn't use the full width of the screen. Page has two tables, side by side, left justified, each 500px in width. So my desktop for instance is 1388px wide. Centering the title makes it off center from the middle of the two tables. So I added:
.centering {width:1020px; padding-top:5px; border:0; margin-top:2px; text-align: center; font-size: 1.6em; font-family: Sans-serif; font-weight:bold;}
to the paragraph tag for the title on the top of the page. OK great, I just hard coded the placement. Have a .centering for each media query with various widths as the table widths vary per device. So it works, have one for desktop, one for the iPad landscape, one for iPad portrait (portrait tables adjust one on top, one underneath), various iPhone versions and some general ones. On the iPad landscape and desktop there is one problem.
I mentioned it was PHP and dynamic. A user can pass along in the PHP URL, that they do not want to see the second table. (ex. http://www.myurl.com/test.php?showsecond=0). Well that's great, however now I have one table of 500 pixels, and a title centered based on a width of 1020px. But the width is now only 500px. I tried loading various styles dynamically based on what was set, but for some reason when I load a style from file, as opposed to being in the physical page, it had some weirdness. Like extra space between two lines of text. Anyway, is there any suggestions how to deal with this title? Is there an element like a div or something I can place around the entire page, that will determine the current page width (based on content), and the title centered will automatically fit into it correctly without having to hard code width information for it? Especially with the dynamic changing width of a page even in the same orientation on the same device?
Here's some addition imagery as I guess I'm being told I write to much. On the desktop I have a webpagge with two pictures:
IF THE WEBSITE LET ME POST PICTURES, YOU WOULD SEE A LEFT JUSTIFIED TWO TABLES WITH A LOT OF WHITE SPACE ON THE RIGHT OF THE BROWSER WINDOW.
When the PHP is set thru the URL to not display the second table I get:
IF THE WEBSITE LET ME POST PICTURES, YOU WOULD SEE A LEFT JUSTIFIED SINGLE TABLES WITH A LOT MORE WHITE SPACE ON THE RIGHT OF THE BROWSER WINDOW.
As you would have seen, the title doesn't recenter based on the smaller content and the page doesn't use the full screen with so don't want it to center by "page width".
Here is my media query to do the initial center
<code><pre>
#media only screen and (min-width : 1224px)
{
th { font-size: 1.6em; font-family:Sans-serif; }
td { font-size: 1.65em; line-height: 1em; font-family:Sans-serif;}
h1 { font-size: 1.75em; line-height: 1.5em; }
h2 { font-size: 1.25em; }
table { width: 500px; align: left; }
.centering {width:1020px; padding-top:5px;
border:0; margin-top:2px; text-align: center;
font-size: 1.6em; font-family: Sans-serif;
font-weight:bold;}
}
</code></pre>
And my PHP to output the title:
echo "<p class='centering'>Pool Mining: " . strtoupper($obj['multiport']['mining']) . "</center></p>";
ThoughTs?
Thanks.
Set the style as:
<h1 style="text-align: center;">You title</h1>
If you think that browser fails to center your text then check your tables to be centered, if not check you glasses ;)

Calculate height of banner based on width

I have a banner slider that I am forcing 100% width. The problem is that when it loads, the first slide does not show (on chrome at least), I have to wait for the second slide to 'slide' in..then everything pushes down and looks as it should. If I set a fixed height it works fine, but my resolution is 1900 and different resolution screens would look bad with one locked in height.
I was wondering if there is a way I could calculate the visitors resolution and the banner dimensions to figure out the appropriate height based on the 100% width on load.
The beta url is http://www.can-do.org/beta/
(again, I think it works ok with IE, I only see it in Chrome/firefox)
Change your banner size using CSS code:
#media only screen and (max-width: 480px) {
#your_baner_image_id {width:000px;height:000px;}
}
#media only screen and (min-width: 480px) and (max-width: 768px) {
#your_baner_image_id {width:000px;height:000px;}
}
#media only screen and (min-width: 768px) and (max-width: 959px) {
#your_baner_image_id {width:000px;height:000px;}
}
#media only screen and (min-width: 959px) {
#your_baner_image_id {width:000px;height:000px;}
}
It might be possible to do this with CSS alone. The problem with #media rules is that you'd need one for each pixel width, which isn't viable. So you could try this instead:
Firstly, change the wrapper div here:
<div align="center">
to this
<div class="pluswrap">
Then, add these styles to your CSS file:
.pluswrap {
text-align: center;
padding-bottom: 30%;
height: 0;
position: relative;
}
The slideshow height is always 30% of the width, so the 30% bottom padding is set to keep the container div open to that dimension at any screen size.
(I can't really text this properly remotely, but it's worth a try. It did seem to work, but I can't refresh the page and see what happen on page load, because the temporary styles get wiped. Would be keen to know if it worked, though.)
Since you are using Jquery, you can get user Resolution by:
$(window).width();
$(window).height();
example:
$(function(){
var w = $(window).width();
$('your-banner').css('height',w*30%);//<--this will set banner height 30% of screen width
});

Print Canvas wrap with 3D perspective preview

I am looking for something that would allow me to render an uploaded image with a 3D perspective and a wrap effect like here.
This will be in the form of a cropping preview using a jQuery library such as jCrop
Currently I was able to achieve the 3D perspective using Reflex.js but looking for a more subtle solution with the wrapping effect as well.
Any help will be appreciated :)
Thanks in advance!
Your requirement of IE9 support basically mandates a canvas approach if you want to keep it client-side. You could of course do the rendering server-side and AJAX load the rendered image back in which will work in every browser.
If you decide that you can dump IE versions less than 10 (or at least just show them the normal photo without the transform then you can do the wrap-around effect with a combination of CSS 3D Transforms and CSS2 clip. Something like:
<!DOCTYPE html>
<style>
body { margin: 100px; position: relative; }
.edge { width: 20px; height: 196px; background-size: auto 100%; position: absolute; left: 30px; top: 2px; transform: perspective(600px) rotateY(-45deg); transform-origin: right; }
.panel { position: absolute; left: 31px; top: 0; clip: rect(auto,auto,auto,20px); }
.panel>img { width: 350px; height: 200px; transform: perspective(600px) rotateY(30deg); transform-origin: left; }
</style>
<div class="edge" style="background-image: url(my_image.jpg)"></div>
<div class="panel"><img src="my_image.jpg" /></div>
To break that down, we’ve loaded the user’s image and dropped it into the page, along with a div with the same image set as a background. That div is set to be a thin width and a height that’s almost as tall as the main image. We can use the background-size property to foce the background image to fit the div even if it’s taller.
We then absolutely position those two so that they’re next to each-other. The CSS2 clip property lets us clip off the left 20px of the image so that at this point the div and img look like one image together.
Finally, we set a perspective and transform-origin for each block and rotate them away from each-other around the Y axis. Because of the clipping we have to fudge the .edge block to be slightly smaller than originally (with a 200px tall image I had to drop it to 196px to look good) but that works pretty nicely for me.
Obviously you’d need to fill in the vendor prefixes (-moz-, -ms-, -o-, -webkit) and I’ll leave the shadow as an exercise for the reader (a simple background on the container would probably do).

Categories