I am using Zurb Foundation 6.3.0 and have come across the following issue. The reveal modal receives the following inline styles when opened both in chrome both in desktop and in responsive mode.
element.style {
display: block;
top: 0px;
left: 0px;
margin: 0px;
}
However if I open the website using remote debugging for my android device the inline styles are set as the following.
element.style {
display: block;
top: 60px;
left: 0px;
margin: 0px;
}
This causes the modal to move 60px further down than it should and display the content behind the modal. What would be causing the inline styles to be set differently on android device?
This is a result of the calculation done by foundation.reveal.js:
var height = this.$element.outerHeight();
var outerHeight = $(window).height();
if (this.options.vOffset === 'auto') {
if (height > outerHeight) {
top = parseInt(Math.min(100, outerHeight / 10), 10);
} else {
top = parseInt((outerHeight - height) / 4, 10);
}
}
If the element height is greater than the window height, it sets the top property for the element to be 1/10th of the window height. If the element height is not greater than the element height then the top value is set to 1/4th of the difference between the window height and the element height.
In this case the height of the element is calculated as being greater than the window height (even though it should be set as 100vh). Therefore the position of the element is being set as ~ 1/10th of the window height.
This issue is also address in this answer: CSS3 100vh not constant in mobile browser.
In order to prevent the modal element to have a top value of greater than 0 is to add the attribute `data-v-offset="0"' to the element like this:
<div class="full reveal" data-reveal data-v-offset="0">
<!-- content -->
</div>
This forces the value of the top property to be 0 as the calculations done in the foundation.reveal.js _updatePosition function are not made if the data-v-offset is set to 0.
This and other plugin options are covered further in the Zurb Foundation docs.
Related
I have a webpage that consists of three panels: header, main and footer. In my .css file, I have successfully adjusted my webpage to fill 100% of the screen's vertical height using "100vh".
.EventHeader {
height: 60px;
}
.EventMain {
height: calc(100vh - 140px);
text-align: left;
overflow-y: auto;
}
.EventFooter {
height: 80px;
}
While this works great with most mobile devices, I'm finding that in iOS Safari their address bar and tabs play havoc to the actual display. If the address bar and tabs are visible, the webpage fills more than 100% of the screen. However, once these two items disappear the webpage takes up 100% of the vertical height as desired.
For example, if vertical height is 720px, then in all mobile devices except iOS Safari, these are the heights of the panels (i.e. in aggregate takes up exactly 100% of the vertical height but not more than 100%):
EventHeader: 60px
EventMain: 580px which is 720 - 60 - 80
EventFooter: 80px
"vh" property reads 720px
When the page origianlly renders in iOS Safari and the address bar and tabs are visible (which take up roughly 44px), these are the heights of the panels (i.e. in aggregate takes up 764px which is 44px more than 100% of the vertical height):
EventHeader: 60px
EventMain: 624px which is 720px - 60px - 80px + 44px
EventFooter: 80px
"vh" property reads 764px
But once the address bar and tabs have disappeared (roughly 15 seconds later), these are the heights of the panels (i.e. in aggregate takes up exactly 100% of the vertical height but not more than 100%):
EventHeader: 60px
EventMain: 580px which is 720 - 60 - 80
EventFooter: 80px
"vh" property reads 720px
So while the actual vertical height of the window is always 720px, the vertical height is somehow modified based of the visibility of the address bar and tabs in iOS Safari.
Unless I'm completely mistaken, this cannot be fixed using flexbox or other similar approaches. Rather, it is a specific issue with iOS where the height.inner property of the window changes based on the visibility of the address bar and tabs. And, this attribute is what is recorded in the "vh" property in css.
I have searched around and found that the best solution is in the following article:
https://github.com/alvarotrigo/fullPage.js/issues/2414
var height = window.innerHeight;
var a = setInterval(function() {
$(window).scrollTop(-1);
resize();
}, 500); // Don't lower more than 500ms, otherwise there will be animation-problems with the Safari toolbar
$(window).on('resize', function() {
resize();
});
var resize = function() {
if(window.innerHeight != height) {
height = window.innerHeight;
$('.section').css('height', height + 'px');
}
};
However, it is in jQuery and I am having problems converting it to pure JS and using it in a React program.
I understand the basic process:
set the css "height" parameter to "innerHeight"
after a defined period of time, assume that the address bar and tabs have disappeared
treat this disappearance as a window resizing
on a window resizing, reassign the "height" parameter to "innerHeight"
Also, how would I send this "height" parameter and its assigned value back to my .css file?
Do I instead need to use inline styling?
Any help would be appreciated. Thanks.
I have responsive navigation menu and item blocks. Item blocks automatically adjusts their width as screen resolution changes(this is great). But navigation menu is in different section of page markup and don't receive the same width values as item blocks.
My goal: When resolution changes - script checks width of item block and then changes width of navigation menu to the same value.
So far I have:
$(document).ready(function(){
$( window ).resize(function() {
Resized();
});
});
function Resized()
{
var block_width= $(".block_item").width();
var width_to_set = parseInt(block_width);
$(".header-navi-inner").css({
'width': (width_to_set + 'px')
});
};
When I resize I can see that script executes and navigation menu changes width, but the width is not exactly the same as item block has. It is very close but it is wider for about 1px-5px based on what resolution is set.
For example:
When I looked in to CSS of these elements I found that item block has such styling:
float: left;
border-radius: 2px;
margin: 2px .25%;
position: relative;
width: 49.5%;
line-height: 0.8;
I believe margin .25% is causing issues because margin percentage value is calculated based on parent node. So when resolution changes parent node changes its size and also margin. That is why 1-5px difference occurs to my script?!
Is it true? How can I get exact width of element without any other added pixels?
What I have also tried:
$(".item").innerWidth();
$(".item").outerWidth(true);
But results were the same.
What I have also tried 2 (UPDATE):
I also tried to calculate margin value and then subtract it from width_to_set value:
var parent_node = $(".twelve").width();
var margin= (main_slaider * 0.0025);
var width_to_set = parseInt(column_width) - margin;
But still navigation menu was wider than item blocks for 1-3px
Thanks in advance for any help.
Code
Demo
The basic form of HTML looks like this:
<div class="home">
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<!-- blah, blah, blah! -->
</main>
</div>
</div>
W.r.t the HTML, I am trying to make the element #main fill the entire height of the browser viewport using JavaScript/jQuery like so:
jQuery(document).ready(function($){
// get height of browser viewport
var window_h = $(window).height();
// get height of the jumbotron, i.e. element #main
var jumbotron_h = $('.home #main').outerHeight(true);
// calculate necessary padding (top/bottom) to apply on #main so that the
// element's height is equal to that of the browser's viewport,
// and its contents are centered vertically
if (window_h > (jumbotron_h + 60)) {
var jumbotron_padding = (window_h - jumbotron_h)/2
} else {
var jumbotron_padding = 30
}
// apply calculated padding on the element dynamically
$('.home #main').attr('style', 'padding-top:'+jumbotron_padding+'px;padding-bottom:'+jumbotron_padding+'px;');
});
As clearly explained in the comments in the code above, the code automatically calculates the necessary padding to be applied on #main so that its height is equal to that of the browser's viewport.
It works well, except, the calculated padding (and therefore the resultant height) is wrong in one case that I was able to identify.
Easily reproducible at least on Windows 7, Google Chrome browser (latest) when you resize the browser window to 567x724 px, which implies 551x611 px viewport size, (you can use an extension like Window Resizer), you'll notice that the element's calculated padding results in its height being larger than that of the browser's viewport.
Why is this happening? I wasn't able to reproduce the same at any other resolution. What could I possibly be missing here?
First off, Jquery's .outerheight() function includes padding, which means that when you measure the height of your #Main element after this function runs the first time, it will equal the window.height. In other words - it will look awful when you resize your browser. You can see this in action on this fiddle when you resize the browser window the old-fashioned way. You can use margins instead, but then you'll have to adjust your CSS quite a bit. Even then, resizing the window still looks awful and buggy and has inconsistent results across browsers. You can see that on this fiddle.
The specific bug you're referring to is probably due to inconsistent math when you resize your window - a combination of your use of padding (which is included in .outerheight() as mentioned above) and the viewport size not being easily divisible by 2 (it's impossible to have half a pixel and different browsers will render that half a pixel differently).
I should also point out this line of code:
if (window_h > (jumbotron_h + 60)) {
var jumbotron_padding = (window_h - jumbotron_h)/2
} else {
var jumbotron_padding = 30
}
This forces your page to always be #main.height() + 60, which can be bigger than your viewable window, depending upon your window size. #main.height() comes out to around 200.5px (there we are with another half pixel).
Assuming that your goal is to vertically center the #Main element, your best bet is to use one of the many straight CSS methods available. The table method seems most applicable here because it is completely dynamic (and thus can be responsive) - simply create a single cell CSS table, use CSS valign, and build your entire page inside that cell. For older versions of IE you'll need to use a tiny hack (display:Inline-block;) to make it work.
HTML:
<div id="parent">
<div id="child">Content here</div>
</div>
CSS:
#parent {display: table;}
#child {
display: table-cell;
vertical-align: middle;
}
IE fix:
#child {
display: inline-block;
}
Based on #Thomas's answer, I've identified two possible solutions. I am going with the #2 solution considering better browser support for it.
1. Using the unit vh (viewport height). Browser support: IE9 and above.
CSS:
.home #primary { /* Parent */
display: table;
width: 100%;
}
.home #main { /* Child */
display: table-cell;
height: 100vh; /* 100% viewport height */
vertical-align: middle;
}
2. Dynamically setting height of parent (.home #primary) equal to that of browser's viewport.
JS:
jQuery(document).ready(function($){
var window_h = $(window).height();
var jumbotron_h = $('.home #main').height();
if (window_h <= (jumbotron_h + 60)) {
var window_h = jumbotron_h + 60
}
$('.home #primary').attr('style', 'height:'+window_h+'px;');
});
CSS:
.home #primary { /* Parent */
display: table;
width: 100%;
}
.home #main { /* Child */
display: table-cell;
height: 100%; /* 100% height of parent */
vertical-align: middle;
}
body {
height:100vh;
}
.element-to-be-centered {
font-size:1em;
text-align:center;
top: 49%;
-webkit-transform: translateY(-49%);
-ms-transform: translateY(-49%);
transform: translateY(-49%);
}
I have been doing quite a bit of experimenting lately with centering content. This technique will work without having to set a height on any element.
This will work in ie9 and up.
In your CSS
html, body {
height: 100%;
}
div, #main {
height: 100%;
}
I'm trying to use this plugin Galleria in its responsive mode, which basically means it will re draw itself based on its container size as the window re-sizes. The demo on the link I've provided shows a really good example. You can see that, as you resize your window, the whole gallery adjusts accordingly. Now my issue is, the plugin won't let me initialize the gallery unless a height has been specified for the DOM element that is used as its container. This means, I've had to write a whole lot of javascript code to respond window resizes - it destroys the point of it having a responsive mode quite a bit - but in the website above, nowhere can I find an explicit height specified. Can someone explain to me where I'm going wrong?
I figured it out by myself. Posting my answer -
When initializing the gallery - specify your height in percentages - as below. I'm guessing it takes 50% of window height as its value in this case. This way, you don't need to explicitly specify heights anywhere and it works as advertised
Galleria.run('#gallery', {responsive:true, height:0.5, debug:false});
Galleria needs a height to initialise correctly. You can do this either via CSS or JS.
If you would like it to fill the width and height of the screen, I would recommend setting a width and height of 100% via CSS. And its parent container needs to be 100%. See below.
**JS:**
Galleria.run('#galleria', {
responsive:true,
showCounter:true,
thumbnails:false,
trueFullscreen:true,
});
**CSS:**
#galleria{
width:100%;
height: 100%;
position: fixed;
z-index: 9999;
top:0px;
bottom: 0px;
}
body,html{
height:100%;
width:100%;
}
The height option ( if it's < 2.0) is relative to the width of the container. So height:0.5 would have a height that is half the width of the container (w=2, h=1).
height:1.5 would result in (w=2, h=3)
To keep it responsive you can use max-width rather than width when styling the container.
If the height option is set to 2.0 or more, it is interpreted as pixels. So height:2.0 will only be 2px tall.
Im not getting my form element to position horizontaly in the center here is my code
$('.form')
.css('top', window.screen.availHeight / 2 - $('.form').height() / 2)
First, make sure it's position: absolute; as #Douglas points out. Past that, you're fetching the screen height, as in the entire monitor, not the browser window. Instead of window.screen.availHeight, you likely just want $(window).height(), like this:
$('.form').css('top', $(window).height() / 2 - $('.form').height() / 2);
You can test it out here.
Setting the top property with css won't affect the horizontal position of the element.
Setting top (or left for horizontal positioning) will not have an effect if the position of the element is set to static, which is the default.
Try position absolute instead:
.form {
position: absolute;
top: 100px;
}