jQuery Tabs Content Overflow + heightStyle and refresh break tabs - css

I am using jQuery-UI Tabs vertically at my site and was having no issues until I started loading content in the tab panels and found that the parent tab panel div does not grow with the content, e.g. tab "Static Info". I can "fix" the issue by setting the parent div class CSS to overflow: auto, which then creates a vertical scrollbar on the parent div. However, I would really prefer if the parent div would just grow with the child content. I did try a couple of clearfix options, including:
$( ".tabs" ).tabs().addClass( "ui-helper-clearfix" );
when intializing the document, but none of the clearfixes made any difference. As I was seeking solutions, I did try adjusting the heightStyle and tab refresh to see if either of those would make a difference. What I found was that this did nothing:
$( ".tabs" ).tabs({ heightStyle: "fill" }); I also tried "content" and "auto" with also no luck.
However, when I tried the alternative as documented at api.jquery.com/tabs:
var heightStyle = $( ".tabs" ).tabs( "option", "heightStyle" );
$( ".selector" ).tabs( "option", "heightStyle", "fill" );
the tabs layout completely broke. The content was all there, but the ul list was at the top of the page with no tabs, followed by all the panel content. I got the same result with:
$( ".tabs" ).tabs( refresh );
I did verify that my jQuery UI in general was working (e.g. I tried
$( ".tabs" ).tabs({ event: "mouseover" }); which worked fine.
This seems like it should be simple, but I've reached a relative dead end with CSS, and I don't understand what is going on with the jQuery- why it breaks with heightStyle and refresh. Any ideas or advice on getting my content to behave itself are very much appreciated... thanks!

Adjust the following from:
#tabs-left > div {
height: 35em;
}
to:
#tabs-left > div {
min-height: 35em;
}

Related

w3 css w3-navbar with w3-top hiding page content

Using w3css with a pinned navbar (ie enclosed in a with class w3-top) how can I know the height of the navbar (which will vary with screen size) so I can leave this much space at the top of my non-pinned content so the navbar doesn't overwrite content?
My best solution so far is to duplicate the navbar in javascript and insert that at the top of the page without the w3-top class so that there is a hidden element which is always the same size at the top of the page.
...
<div id="pinned_nav" class="w3-top">
<ul class="w3-navbar w3-light-grey w3-border">
<li>
...
<script type="text/javascript">
//Duplicate the nav without pinning it to the top - this means that the other content will adjust to height of pinned nav
var nav = document.getElementById("pinned_nav");
var nav_copy = nav.cloneNode(true);
nav_copy.classList.remove("w3-top");
nav.parentElement.insertBefore(nav_copy, nav);
</script>
...
Since this seemed less error prone than just copy and pasting the HTML block.
But it's still rather clunky and I just wondered if there was a simpler way I was missing.
Other questions like this one which are not w3css specific suggest using a fixed margin to skip a pinned toolbar but I can't see how to determine this margin height with a responsive navbar.
You could use a Javascript script to get the height and append it however you want to use it.
function getHeight() {
var nav = document.getElementById("pinned_nav");
var nav_height = nav.offsetHeight; //append this var where you need to.
alert(nav_height);
};
window.onload = getHeight();
window.onresize = getHeight(); //edit, added for if you resize the page
#pinned_nav {
height: 100px;
/*as example */
background-color: red;
}
<div id="pinned_nav" class="w3-top"></div>
EDT
Added resize event subscription.

Sticky navigation element jumps during scroll

In Firefox especially, I've run into an issue I can't figure out how to fix.
On the following page, when scrolling down the page jumps several times - mainly on smaller screens where the page doesn't have its full size displayed. You can replicate this issue by making your browser smaller than the page so you have to scroll.
It's on this page: http://www.nucanoe.com/frontier-accessories/
If I disable the position:fixed on the navigation selector, it fixes the issue - but we need the navigation to be sticky. Is there a solution to fix this? I'm thinking we may need to use jQuery somehow.
Thanks in advance!
After seeing you asking for help on another answer, I will try and explain more clearly for you.
The Problem
Your problem is when you add position:fixed to the navigation bar, it removes it from its place and sticks it at the top of the page. This is why the rest of your content jumps up - because the navigation bar is not where it was anymore.
How To Fix
You can get around this by wrapping your navigation element in a new div - let's call it nav-wrapper - and set its height to the same as your navigation element. These are known as placeholder elements. This new wrapper and your original navigation bar must always be the same height for the 'jump' to disappear.
<div class="nav-wrapper" style="height:80px;"> <-- add this
<div class="your-original-nav" style="height:80px"></div>
</div> <!-- add this
Now, when you set the navigation bar to fixed and it disappears to the top, the new wrapper we created with the same height keeps the page's content the same. When the fixed class has been removed, it sits back in the wrapper again, without pushing the content down.
A Suggestion
From what I can see on your site, there will be a big gap where the navigation bar was until the new fixed navigation reaches that point and covers it. What you want, is a little jQuery to figure out where to make the navigation fixed and where to hide it. I'll explain:
// cache the element
var $navBar = $('.your-original-nav');
// find original navigation bar position
var navPos = $navBar.offset().top;
// on scroll
$(window).scroll(function() {
// get scroll position from top of the page
var scrollPos = $(this).scrollTop();
// check if scroll position is >= the nav position
if (scrollPos >= navPos) {
$navBar.addClass('fixed');
} else {
$navBar.removeClass('fixed');
}
});
You may want to add further functionality to this example, as it is very, very basic. You would probably want to recalculate the offsets on window resize as one addition.
A Demo
This is a little demo which might help you - I was bored and feeling helpful :)
Made it this way now: Added an element before the nav:
<div class="nav-placeholder"></div>
And the jquery:
<script type="text/javascript">
$(document).on("scroll",function(){
if($(document).scrollTop()>150){
$(".nav-placeholder").height($(".nav").outerHeight());
} else {
$(".nav-placeholder").height(0);
}
});
</script>
When I scroll down to 150 the placeholder gets the height of the nav, when i scroll up again I set it's height to 0.
Here is a fiddle: https://jsfiddle.net/herrfischerhamburg/562wu62y/
You need to have a placeholder when your nav goes from relative to fixed.
Therefore you need to make a new div.
jQuery(".nav").wrap('<div class="nav-placeholder"></div>');
jQuery(".nav-placeholder").height(jQuery(".nav").outerHeight());
jQuery(".nav").wrapInner('<div class="nav-inner"></div>');
Remember to change ".nav", "nav-inner" and "nav-placeholder" to your desire.
For a fully functional sticky nav, check my website: http://www.swegre.se/
I solved the problem differently so on firefox as you can see in logs it scroll up itself so to stop this scrolling I made simple statement
$(document).ready(function () {
var header = $('#left-menu');
var offset = header.offset().top;
var up = true;
$(window).scroll(function () {
var scroll = $(window).scrollTop();
console.log(scroll + ' ' + offset )
if (scroll >= offset) {
header.addClass('sidebar-sticky');
if (up){
$(window).scrollTop(offset);
up=false;
}
} else {
up=true;
header.removeClass('sidebar-sticky');
}
});
});
that solution work for me when I can't specify height of div's I use.

Bootstrap modal at top of iframe regardless of scroll position. How do I position it on screen?

When embedding a Bootstrap app in an iframe, modal dialogs always open at the top of the iframe, not the top of the screen. As an example, go to http://getbootstrap.com/javascript/ and open an example modal on the page. Then using the sample code below which places the same bootstrap page in an iframe, find a modal and open it:
<html>
<head>
</head>
<body>
<table width="100%">
<tr><td colspan="2" style="height:80px;background-color:red;vertical-align:top">Here's some header content I don't control</td></tr>
<tr><td style="width:230px;height:10080px;background-color:red;vertical-align:top">Here's some sidebar content I don't control either</td>
<td valign="top">
<iframe width="100%" height="10000px"
scrolling="no" src="http://getbootstrap.com/javascript/">
</iframe>
</td>
</tr>
</table>
</body>
</html>
Demo in fiddle
How do I go about positioning the modal on the screen in this scenario?
UPDATE: Unfortunately, my iFrame cannot fill the screen, nor can I make it fixed since it needs to blend into the rest of the page and the page itself has enough content to scroll. This is not my design and I ultimately intend to rework the whole thing, but this is what I have to work around for now. As a temporary option, I'm using javascript to tell the iframe parent to scroll to the top where the modal dialog pops up. While this is acceptable, this isn't the desired behavior.
I'm using angularjs and the ui-bootstrap library in my code but as you can see above, it's a bootstrap issue.
If your iframe has the same document.domain as the parent window or it is a sub domain, you can use the code below inside the iframe:
$('#myModal').on('show.bs.modal', function (e) {
if (window.top.document.querySelector('iframe')) {
$('#myModal').css('top', window.top.scrollY); //set modal position
}
});
show.bs.modal will fire after you call $('#myModal').show()
window.top.scrollY will get the scrollY position from the parent window
In case your document.domain differs from the parent, you can hack it getting the onmousedown position inside the iframe. For example:
$('#htmlElement').on('mousedown', function (event) {
event.preventDefault();
$('#myModal').data('y', event.pageY); // store the mouseY position
$('#myModal').modal('show');
});
$('#myModal').on('show.bs.modal', function (e) {
var y = $('#myModal').data('y'); // gets the mouseY position
$('#myModal').css('top', y);
});
Quite old question but I don't see the solution/workaround I've found. It might be helpful for someone in the future.
I had the same issue - my iFrame doesn't fill the entire screen, it displays bootstrap's modal and it is loading content from different domain than the parent page.
TL;DR
Use window.postMessage() API - Documentation here. for communication between parent and iframe (cross-domain)
pass message with currentScrollPosition and Y position of your iframe
Reveive message and update modal's padding from the top
In my case the workaround was to use window.postMessage() API - Documentation here.
It requires to add some extra code to the parent and handle message in an iFrame.
You can add EventListener and listen to 'scroll' event. Each time the event handling function is invoked you can get currentScrollPosition like document.scrollingElement.scrollTop.
Keep in mind that your iframe can have some margin from the top in the parent page so you should also get its 'offset'.
After that you can post these two values to your iframe e.g. ncp_iframe.contentWindow.postMessage(message, '*');
Note that the message has to be a String value
After that in your iFrame you need to add EventListener and listen to 'message' event.
The event handling function will pass your 'message' in event.data property. Having that you can update modal padding. (Looks much better if you don't use animations e.g. fade, in classes);
Quick Example:
Parent:
window.addEventListener('scroll', function(event){
var myIframe = document.querySelector('#myIframe');
var topOffset = myIframe.getBoundingClientRect().top + window.scrollY;
var currentScroll = document.scrollingElement.scrollTop;
myIframe.contentWindow.postMessage(topOffset + ':' + currentScroll, '*');
});
iFrame:
window.addEventListener('message', function(event) {
var messageContent = event.data.split(':');
var topOffset = messageContent[0];
var currentScroll = messageContent[1];
//calculate padding value and update the modal top-padding
}, false);
This is a bug in most browsers (IE appears fine) where the elements are fixed to the iframe, not the window. Typically, if you need something to be relative to the main document, it has to be in the main document.
A workaround is to wrap your iframe in a fixed position div that takes up the whole width of the screen and then maximize the iframe within that. This appears to resolve the issue
HTML:
<div class="fixframe">
<iframe src="http://getbootstrap.com/javascript/"></iframe>
</div>
CSS:
.fixframe {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
.fixframe iframe {
height: 100%;
width: 100%;
}
Working Demo in fiddle
See Also:
position:fixed inside of an iframe
iframe with a css fixed position : possible?
position fixed div in iframe not working
It is because the class .modal has position: fixed attribute. Try position: relative instead.

Get div to adjust height with header content

I have a side bar that contains two divs. The first div may or may not have content, depending on what else is done on the page. The second div contains a long list of things and has a limited height, so scrolling is possible. I want to have the sidebar be as tall as the page, and I want the list container in the sidebar to be as tall as the sidebar minus the height of the header (which will change while using the page). I don't care about limiting the size of the header. The biggest is will get isn't anything significant.
Right now I'm just setting the height of the list container to be some number that is won't go over a maximized window height if the header div as as much content as it can, but this leaves an empty space at the bottom when the header is empty, and still doesn't work very well if the window is resized.
The layout is similar to this.
Is there a css solution to what I'm looking for, or will I have to use javascript and get window height/set div heights in pixels? I'm fine with either, it just seemed like there should be a CSS way to accomplish it.
If you're not opposed to using a little jQuery, here's a little code snippet that should help you equalize the height of the two divs, no matter which has more content. You can change it to your liking too.
var leftHeight = $(".left").height();
var rightHeight = $(".right").height();
var maxHeight = 0;
var div = "";
if (leftHeight >= rightHeight)
{
maxHeight = leftHeight;
div = ".right";
}
else
{
maxHeight = rightHeight;
div = ".left";
}
$(div).each(function(){
if ($(this).height() > maxHeight) { maxHeight = $(this).height(); }
});
$(div).height(maxHeight);
and credit where credit is due, this is an edit of a code snipped found at css-tricks.com
is this what you want?
http://jsfiddle.net/YWNyr/
CSS tips:
If you use 'absolute' positioning, width,height,left,top, etc... is relative to the first ancestor that has a "position" property other than "static", or the body if nothing is there.
for static menus, it is common to use 'position:fixed' as it will simplify scrolling issues
When using jquery its easier(and faster) to toggle a class than to change the DOM since that requires redrawing of the elements by the browser
-edit: for refreshing the sidebar size some javascript is necessary:
$('#headerAdd , #headerRemove').click( function()
{$('#sideContainer').height($(window).height()-$("#header").height());
} );
Try setting the height of your list container to 100%, and your overflow to scroll:
#listContainer {
height: 100%;
overflow: scroll;
}
This will keep the list in a scrollpane that reaches to the bottom of the page, no matter how large the header grows or shrinks.

Addthis widget in fixed element - position error?

I am using addthis as a vertical toolbox with the popup to be displayed on hover in a fixed element.
But when scrolling, the popup is displayed somewhere else. I tried using configs of offset top and left, but there were of no use. Is there any solution for this ???
DEMO here ----> http://jsfiddle.net/vaakash/QzjxR/1/embedded/result/
I tried using the code using jQuery and fairly satisfied my needs. So. here i used the on "mousemove" event to position the popup and it did worked.
$('.addthis_button_compact, .addthis_bubble_style').mousemove(function(e){
$('#at15s').css({
'top': e.pageY - 200 ,
'left': e.pageX - 200
});
});
Apparently there is no fix, according to the AddThis people.
This happens because we don't
recalculate the position of the DIV
after the menu is invoked. What I
would do is disable the compact menu
and set the button to only use the
expanded (full) menu, which is auto
centered.
So change <a class="addthis_button_compact"></a> to <a class="addthis_button_expanded"></a>
http://www.addthis.com/forum/viewtopic.php?f=5&t=24157
I ran into a similar situation where I had a div that dynamicly changed from normal to fixed positioning based on the scroll position (it was a sticky menu halfway on the page).
In the end I fixed it with this code:
// begin Fix for the AddThis menu positioning..
$(".sharing").bind("mouseenter", function (e) {
var isSticky = $(".sharing").hasClass("sticky");
var buttonPos = $(".addthis_button_compact").offset();
addthis_config.ui_offset_top = isSticky ? buttonPos.top - 9 : 0;
});
// config for the AddThis menu positioning, needs to be in the global scope..
var addthis_config = { ui_offset_top: 0 }
See AddThis menu offset for help on the addthis_config parameter.

Resources