jquery css applied but not visible for flex element - javascript

I find myself struggling to understand why my approach at recalculating width of an element on resize and seeing the result doesn't work.
Scenario:
I have a flex layout, with 3 unequally wide containers divided into 3/7, 1/7 and 3/7 of the width of the page. I use width: calc(100%/7) or width: calc(100%/7*3) to let the browser calculate the relation of these containers.
I am aware of the issue that Chrome rounds the calculated values down in case there is an inaccuracy when calculating the relation. This is visible when resizing the browser window as a subpixel-wide white stripe, where the background shines through between the containers on certain widths. Note: this problem does not happen in Firefox, they seem to round these values differently (?).
What I tried:
I used jQuery and parseFloat(document.getComputedStyle(element).width) to get the values of the containers and calculate the difference in order to "stretch" the middle container to fill in the gap:
jQuery(window).on('resize', function () {
var mainSite = document.getElementsByClassName('site-main')[0];
var leftStart = document.getElementsByClassName('page-trigger left')[0];
var middleStart = document.getElementsByClassName('page-trigger middle')[0];
var rightStart = document.getElementsByClassName('page-trigger right')[0];
var mainSiteWidth = parseFloat(window.getComputedStyle(mainSite).width);
var leftStartWidth = parseFloat(window.getComputedStyle(leftStart).width);
var middleStartWidth = parseFloat(window.getComputedStyle(middleStart).width);
var rightStartWidth = parseFloat(window.getComputedStyle(rightStart).width);
console.log(mainSiteWidth);
console.log(leftStartWidth);
console.log(middleStartWidth);
console.log(rightStartWidth);
var calculatedElementWidth = leftStartWidth + middleStartWidth + rightStartWidth
if (mainSiteWidth > calculatedElementWidth){
var diff = mainSiteWidth - calculatedElementWidth;
var newMiddleWidth = middleStartWidth + diff;
console.log("diff: " + diff);
console.log("new middle width: " + newMiddleWidth);
jQuery(middleStart).css({
flex : "0 0 " + newMiddleWidth + "px",
width: newMiddleWidth + "px",
minWidth: newMiddleWidth + "px",
maxWidth: newMiddleWidth + "px"
});
console.log(parseFloat(window.getComputedStyle(middleStart).width));
}
}).resize();
So far, the values get correctly calculated and even applied to the middleStart element, at least in the DOM inspector, however, the gap is still there, even though the css values indicate, it should have changed.
These were the css settings before the jquery modifications:
flex: 0 0 calc(100%/7); --> translates to 273.562px, Chrome shows as 273.56px
width: calc(100%/7); --> translates to 273.562px, Chrome shows as 273.56px
min-width: calc(100%/7); --> translates to 273.562px, Chrome shows as 273.56px
max-width: calc(100%/7); --> translates to 273.562px, Chrome shows as 273.56px
These are the values in the DOM inspector after that:
flex: 0 0 273.594px;
width: 273.594px;
min-width: 273.594px;
max-width: 273.594px;
I tried to create a jsfiddle but I couldn't reproduce that issue there, since my layout is more complex and has more layers.
Does anybody have an idea, why the css settings, though being applied to the element in the DOM, are not visible?
EDIT: this is what happens, try to resize the browser window horizontally (please ignore the occasional jump of the right element, I had to use float:left; to make it reproducable and it only happens in Chrome: jsfiddle

Related

HTML Resize Div with Javascript

I am working on an online presentation editor.
I have a div (which should be the slide - the format is 16x9)
If the user decides to export it as pdf, the div should resize to 1920x1080, and then it should be exported (so that the pdf is not the same size as the user window, but always 1920 x 10800. My problem is, that if I set the width in JS like this:
$('#content').css('min-width', `1920px`);
$('#content').css('min-height', `1080px`);
$('#content').css('width', `1920px`);
$('#content').css('height', `1080px`);
only the container resizes, but the content doesn't.
This is what the slide looks like in the app
This is what the exported pdf looks like because the content doesn't resize.
If you have any idea, please let me know.
HTML:
<div style="background-color: green" id="content">
<h1 style="color: black">Hallo Welt</h1>
<p>Hallo 3CHIF!</p>
</div>
Well, maybe there's other solutions (or even better solutions), but I tought about scale(), this will scale the div and consequently, it's contents.
So, how I did it:
I estipulated the desired width and height (in your case, 1920x1080), then I got the div current size.
Divided the desired sizes by current sizes to get the "ratio", then used the CSS transform to set the new scale(x, y), as you can see in the below example.
You can base yourself in the code to get your solution
var desiredWid = 1920;
var desiredHei = 1080;
var theDiv = $("#content");
var currentWid = theDiv.width();
var currentHei = theDiv.height();
var ratioW = desiredWid / currentWid;
var ratioH = desiredHei / currentHei;
theDiv.css("transform","scale(" + ratioW + "," + ratioH + ")")
var currentSizes = theDiv[0].getBoundingClientRect();
console.log("Adjusted Size:", currentSizes.width + " x " + currentSizes.height)
#content {
width: 2500px;
height: 1200px;
background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">Original Size: 2500x1200</div>
I used jQuery since I saw you are using, but you can do it with pure JS also.
try
#content{
width:100%;
height:100%;
}
if you want to have initiate max with or height you can add it to css too
then see if .css work or not
or must I say
then use js

Using Vanilla JS to add inline CSS property and fallback value

The problem I am trying to solve is basically the issue with Safari iOs and Vh calculations.
Here is the function:
function overflowHandler() {
const header = document.querySelector('.header-container').getBoundingClientRect().height;
const regionTop = document.querySelector('.region-top').getBoundingClientRect().height;
const totalHeaderHeight = header + regionTop;
if (window.innerWidth < 1080) {
flyout.style.height = 'calc(100vh - ' + totalHeaderHeight + 'px)';
}
}
But I need to be able to also pass in height: webkit-fill-available as a style as well to fix the bug on iOS where the user can't scroll completely to the bottom of the nav.
I've tried using element.style.cssText to set both height properties, but whatever is the rightmost value is what gets rendered in the browser.
Example of what I mean would be:
element.style.cssText = 'height: calc(100vh - ' + totalHeaderHeight + 'px); height: -webkit-fill-available;'
would render as height: -webkit-fill-available;
I am at a loss on any other way to make it work or how else to ensure the full height of the menu can be scrolled on iOS.
Use element.setAttribute('style', 'height: -webkit-fill-available;')

Render div content in fullhd then proportional scale

TV shows slides, that holds HTML inside. TV's resolution is FullHD (1920x1080).
When editing the slide I want to able to know, how slide will exactly be shown on TV. Although I have a FullHD monitor, I've never worked in the browser in fullscreen mode. Other people, which potentially be working with slides, want to see slides as is too.
Using another word, I need to render 1920x1080 div, then proportionally scale it to fit client's browser. How can be this done using CSS or JS, or jQuery?
Edit: I do NOT need to proportional manipulate the image. I need to see how page will look on FullHD resolution regardless of client's viewport resolution
UPDATED!! Here is the demo: https://jsfiddle.net/8jxk0atm/4/
Old resize 1920x1080 aspect ratio demo: https://jsfiddle.net/8jxk0atm/2/
You can create the div spec with 1920x1080. And put this
// screen zoom out for checking
document.body.style.zoom="40%"
on top of your js code.
It will zoom out your document so you can see what it will look on 1920x1080 div.
HTML
<div id="fullscreen"></div>
CSS
html,
body {
margin: 0;
padding: 0;
}
#fullscreen {
width: 1920px;
height: 1080px;
background: green;
color: #fff;
}
JS
// screen zoom out for checking
document.body.style.zoom="40%"
makeFullHD();
function makeFullHD() {
var value = $(window).outerWidth();
value *= 1;
var valueHeight = Math.round((value / 16) * 9);
$('#vidHeight').text(valueHeight);
$('#videoBox').css('width', value + 'px').css('height', valueHeight + 'px');
$('#videoPlayer').css('width', value + 'px');
$('#fullscreen').css({
width: value,
height: valueHeight
});
// test
$('#fullscreen').text('Width:' + value + '\n' + 'Height:' + valueHeight);
}
$(window).resize(function() {
makeFullHD();
});

JavaScript: How to get a dynamically created element's width?

I'm a JavaScript novice. Have patience with me.
I searched this site for relevant questions and found two: How to get width of a dynamically created element with $comiple in Angularj and jQuery + CSS. How do I compute height and width of innerHTML?. Their relevance and their answers are discussed below. If I missed a relevant question and this is a duplicate question, please direct me to it.
I dynamically create a <div class="popup"> (call it "popup"), populate it with innerHTML from a display: none; <div> in the markup, and insert it on the page. The relevant CSS is:
.popup {
top: 0;
left: 0;
width: 200px;
height: 250px;
}
Using event.clientX, I position popup relative to the cursor position at the time the mouseover event fired, as follows:
var widthOffset = 75, heightOffset = 0;
var windowWidth, popupWidth;
// other code ...
windowWidth = $(window).width();
popupWidth = 200; // popup.style.width returns nothing (not null,
// not undefined, just nothing).
// when event.clientX is in the left half of the window, display popup
// offset to the right of clientX;
// when clientX is in the right half, display popup offset to the left.
if( event.clientX > windowWidth/2 ){ widthOffset = -(widthOffset + popupWidth);}
popup.style.top = event.clientY - heightOffset + "px";
popup.style.left = event.clientX + widthOffset + "px";
There is a working reduced case at the Pen Popup Project Reduced Case on CodePen.
The problem is that I want to programmatically obtain popupWidth not set it as a fixed quantity. But, as the comment states,
popupWidth = popup.style.width;
is nothing. (Maybe it's a null string: popupWidth === "". I'm uncertain.)
The answer to the first question referenced above said to insert popup into the DOM before trying to obtain its width. I have done this. (See the Pen.) Still, it doesn't work.
A comment to the second answer to the second question said:
the root issues is that height cannot be set on an element with display:none.
I had display: none but when I changed it to display: block, and set popupWidth = popup.style.width;, popup "stuttered" fiercely on mouseover.
So the question remains: How do I programmatically get popupWidth just as I did with windowWidth?
With help from #Redu and #torazaburo, the answer became clear.
popupWidth = popup.offsetWidth; is the correct statement but both these conditions must be true:
popup must have been inserted into the DOM, and
display: block; must have been set.
If popup is still in memory or display: block; has not been set, then popup.offsetWidth === 0. If both of the conditions are true, then popup.offsetWidth is equal to the width set in the CSS.
Thanks to both commenters for their help.
You can do like
var popupDiv = document.getElementsByClassName("popup")[0],
width = window.getComputedStyle(popupDiv).width;
If you deal with a window or document type of element then getElementsByClassName(element,null), element.offsetWidth or element.clientWidth doesn't work. You have to access the width value like
var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

JavaScript: Get window width minus scrollbar width

Ok, I thought this would be really simple, but it's turning out not to be. I think I'm just messing something up in my HTML/CSS, but here goes.
I have a basic page like so:
HTML
<!DOCTYPE html>
<html>
<head>
<link href='test2.css' rel="stylesheet" type="text/css" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="test2.js"></script>
</head>
<body>
<div id="scroll"></div>
</body>
</html>
test2.css
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
width: 100%;
}
#scroll {
height: 100%;
width: 100%;
overflow: scroll;
background-color: black;
}
test2.js
$(document).ready(function() {
// my resolution is 1440x900
alert('innerwidth should be 1425');
// all of these return 1440
alert('body innerwidth: ' + $('body').innerWidth());
alert('document width: ' + $(document).width());
alert('window width: ' + $(window).width());
alert('scroll div innerwidth: ' + $('#scroll').innerWidth());
alert('document.documentElement.clientWidth: ' + document.documentElement.clientWidth);
alert('document.documentElement.scrollWidth: ' + document.documentElement.scrollWidth);
});
So I've got one element on the page... a div that takes up the entire screen, or rather it should be taking up the entire screen minus the scrollbars. Now, I've been doing some snooping on how to grab the width and height of a page without the scrollbars, but unfortunately, none of them return the proper value... which makes me believe I'm missing the boat in my HTML or CSS.
I looked at the following:
jquery - how to get screen width without scrollbar?
how to get the browser window size without the scroll bars
So what I need is for a method to return the value of my viewable screen minus the respective scrollbar value... so for my width, my value should be 1425 because the scrollbar is 15 pixels wide. I thought that's what innerWidth's job was, but apparently I'm wrong?
Can anyone provide any insight? (I'm running Firefox 24.)
EDIT
To add some background, I've got a blank page. I will be adding elements one by one to this page, and I need to use the width of the page when calculating the sizes for these elements. Eventually, this page will grow and grow until the scrollbar appears, which is why I'm trying to force the scrollbar there from the start, but apparently, that still doesn't do anything.
EDIT2
Here's something even more interesting... if I do document.getElementById('scroll').clientWidth, I get the proper innerWidth, but if I do $('#scroll').width() or $('#scroll').innerWidth(), they both return the max resolution... sounds like a jQuery bug.
I got this somewhere and would give credit if I knew where, but this has been succesfull for me. I added the result as padding when setting the html overflow to hidden.
Problem is that the scrollbar is a feature of the browser and not the web page self. Measurement should be done dynamically. A measurement with a scrollbar and a measurement without a scrollbar will resolve into calculating the difference in width.
Found the source: http://www.fleegix.org/articles/2006/05/30/getting-the-scrollbar-width-in-pixels
scrollCompensate = function () {
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild(inner);
document.body.appendChild(outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild(outer);
return (w1 - w2);
}
var htmlpadding = scrollCompensate();
The correct answer is in this post marked as accepted:
CSS media queries and JavaScript window width do not match
This is the correct code:
function viewport() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
Discovered a very hacky solution... by adding this before my alerts in test2.js, I get the proper width:
var p = $('body').append('<p style="height: 100%; width: 100%;"></p>');
alert(p.width());
$('body').remove('p');
And consequently, all of the alerts now have the proper width. I also don't even need overflow-y in the CSS if I do it this way. Curious why this solves it...
The real answer should be keeping the HTML and CSS as is, then using document.getElementById('scroll').clientWidth. Using clientWidth gets the viewable area minus the scrollbar width.
The correct width of the page is given by $(document).width().
Your problem is that you're using a scroll within the div (overflow: scroll).
Using $(document).width() the returned value is already discounting the visible width of the scroll, but how do you put a scroll within the div value returned is no longer the same.
As the width of the scroll is not standard and varies from system to system and browser to browser, it is difficult to solve.
I suggest you remove the scroll of the div and let the browser manage this by default in the body, then yes you have the correct width.

Categories

Resources