Get width of an element after the browser has determined its width - javascript

I have a pop up box that I want to be perfectly centered on the window. It has the following CSS properties:
#pop_up {
position: fixed;
display: inline-block;
border: 2px solid green;
box-shadow: 0px 0px 8px 5px white;
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
border-radius: 5px;
background-color: grey;
}
I also have some jQuery stuff that sets this element's left and top properties.
$(document).ready(function() {
window_height = $(window).height();
window_width = $(window).width();
pop_up_height = $('#pop_up').outerHeight();
pop_up_width = $('#pop_up').outerWidth();
pop_up_left = (window_width / 2) - (pop_up_width / 2);
pop_up_top = (window_height / 2) - (pop_up_height / 2);
$('#pop_up').css('left', pop_up_left);
$('#pop_up').css('top', pop_up_top);
});
I had it alert me of all of the variables and the window variables were right but for pop_up_height and pop_up_width it would alert me '4'. This obviously means that it is only getting the border. If I change it to .innerHeight(); and .innerWidth(); it alerts '0'. So, it is returning the width before the browser decides according to my width: max-content; property. Trying to figure how to get the width after the browser auto's it.
Also, when I specify a left property does it position the element according to the border or to the actual inside of the element? So if I gave an element 2px border and a left of 20px, would the border be 20px from the left or the actual inside of the element? Just a side question.

function popCenter()
{
$('#pop_up').css({'top':($(window).height()-$('#pop_up').height())/2,'left':($(window).width()-$('#pop_up').width())/2});
}
$(document).ready(function() {
popCenter();
})
$(window).resize(function() { //if resize the window, keep the selector in center;
popCenter();
})

No the border will not be 20 px.
And the element will stick to left .

Try using $("#pop_up").width(); and .height()

Related

Maintain aspect ratio of a video when resizing the browser

I'm working on a Video editing tool, and I need to maintain the 16:9 aspect ratio of the video when resizing the screen horizontally and vertically. So far I got it to work as expected when resizing horizontally, and when resizing down vertically, but can't get it to work when sizing up vertically. The Javascript code I used to calculate the height of the video and resize it is below (notice how the else clause is empty because that's where the code should go):
const calculateHeight = () => {
// Get the other elements on the page
const header = document.querySelector('.main-navigation');
const meshTopBar = document.querySelector('.mesh__top-bar');
const footer = document.querySelector('.mesh__bottom-bar');
// Get the section to apply the window height to it
const mainSection = document.querySelector('.insert-level-container');
// Get the video elements
const editor = document.querySelector('.mesh__insert-editor-container');
const video = document.querySelector('.mesh__insert-editor-video-container');
// Apply the height to the main section by calculating the window height minus the other elements' height
if(mainSection !== null) {
mainSection.style.height = (window.innerHeight - header.offsetHeight - meshTopBar.offsetHeight - footer.offsetHeight) + 'px';
}
// This should be the ideal height for the video
video.style.minHeight = ((video.offsetWidth * 9) / 16) + 'px';
// If the video height is bigger than the section height (calculated above), then resize it
if(video.offsetHeight + 115 > mainSection.offsetHeight) {
video.style.minHeight = video.offsetHeight - 1 + 'px';
editor.style.maxWidth = video.offsetHeight * 16 / 9 + 'px';
} else {
// This is where the logic for the vertical resizing should go
}
}
The relevant CSS for these items is:
.mesh__insert-editor-container {
margin-left: auto;
margin-right: auto;
}
.mesh__insert-editor-video-container {
position: relative;
width: 100%:
}
And the HTML:
<section class="mesh__insert-editor-container flex__one flex-container flex-column horizontally-left-aligned" id="video-main-container">
<div class="mesh__insert-editor-video-container flex-container horizontally-right-aligned flex-wrap">
<video class="mesh__insert-editor-video-placeholder"></video>
</div>
</section>
All this code is:
Get the height of all the elements on the page, sum them and calculate the main section height by subtracting that height;
If the video height gets bigger than the section height, I reduce its height by -1px each time the window gets resized, and calculate the new width.
All the above code is giving me this result, which works great for most scenarios, but I need the video to size up when the condition on the if statement is not met. Everything I tried inside the else statement gets "jumpy".
Any better alternatives to solve this would be much appreciated. Thanks all!
The CSS aspect ratio trick might be a good solution: https://css-tricks.com/aspect-ratio-boxes/
The approach takes advantage of a quirk in CSS where padding based on a percentage value will be relative to the element's width. Create a container using this trick, the important bit is this line:
padding-top: calc(9/16 * 100%);
The value is calculating the correct height based on the aspect ratio you want (9 tall over 16 wide in this case) and generating it relative to the width of the element by multiplying by 100%.
With the container maintaining aspect ratio, just place the content inside an absolute positioned inner div and you should be good. This solution is fully responsive at that point.
* { box-sizing: border-box }
.outer-max-width {
max-width: 960px;
margin: 0 auto;
}
.aspect-ratio-box {
width: 100%;
padding-top: calc(9/16 * 100%);
position: relative;
border: 2px solid red; /* for demo visibility, remove */
}
.aspect-ratio-box-content {
position: absolute;
width: 100%;
top: 0;
left: 0;
border: 2px solid blue; /* for demo visibility, remove */
}
.video-placeholder {
display: block;
width: 100%;
height: auto;
}
<div class="outer-max-width">
<div class="aspect-ratio-box">
<div class="aspect-ratio-box-content">
<img class="video-placeholder" src="https://placeimg.com/640/360/nature" />
</div>
</div>
</div>
Got it to work! I used this amazing CSS-only solution: https://codepen.io/EightArmsHQ/pen/BvNzrm similar to BugsArePeopleToo's suggestion, from eightarmshq:
.content{
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
background: #555;
box-shadow: inset 1vh 1vh 10vh 0 rgba(0,0,0,0.5);
display: flex;
box-sizing: border-box;
border: 25px solid #cecece;
}

How to add or adjust this code to ALSO listen for browser resizing?

The following code does what I need on my site:
$(document).ready(function() {
$(".position").css("height", $(".wrapper-slider").height());
});
It makes my position div the same height as the wrapper-slider.
However, if I change the window size, it doesn't retrigger the sizing that that this javascript does.
I thought maybe adding lines something like this would work:
$( window ).resize(function() {
$(".position").css("height", $(".wrapper-slider").height());
});
However, it doesn't. I have to manually click Reload or Refresh on my browser to have the resizing triggered. What am I missing?
If helpful, this was the original inspiration: http://jsfiddle.net/Jyu94/
It looks like I could use this too:
$(window).resize(function(){
location.reload();}
);
I'm not sure how to combine the two so that its all one command.
You just forgot to add + "px" after getting the height of .wrapper-slider div! Here's an example (run it in Full Page so you can resize):
$(document).ready(function(){
var new_height = $(".wrapper-slider").height() + "px";
$(".position").css("height", new_height); // SET HEIGHT
$(".position .dim").text(new_height); // DISPLAY NEW HEIGHT
$(".wrapper-slider .dim").text(new_height); // DISPLAY NEW HEIGHT
});
$( window ).resize(function() {
var new_height = $(".wrapper-slider").height() + "px";
$(".position").css("height", new_height); // SET HEIGHT
$(".position .dim").text(new_height); // DISPLAY NEW HEIGHT
$(".wrapper-slider .dim").text(new_height); // DISPLAY NEW HEIGHT
});
/* MOST OF THE STYLING HERE IS PURELY AESTHETIC AND DOES NOT AFFECT ANSWER :) */
div {
display: inline-block;
text-align: center;
width: 45vw;
min-width: auto;
padding: 20px 0px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3);
}
.position {
background-color: #d55;
height: 75px; // NOTE THAT THE JS CODE OVERRIDES THIS
}
.wrapper-slider {
background-color: #da1;
height: 50vh;
}
.class {
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 10px;
}
.dim, .class {
font-family: "Courier"
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="position">
<span class="class">.position</span>
<p class="dim"></p>
</div>
<div class="wrapper-slider">
<span class="class">.wrapper-slider</span>
<p class="dim"></p>
</div>

why is child element's width changing when parent's width changes?

I am trying to create a tooltip element that has a min width of 50px and a max width of 200px. I place the tooltip element inside another element so that I can easily control when the tooltip appears or disappears when there is a hover event on the parent.
The problem that I have is that the tooltip element's width appears to be controlled by the parent's width even though I specified that the child(tooltip) has an absolute position.
let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
b = !b;
let w = 10;
if( b ) {
w = 300;
}
p.style.width = `${w}px`
}, 5000 );
#parent {
background-color: cyan;
width: 100px;
height: 25px;
position: relative;
transition: width 2s;
}
#tooltip {
position: absolute;
top: calc( 100% + 5px );
left: 5px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="parent">
<div id="tooltip">
My long tooltip text that wraps to multiple lines as needed.
</div>
</div>
I would like the tooltip (yellow div) to keep it's size at 200px in this example, but we can see that when the parent changes width, the tooltip width also changes. Why?
Is there a way to fix this problem?
Clarification: In this example: https://codepen.io/anon/pen/ePPWER we see that the tooltip text looks nice on one line. I don't want the tooltip's div to change its width when the parent changes width, because it forces the tooltip text to wrap onto 2 lines which is undesirable.
If we check the specification related to the width of absolutely positioned element we can read this:
'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
So in your case the width of your element is shrink to fit:
Calculation of the shrink-to-fit width is similar to calculating the
width of a table cell using the automatic table layout algorithm.
Roughly: calculate the preferred width by formatting the content
without breaking lines other than where explicit line breaks occur,
and also calculate the preferred minimum width, e.g., by trying all
possible line breaks. CSS 2.1 does not define the exact algorithm.
Thirdly, calculate the available width: this is found by solving for
'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.
Then the shrink-to-fit width is: min(max(preferred minimum width,
available width), preferred width).
To make it easy, and without considering the min/max-width, the width of your element will try to fit the content without exceding the width of its parent container (containing block). By adding min/max-width you simply add more constraint.
One idea of fix it to remove positon:relative from the parent element so that it's no more the containing block of the position:absolute element (it will be the initial containing block which is wide enough to avoid the available width constraint).
Then use margin instead of top/left to control the position:
let p = document.getElementById( 'parent' );
let b = true;
setInterval( ()=> {
b = !b;
let w = 10;
if( b ) {
w = 300;
}
p.style.width = `${w}px`
}, 5000 );
#parent {
background-color: cyan;
width: 100px;
height: 25px;
transition: width 2s;
}
#tooltip {
position: absolute;
margin-top: 30px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="parent">
<div id="tooltip">
My long tooltip text that wraps to multiple lines as needed.
</div>
</div>
ID Tooltip is being used under Parent. When parent's width changes, it also suggest that tooltip's total width is changed. Since you have used mix-width and max-width it will expand till it reaches max-width. If you want it to be fixed then simple use width.
It is because the .parent has a position: relative. This will keep all children (position: absolute included) as confined by the parent div.
Not sure if this will work for you because it is pulling the tooltip out of the parent and making it's own with span wrapping the text. Alternatively, you'll need to change the parent from being relative otherwise it'll continually affect the child.
let p = document.getElementById('parent');
let b = true;
setInterval(() => {
b = !b;
let w = 10;
if (b) {
w = 300;
}
p.style.width = `${w}px`
}, 5000);
#parent {
background-color: cyan;
width: 100px;
height: 25px;
transition: width 2s;
position: relative;
}
#root {
position: relative;
}
#tooltip {
width: 100%;
}
#tooltip span {
position: absolute;
top: calc( 100% + 5px);
left: 5px;
min-width: 50px;
max-width: 200px;
background-color: yellow;
padding: 5px;
border: 1px solid black;
}
<div id="root">
<div id="parent"></div>
<div id="tooltip">
<span>My long tooltip text that wraps to multiple lines as needed.</span>
</div>
</div>

Jquery ScrollLeft so that div's right border is always center of screen?

I have a DIV that expands as time increases after page load:
function scrollContainer() {
var wave = $("#wave");
$("body").scrollLeft(wave.width());
}
I would like to re-center the browser scroll horizontally as this div expands, to make sure that the right border of this div is always centered in the screen. Am I on the right track using scrollLeft?
I'm not really sure what effect you're looking for, but this is an expanding div, which remains centered: http://jsfiddle.net/y0hn2Lrm/
JavaScript
var expand = function( domNode ) {
domNode.css('width', '+=10px')
}
setInterval( expand.bind( this, $('#block') ), 1000 );
CSS
#block {
text-align: center;
margin: 0px auto;
border: 1px solid black;
width: 100px;
}

How to place a div inside a bigger scrollable div at particular position

I have a div with height = 10*screen-height.
I want to add another smaller div to it with height = screen height
Assuming that I can add 10 such smaller div's onto the bigger div, I want to add this div at particular position on the bigger div. Say starting from 4*screenheight pixel. How do I do that using jQuery?
Presumably you already have the screen height stored, and the two divs created at the correct heights, so:
$(inner_div).css('position', 'relative').css('top', 4*screen_height);
You may not need position:relative in your style if it's in your css already
See here how you can access and manipulate the body's height and the big div's inners afterwards;
JSfiddle
HTML
<div id="biggy">
<div class="smally">Smally :)</div>
<div class="smally">Smally 2, don't forget me :D</div>
</div>
CSS
html, body {
height: 100%;
padding: 0px;
margin: 0px;
}
#biggy {
width: 200px;
background-color: orange;
position: relative;
}
.smally {
width: 100%;
background-color: blue;
color: white;
text-align: center;
position: absolute;
}
JavaScript
$(document).ready(function() {
var bh = $('body').height();
var smally_offset = (bh / 10);
// Set biggy to be the body's height
$('#biggy').css('height', bh);
// Make all smallies 10% of the set height
$('.smally').css('height', smally_offset);
// Handle the different smallies :)
$('.smally:nth-child(1)').css('top', smally_offset * 0);
$('.smally:nth-child(2)').css('top', smally_offset * 1);
});

Categories

Resources