I have the UIWebView object that loads html-pages. Html-page has zoom function via js.
function setViewPortWidth(width) {
var metatags = document.getElementsByTagName('meta');
for(cnt = 0; cnt < metatags.length; cnt++) {
var element = metatags[cnt];
if(element.getAttribute('name') == 'viewport') {
element.setAttribute('content','width = '+width+'; minimum-scale = 0.1;
maximum-scale = 1.7%; user-scalable = yes');
document.body.style['max-width'] = '10px'+width;
}
}
}
I need decrease font size if my app runs on iPhone. How to do that with saving zoom function? If I do that via css #media queries
#media screen and (min-width : 480px) {
body { font-size: 25pt; }
}
font will looks great, but when I zoom in and zoom back it will be bigger than needed 25pt.
Problem solved by using standard zoom function instead js zoom.
1 px ≠ 1 pixel
CSS pixels are not device pixels
go and watch this tutorial its help to you
http://adcdownload.apple.com//wwdc_2012/wwdc_2012_session_pdfs/session_602__delivering_web_content_on_high_resolution_displays.pdf
Related
I'm working on a simulation of the famous Prague astronomical clock. It's only partially done, but the work-in-progress can be seen here: https://shetline.com/orloj/
The page layout consists of an SVG image of the clock, plus a control panel for setting date, time, longitude, and latitude. The clock needs to expand to fill available space. The control panel is close to a fixed size, but can shrink a bit for smaller displays.
What I want (and I think should be MUCH easier to do) is for the contents of the web page to display nicely and neatly like this:
The tricky thing has been getting the layout to use available space well, but without needing to be scrolled, and without any components being clipped or hidden. What was especially difficult was automatically sizing things regardless of whether "chrome" (i.e. address and navigation bars) was being displayed or not.
Simple solutions only worked partially for me -- the user might have to pinch and scroll to get things right, manually hide toolbars, forcibly refresh after changing from landscape to portrait orientation, etc.
These are the difficulties I ran into:
With mobile browsers like Safari, 100vh was taller than window.innerHeight, so if I scaled using vh units, parts of what I wanted to display would be cut off until the user manually hid the toolbars. In desktop browsers, however, 100vh and window.innerHeight were always in sync.
Orientation changes weren't consistently reported. Safari didn't generate any resize events when the orientation of my phone was changed, only now-deprecated orientationchanged events. On one Android tablet I experimented with, orientation changes produced no browser events at all that I was aware of at all.
When the orientation changed, window.screen.width and window.screen.height weren't swapped as I would have expected... unless I was using the Chrome console responsive layout test.
After receiving resize or orientationchanged events, some of the values I needed to check like window.innerHeight weren't "settled" yet, so I needed to use setTimeouts to recheck if values changed over time.
When a user manually zooms into the display, the zoom state is sort of "sticky" and can keep the layout from returning to the preferred state after orientation changes.
All of this meant coming up with a bunch of ad hoc hackery to get the results I wanted. But this seems like such a basic result kind of layout effect to want to get, I can't help but wondering if I've made this much harder than it should be, and there isn't a much easier solution that I'm missing.
Here's the code I used to solve this layout:
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
:root {
--mfh: 100vh; // mobile full height
--mvh: 1vh; // mobile vh-like unit
}
html {
height: 100%;
margin: 0;
overflow: hidden;
width: 100%;
}
body {
background-color: #4d4d4d;
font: 14px sans-serif;
height: var(--mfh);
left: 0;
margin: 0;
position: absolute;
top: 0;
width: 100vw;
}
// Get scrolling, zooming, and panning back if display is very small:
#media screen and (orientation:landscape) and (max-height: 340px),
screen and (orientation:landscape) and (max-width: 630px),
screen and (orientation:portrait) and (max-width: 360px),
screen and (orientation:portrait) and (max-height: 740px)
{
html {
overflow: auto;
}
body {
position: static;
}
}
const docElem = document.documentElement;
const doResize = (): void => {
setTimeout(() => {
const height = window.innerHeight;
const disallowScroll = docElem.style.overflow === 'hidden';
docElem.style.setProperty('--mfh', height + 'px');
docElem.style.setProperty('--mvh', (height * 0.01) + 'px');
if (this.lastHeight !== height) {
this.lastHeight = height;
if (disallowScroll && (docElem.scrollTop !== 0 || docElem.scrollLeft !== 0)) {
docElem.scrollTo(0, 0);
setTimeout(doResize, 50);
}
else
this.updateGlobe();
}
});
};
let lastW = window.innerWidth;
let lastH = window.innerHeight;
const poll = (): void => {
const w = window.innerWidth;
const h = window.innerHeight;
const disallowScroll = docElem.style.overflow === 'hidden';
if (lastW !== w || lastH !== h || (disallowScroll && (docElem.scrollTop !== 0 || docElem.scrollLeft !== 0))) {
lastW = w;
lastH = h;
doResize();
}
setTimeout(poll, 100);
};
poll();
doResize();
Full code is here: https://github.com/kshetline/prague-clock
I am working on a freelancing project and I need to get this part done no matter what.
For screen resolutions lower than 1200px, I have used "rem" for font-size and changed the HTML font-size by using:
curr_size = parseInt($("html").css("font-size"));
curr_size = (curr_size * 100) /16;
if(curr_size < 72.5) {
curr_size += 2.5;
$('html').css('font-size', ''+curr_size+'%');
}
Coming to screen resolution > 1200px, I have converted everything to vw to support all browser zoom levels and big monitors.
All my font-size class starts with "fz-" and I am using this function below to change the font-size of all elements:
var elements = document.querySelectorAll("[class*=fz-]");
for (var index = 0; index < elements.length; index++) {
var cursize = parseInt($(elements).eq(index).css("font-size"));
cursize = (cursize/15);
var add = cursize + 0.05;
$(elements).eq(index).css("font-size","calc("+add+"vw");
}
This is working perfectly on 100% browser zoom, but when zoomed out and applied (or if the browser was by default at 50%), the text sizes in increasing humongously.
Any solutions that come to mind?
N.B: I need to keep support for VW, and for browser zoom on all levels.
I am working on a fade-in/out-effect-on-scroll on a web project.
On my js I have to set a certain value for the scroll position i. e. the offset to make the effect kick in.
The problem:
The offset value cannot be applied to all kinds of devices due to
different heights.
Questions (hierarchic):
How to make the static values dynamic and variable to the device
height/media queries?
How can you generally slim down the code?
How can I trigger an additional slide-slightly-from-right/left to the
effect?
Here is the code:
// ---### FOUNDATION FRAMEWORK ###---
$(document).foundation()
// ---### FADE FX ###---
// ## SECTION-01: fade out on scroll ##
$(window).scroll(function(){
// fade out content a
$(".j-fadeOut").css("opacity", 1 - $(window).scrollTop() / 470);// 470 should be variable
// ## SECTION-02: fade in/out on scroll bottom ##
var offset = $('.j-fadeOut-2').offset().top;
console.log('offset: '+offset);
console.log('window: '+$(window).scrollTop())
if($(window).scrollTop() > offset)
{
// fade out top part of content b
$(".j-fadeOut-2").css("opacity", 1-($(window).scrollTop() - offset)/520);// 520 should be variable
// fade in bottom part of content c
$(".j-fadeIn").css("opacity", 0 + ($(window).scrollTop() - offset)/ 1100);// 1100 should be variable
}
});
See here for JavaScript Media Queries
You can use window.matchMedia to perform media queries in JavaScript. Example:
var mediaQuery = window.matchMedia( "(min-width: 800px)" );
The result will be stored as a boolean in mediaQuery.matches, i.e.
if (mediaQuery.matches) {
// window width is at least 800px
} else {
// window width is less than 800px
}
You can use multiple of these to suit your different device widths. Using the standard Bootstrap buckets:
var sizes = ['1200px', '992px', '768px', '480px']; // standard Bootstrap breakpoints
var fadeOutAs = [470, 500, 530, 560]; // this corresponds to your content a fadeout variable. Modify as required per screen size
var fadeOutBs = [520, 530, 540, 550]; // content B fadeout
var fadeOutCs = [1100, 1200, 1300, 1400]; // content C fadeout
var fadeOutA = 0;
var fadeOutB = 0;
var fadeOutC = 0;
for (i = 0; i < sizes.length; i++) {
var mediaQuery = window.matchMedia( "(min-width: " + sizes[i] + ")" );
if (mediaQuery.matches) {
fadeOutA = fadeOutAs[i];
fadeOutB = fadeOutBs[i];
fadeOutC = fadeOutCs[i];
}
}
Hope this helps
The problem
I'm using javascript to calculate widths of elements to achieve the layout I'm after. The problem is, I don't want to load the code on smaller screen sizes (when the screen width is less than 480px for example). I'd like this to work on load and on browser/viewport resize.
I'd consider small screen devices 'the default' and working up from there. So, none of the following script is called by default, then if the browser width is greater than 480px (for example), the following script would be called:
The code
$(document).ready(function() {
//Get the figures width
var figure_width = $(".project-index figure").css("width").replace("px", "");
//Get num figures
var num_figures = $(".project-index figure").length;
//Work out how manay figures per row
var num_row_figures = Math.ceil(num_figures / 2);
//Get the total width
var row_width = figure_width * num_row_figures;
//Set container width to half the total
$(".project-index").width(row_width);
x = null;
y = null;
$(".project-index div").mousedown(function(e) {
x = e.clientX;
y = e.clientY;
});
$(".project-index div").mouseup(function(e) {
if (x == e.clientX && y == e.clientY) {
//alert($(this).next().attr("href"));
window.location.assign($(this).next().attr("href"));
}
x = y = null;
});
});
// Drag-on content
jQuery(document).ready(function() {
jQuery('#main').dragOn();
});
The extra bit
The slight difference on larger screens is to do with the browser/viewport height. This is in regards to the line:
var num_row_figures = Math.ceil(num_figures / 2);
You can see once the calculation has a value, it divides it by 2. I only want this to happen when the browser/viewport height is above a certain amount - say 600px.
I'd be happy with this being the 1st state and then the value is divided by 2 if the height is greater than 600px if it's easier.
Can anyone help me/shed some light on how to manage my script this way. I know there's media queries for managing CSS but I can't seem to find any resources for how to manage javascript this way - hope someone can help.
Cheers,
Steve
You can use window.matchMedia, which is the javascript equivalent of media queries. The matchMedia call creates a mediaQueryList object. We can query the mediaQueryList object matches property to get the state, and attach an event handler using mediaQueryList.addListener to track changes.
I've added an example on fiddle of using matchMedia on load and on resize. Change the bottom left pane height and width (using the borders), and see the states of the two queries.
This is the code I've used:
<div>Min width 400: <span id="minWidth400"></span></div>
<div>Min height 600: <span id="minHeight600"></span></div>
var matchMinWidth400 = window.matchMedia("(min-width: 400px)"); // create a MediaQueryList
var matchMinHeight600 = window.matchMedia("(min-height: 600px)"); // create a MediaQueryList
var minWidth400Status = document.getElementById('minWidth400');
var minHeight600Status = document.getElementById('minHeight600');
function updateMinWidth400(state) {
minWidth400Status.innerText = state;
}
function updateMinHeight600(state) {
minHeight600Status.innerText = state;
}
updateMinWidth400(matchMinWidth400.matches); // check match on load
updateMinHeight600(matchMinHeight600.matches); // check match on load
matchMinWidth400.addListener(function(MediaQueryListEvent) { // check match on resize
updateMinWidth400(MediaQueryListEvent.matches);
});
matchMinHeight600.addListener(function(MediaQueryListEvent) { // check match on resize
updateMinHeight600(MediaQueryListEvent.matches);
});
#media screen and (max-width: 300px) {
body {
background-color: lightblue;
}
}
So i searched a bit and came up with this example from w3 schools .http://www.w3schools.com/cssref/tryit.asp?filename=trycss3_media_example1
i think this is something you are trying to achieve.
For pure js , you can get the screen width by screen.width
How do I auto-detect a screen resolution and change browser zoom with Javascript?
I was thinking of something more like this:
I've got the following code:
#warp with width: 3300% and a mask with width: 100%; and then, each .item has width: 3.030303% — with overflow hidden, otherwise it couldn't work as I want.
My point is: I've done this for at least 1280px wide screens.
What I want is if someone can write code that I could use toswitch the CSS file once viewed on a <1280px screen — them, I could do something like:
.item img { width: 80%; } and then, the result would be the same as "browser zoom out".
If you mean change the native browser zoom triggered by CTRL +/- then this isn't possible. You can adjust CSS properties/apply stylesheets but you cannot affect native browser controls. There are in fact CSS only options here depending on your target audience (and their browser choice) through the use of media queries, a couple of examples here and here. If these are not suitable then you can do various things with JavaScript to detect screen width/height and adjust accordingly.
Auto-detect a screen resolution
See this SO question
change browser zoom with javascript
This is not possible. See this SO question.
This will help to detect browser zoom tested on all browser
<script>
window.utility = function(utility){
utility.screen = {
rtime : new Date(1, 1, 2000, 12,00,00),
timeout : false,
delta : 200
};
utility.getBrowser = function(){
var $b = $.browser;
$.extend(utility.screen,$.browser);
utility.screen.isZoomed = false;
var screen = utility.screen;
screen.zoomf = screen.zoom = 1;
screen.width = window.screen.width;
screen.height = window.screen.height;
if($b.mozilla){ //FOR MOZILLA
screen.isZoomed = window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;
} else {
if($b.chrome){ //FOR CHROME
screen.zoom = (window.outerWidth - 8) / window.innerWidth;
screen.isZoomed = (screen.zoom < .98 || screen.zoom > 1.02)
} else if($b.msie){//FOR IE7,IE8,IE9
var _screen = document.frames.screen;
screen.zoom = ((((_screen.deviceXDPI / _screen.systemXDPI) * 100 + 0.9).toFixed())/100);
screen.isZoomed = (screen.zoom < .98 || screen.zoom > 1.02);
if(screen.isZoomed) screen.zoomf = screen.zoom;
screen.width = window.screen.width*screen.zoomf;
screen.height = window.screen.height*screen.zoomf;
}
}
return utility.screen;
};
window.onresize = function(e){
utility.screen.rtime = new Date();
if (utility.screen.timeout === false) {
utility.screen.timeout = true;
setTimeout(window.resizeend, utility.screen.delta);
}
};
window.resizeend = function() {
if (new Date() - utility.screen.rtime < utility.screen.delta) {
setTimeout(window.resizeend, utility.screen.delta);
} else {
utility.screen.timeout = false;
utility.screen = utility.getBrowser();
if(window.onresizeend) window.onresizeend (utility.screen);
if(utility.onResize) utility.onResize(utility.screen);
}
};
window.onresizeend = function(screen){
if(screen.isZoomed)
$('body').text('zoom is not 100%');
else{
$('body').text('zoom is 100% & browser resolution is'+[screen.width+'X'+screen.height]);
}
};
$(document).ready(function(){
window.onresize();
});
return utility;
}({});
</script>
Demo
RE: Auto-detect a screen resolution and change browser zoom with Javascript?
The question is perfectly possible and is in effect at our website here:
www.noteswithwings.com
JS detects the screen width and zooms out or in a little to fit the content on to the screen.
Further, if the user resizes the window the zoom is triggered.
This actually helps fit content on to tablet sized screens and screens as small as the iphone without adding extra stylesheets or having to detect an OS/ Browser..
var oldZoom = $(window).width();
var windowWidth = $(window).width();
check_window_size(windowWidth,1,bsr,bsr_ver);
$(window).resize(function() {
var windowWidthnow = $(window).width();
check_window_size(windowWidthnow,2,bsr,bsr_ver);
});
function check_window_size(size,init_var,bsr,bsr_ver)
{
/* Develop for resizing page to avoid grey border!
Page layout 1265px wide.
On page resize shift layout to keep central, zoom BG-img to fill screen
Zoom content down for smaller screens by 5% to keep content flow!
*/
//change this var for screen width to work with, in this case our site is built at 1265
var wdth = 1265;
//Change this variable for minimum screen;
var smallest_width=1120;
var varZoom= $(window).width()/wdth;
var s_size = $(window).width();
var scale_smaller;
var center = (s_size-wdth)/2;
var its_ie=false;
if(size<=smallest_width)
{
$("#old_browser").css("width","50%").css({"height":"40px","left": center+"px"});
if(!check_for_object(false,"moved_pages"))
{
if(center<-110)//margin width!
{
if(!its_ie)
$("#scroller").css("zoom",0.95);
$("#footer").css("zoom",0.9).css("left",120+"px");
$(".colmask").css("left",-110+"px");
if(check_for_object(false,"move_menu_loggedin"))
$("#move_menu_loggedin").css("right","110px");
if(check_for_object(false,"login_div"))
$("#login_div").css("left","-80px");
return;
}
$("#move_menu_loggedin").css("left","-"+center+"px");
$("#scroll").css("zoom","normal");
$(".colmask").css("left",center+"px");
}
else
{
/*Only pages that you do not want to move the colmask for!*/
$("#scroller").css("zoom",0.90);//.css("left","-50px");;
$("#footer").css("zoom","normal");
}
}
else
{
if(size>wdth)
$("#background").css("zoom",varZoom);
$("#scroller").css("zoom","normal");
$("#footer").css({"zoom":"normal","left":0});
if(!check_for_object(false,"moved_pages"))
{
$(".colmask").css("left",center+"px");
$(".colmask").css("zoom","normal");
var movelog = -center;
if(check_for_object(false,"move_menu_loggedin"))
$("#move_menu_loggedin").css("right",movelog +"px");
if(check_for_object(false,"login_div"))
$("#login_div").css("left","80px");
}
else
{
$(".colmask").css("zoom","normal");
}
}
}
-- check_window_size(windowWidth,1,bsr,bsr_ver); bsr & bsr_ver are detected using a php class.
-- #old_browser is a div containing information if you have an old web browser.
-- #background is a fixed image 100x100% of the screen.
As you can see we also move a few items which were not in the containing div scope.
Colmask is the containing div for most of the pages content (For us that sits underneath the header which is why we move some items manually)
Hope the code snippet can help someone else achieve this.