Dynamically setting max-height of Bootstrap modal body - twitter-bootstrap-3

I'm trying to dynamically set the max-height of Bootstraps modal-body elements for all modal dialog boxes. I've written the following, which seems to work when the dialog is opened. I'm depending on the enforceFocus method to exist and to be called once the dialog is rendered. I realize there may be moment before the CSS property is set where the dialog will not be rendered exactly right, but I'm okay with that. Is there anything wrong with this solution? I know I have yet to account for resizing the screen with a modal open, but that seems the easier problem to solve.
(function ($) {
$.fn.modal.Constructor.DEFAULTS.backdrop = 'static';
$.fn.modal.Constructor.DEFAULTS.keyword = false;
var oldEnforceFocus = $.fn.modal.Constructor.prototype.enforceFocus;
$.fn.modal.Constructor.prototype.enforceFocus = function () {
oldEnforceFocus.call(this);
var $element = this.$element;
var maxHeight =
$("body").height() // full page
- $element.find(".modal-header").outerHeight(true) // modal header
- $element.find(".modal-footer").outerHeight(true) // modal footer
- ($element.find(".modal-dialog").outerHeight(true) - $element.find(".modal-dialog").height()) // dialog margins
- 5; // fudge factor
$element.find(".modal-body").css("max-height", maxHeight);
}
})(jQuery);
Thanks!
edit: To give credit where credit is due, this is based on
Correct way to extend Bootstrap Modal - lock, unlock.

If you don't want to use javascript, you can use CSS media queries and get close-ish to the height you need by using min-height. For example, define a media query on min-height: 540px, and set the max-height of the modal to something like max-height: 500px. Then define a media query at say min-height: 680px and set the modal to max-height: 640px. It's not fluid, and it requires several media queries to inch up to the largest size you want to plan for, but it will get you there.

#Josh solution is good with CSS and media queries but writing so many media queries where small devices has different screen heights e.g Iphone and SamSung G and N series, required alot of media queries to even calculate close-ish modal height on different screen sizes.
so setting height of modal (modal-body) dynamically according to media screen size and on small devices where there will be 2 types of media screen landscape and portrait, following few lines of code will put you very close-ish to your goal
Rendering modal HTML according to screen size with-in sec and later if screen size changes adjust it's height according to screen size
$(document).ready(function () {
setInterval(Dimension, 100);
function Dimension() {
var doc = $(document).height(); // document height
var head = $(".modal-header").height(); // modal header height
var footer = $(".modal-footer").height(); // modal footer height
var modheight = doc - head - footer - 65; // 65 is extra margins and it will not effect the height of modal any way if not changed.
$('.modal-body').css('height', modheight);
}
});
Note
Few Changes required in Modal CSS
CSS
.modal-dialog {
margin: 0px auto !important;
}
.modal-body {
overflow-y: scroll; // In-case the content in modal-body overflow so it will have scrolling.
}
Fiddle
You can check the modal height adjust itself by increasing and decreasing the fiddle result window's height and width.

Related

Sticky tab bar with Fluent UI's Pivot

I am building a tabbed environment using Fluent UI's Pivot component. Some of the tabs (or PivotItems in Fluent UI parlance) are quite long and need to be scrollable. Is there a way of having the tab bar be sticky such that it stays on top of the frame and visible no matter where the user scrolls to on the tab?
To get expected behavior you just need some CSS.
Set height of body and html to 100vh, and overflow: hidden to avoid multiple scrollbars.
body, html {
height: 100vh; /* Viewport height */
overflow: hidden; /* To avoid multiple scrollbars */
}
As a working example I'm gonna use Links of large tab style. Content of every item renders inside PivotItem Component. So, you have to put some styles on it:
const pivotItemStyles = {
height: 'calc(100vh - 44px)',
overflow: 'auto',
}
PivotTabs by default uses height: 44px that's the reason why I put calculate inside height property. overflow: auto is to get scrollable content.
Reference: Pivot.styles.ts
Codepen working solution

Magnific Popup - taller mfp-bottom-bar causes max image height issue

I am customizing the title of the Magnific popup/lightbox to include more than one row of content by using the 'change' callback, and modifying the content of
this.content
within the callback. It is working correctly, except for the fact that if the image within the popup is very tall, or the window re-sizes to a smaller height, the calculation that Magnific is doing to adjust the 'max-height' of the image seems to only take into account a single row of text for the title.
Does anyone know what is needed to adjust the max-height calculation of the image to take into account a taller title box?
Thank you
** Edit
A quick hack to jquery.magnific-popup.js around line 461 in the "updateSize:" callback has allowed me to get around this problem. It seems reasonable to for this popup/lightbox to accept a max height in percentage so that it doesn't fill the screen.
Here's my change, I'd appreciate some feedback if possible. Thanks!
updateSize: function(winHeight) {
if(mfp.isIOS) {
// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
var height = window.innerHeight * zoomLevel;
mfp.wrap.css('height', height);
mfp.wH = height;
} else {
mfp.wH = winHeight || _window.height();
// ########################################
// CHANGE IS RIGHT HERE TO FORCE 80% height
// ########################################
mfp.wH *= 0.8;
}
// Fixes #84: popup incorrectly positioned with position:relative on body
if(!mfp.fixedContentPos) {
mfp.wrap.css('height', mfp.wH);
}
_mfpTrigger('Resize');
},
You can limit the max height of the image in the resize callback, which will allow more room for the title:
$('a.magnific').magnificPopup({
type: 'image',
callbacks: {
resize: function() {
var img = this.content.find('img');
img.css('max-height', parseFloat(img.css('max-height')) * 0.95);
}
}
});
I'd like to add my contribution. As I wanted to include both titles and descriptions to images. This meant that I couldn't fit all this information in the viewport space. The description was cut off and I was left with a scrollbar.
#alexantd - I tried your callback addition which only works when the window is being resized.
#ajhuddy - Your solution worked perfectly for me. I was able to fit the text in fine. Though the image was considerably small with a lot of space at the top.
I adjusted the padding as to regain 40px space to display a slightly larger image. Here's my CSS to do so. The CSS below allowed me to reduce images to 0.85 (85%).
.mfp-img {
padding: 0px 0px 40px !important;
}
.mfp-close {
margin-top: -40px;
}
else b.wH=a||v.height()**,b.wH*=.9**;b.fixedContentPos

Script/code to detect screen dimensions

I have a div on my page containing images. As it is 800px high and situated 400px from the bottom of the page, my images are getting cut off from the top when viewed on smaller monitors. I am not using scrollbars on my website.
I have added some CSS to my div that zooms out/scales the content...
.hello {
width:100%;
height:800px;
position:fixed;
top:0;
bottom-margin:400px;
z-index:0;
-moz-transform: scale(.8);
-webkit-transform: scale(.8);
zoom : .8;
-moz-transform-origin:top center;
-webkit-transform-origin:top center;
}
But is there any script that I could implement that will only apply the zoom/scale if the user's monitor dimensions are 1200px high or smaller?
Thanks in advance for any help!
What you're looking for is the screen resolution. See here. Relevant bits:
height
Returns the height of the screen in pixels.
width
Returns the width of the screen.
However, this does not tell you how big the window is, in which case you'll need the windows dimensions. See here. Relevant bits:
window.innerHeight
Gets the height of the content area of the browser window including, if rendered, the horizontal scrollbar.
window.innerWidth
Gets the width of the content area of the browser window including, if rendered, the vertical scrollbar.
I would detect this and change classes and whatnot appropriately.

Is it possible to have a sticky header, scrolling to anchors all in a responsive layout?

I have a responsive layout and I am using sticky.js for my header. This seems to be working minus a few glitches that I can live with. But my anchors are always off (I am using smooth scrolling). I am not sure how to compensate for the sticky header when scrolling to an anchor when the responsive layout is constantly changing the width and height?
Unfortunately there is not a whole lot you can do with straight-CSS which won't distort your design. To tackle this issue in previous projects, I have used jQuery to handle these types of scrolling/anchor issues.
What You Have Now: <a> tags that look for id's on the page. The problem is this: when the site goes responsive, those anchor tags don't line up so nicely with your DOM layout.
My Solution: To give you the high level concept - I used jQuery to modify the ID positions on the fly. Say you click on a link when the site is full-size, and everything is fine. jQuery is not needed here. Now say that when you click that same link when the site was scaled to about the 768px-width range (iPad portrait): then my anchors might look as if they were about 100px off (for example). I wrote a bit of jQuery to handle this: "If the width is __, then offset the anchor ID's by ___px."
I would recommend using JS to account for the difference at time-of-scroll, rather than trying to artificially alter the height property of your anchor tags. Here's a function that might work for you, using pure JS:
adjustScroll = function () {
// Sticky nav selector (you'll have to provide your own selector)
const nav = document.querySelector('header>nav');
if (location.href.indexOf("#") >= 0) {
// Find the name of the anchor
let n = location.href.substr(location.href.indexOf("#")+1);
// Find the anchor by name, if it exists
let a = document.querySelector('a[name="'+n+'"]');
if (!a) {
return;
}
// Set y value as y-value of the anchor, offset by the header height
let y = a.offsetTop;
y -= nav.height + 10;
// Scroll to the y position
window.scrollTo(0, y);
}
}
// Call it wherever you need to call it
adjustScroll();
Examples of where to call it might be on a DOMContentLoaded event, or on an onclick event for anchor tags.

Supersized Slideshow below Header

I'm using the supersized jquery plugin in order to display a fullscreen background slideshow.
Look at this website (it's not my own but I'm using the same structure):
http://mysampleconcept.com/situs4/
As you can see (for example if you give the header some opacity) the images begin at the top of the body.
But I want them to begin below the header (so that the header doesn't cover the top of the image).
If you give the supersized LIs for example top: 100px; the whole image moves down so that the bottom of the image disappears below my footer.
So that's not the solution I want.
So all in all which I need is the image to stretch to the biggest size it can, while still being inside the window not stretching over the top 100px nor bottom.
How can I do this?
Sorry, my English is not the best...
I found this solution but I don't know how to implement it: https://stackoverflow.com/a/12889088/1981981
You can use the solution offered in the question you refered to as a starting point. Just place it right below the $.supersized() inside your document ready function.
Since you want a top offset, we have to modify the top value aswell. I modified the snipped to suit your needs:
var portfolioSize = function() {
var headerOffset = 100;
$('#supersized').css({
height: $(window).height() - headerOffset,
top: headerOffset + 'px'
});
};
portfolioSize();
$(window).resize(function() { portfolioSize(); });
I changed the $(window).load Event to a direct call, since we place the code inside the document ready function.
Don't forget to modify the CSS for positioning as mentioned in the other answer (https://stackoverflow.com/a/12889088/860205).