Changing position of absolute element without container overflow - javascript

Maybe an obvious question but how do I make an element with a absolute position not overflow its container when moving it's position right? I know I could change it to relative position or move it 99% but for my project that won't due. I tried using margins, padding, object-fit, all with no success. Thanks for any help
var green = document.getElementById('green');
function myFunct() {
green.style.right = '100%';
}
h1 {
position: relative;
width: 80%;
height: 100px;
margin: auto;
background-color: red;
}
#green {
position: absolute;
right: 0px;
height: 100px;
background-color: green;
width: 20px;
}
<h1>
<div id = 'green'></div>
</h1>
<button onclick="myFunct()">FindHighScore</button>

Use CSS calc()
var green = document.getElementById("green");
function myFunct() {
green.style.right = "calc(100% - 20px)";
}
Or, apply left: 0 and right: auto (reset)
var green = document.getElementById("green");
function myFunct() {
green.style.left = "0";
green.style.right = "auto";
}
A <div> should not be in a <h1> tag by the way.

You can set overflow to hidden at parent container.
<h1> permitted content is Phrasing content
var green = document.getElementById('green');
function myFunct() {
green.style.right = '100%';
}
div:not(#green) {
position: relative;
width: 80%;
height: 100px;
margin: auto;
background-color: red;
overflow: hidden;
}
#green {
position: absolute;
right: 0px;
height: 100px;
background-color: green;
width: 20px;
}
<div>
<div id='green'></div>
</div>
<button onclick="myFunct()">FindHighScore</button>

Related

How to achieve the same function of position:sticky using jQuery or JavaScript?

I'm having a hard time figuring out why the code below doesn't work as expected.
What I'm trying to achieve is same functionality with position:sticky whereas when the scrolled reaches the top of the #second-header then fixes its position below the #header which is also fixed, however, the height of the #header is unknown which is I believe can be calculated using the function outerHeight(true) on JQuery.
Then after reaching out to the bottom of the #second-header-container, remove the fixed position of #second-header turning it back to normal position.
Due to browser compatibility issues and other customization, I cannot simply use the position:sticky of css.
It looks like my logic is wrong, and I need help.
jQuery(document).ready(function(){
var $document = jQuery(document);
var header = jQuery('#header');
var second_header = jQuery('#second-header-container').find('#second-header');
var second_header_container = jQuery('#second-header-container');
var second_header_offset = second_header.offset().top;
var second_header_container_offset = second_header_container.offset().top;
jQuery(window).scroll(function(){
var top_margin = header.outerHeight(true);
var second_header_height = second_header.outerHeight(true);
var second_header_container_height = second_header_container.outerHeight(true);
if( jQuery(window).scrollTop() > (second_header_offset - second_header_height) && jQuery(window).scrollTop() < second_header_container_height) {
second_header.addClass('fixer');
second_header.css({position:'fixed', top:top_margin, 'z-index':'999999'});
} else {
second_header.removeClass('fixer');
second_header.css({position:'relative', top:'0px', 'z-index':'0'});
}
});
});
*{
color: #FFFFFF;
padding: 0;
margin: 0;
}
.fixer{
position: fixed;
width: 100%;
}
#header, .banner, #second-header, .contents{
padding: 5px;
}
#header{
position: fixed;
width: 100%;
height: 74px;
z-index: 99999;
background-color: #000000;
}
.banner{
padding-top: 84px;
height: 200px;
background-color: #583E5B;
}
#second-header-container{
min-height: 300px;
background-color: #775F5E;
}
#second-header{
padding-bottom: 10px;
padding-top: 10px;
background-color: #4C3D3C;
}
.contents{
min-height: 200px;
background-color: #97A36D;
}
.footer{
background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
<div id="second-header">SECOND-HEADER</div>
<!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>
To achieve this you need first check if the scroll height is near the second div header and within the height of the second div. Then add a class that make it stick below the main header. I have created a sticky class and added it while scrolling conditions are met.
Please check below code
jQuery(document).ready(function() {
var headerHeight = $('#header').outerHeight(true);
var secondHeaderContainer = $('#second-header-container');
const secondHeaderTopPos = secondHeaderContainer.offset().top;
const secondHeaderContainerHeight = $(secondHeaderContainer).height();
$(window).scroll(function() {
const scrollTop = $(this).scrollTop();
const secondContainerHeightEnd = secondHeaderContainerHeight + secondHeaderTopPos - $('#second-header').height() - headerHeight;
if (((secondHeaderTopPos - headerHeight) <= scrollTop) && (secondContainerHeightEnd >= scrollTop)) {
$('#second-header').addClass('sticky').css('top', headerHeight);
} else {
$('#second-header').removeClass('sticky');
}
});
});
* {
color: #FFFFFF;
padding: 0;
margin: 0;
}
.sticky {
position: fixed;
width: 100%;
top: 0;
left: 0;
}
.fixer {
position: fixed;
width: 100%;
}
#header,
.banner,
#second-header,
.contents {
padding: 5px;
}
#header {
position: fixed;
width: 100%;
height: 74px;
z-index: 99999;
background-color: #000000;
}
.banner {
padding-top: 84px;
height: 200px;
background-color: #583E5B;
}
#second-header-container {
min-height: 300px;
background-color: #775F5E;
}
#second-header {
padding-bottom: 10px;
padding-top: 10px;
background-color: #4C3D3C;
}
.contents {
min-height: 200px;
background-color: #97A36D;
}
.footer {
background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
<div id="second-header">SECOND-HEADER</div>
<!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>

I am not able to add and remove the classes

My Code:
window.addEventListener('scroll', scrollWhere);
function scrollWhere(e) {
var windowScroll = $(window).scrollTop();
var idScroll = $('.me').offset().top;
var height = $("#half-who").height();
if (windowScroll > idScroll) {
$('.me').addClass('me-fixed');
} else {
$('.me').removeClass('me-fixed');
}
}
I want to add a class when the scroll is past a certain point and remove it when is smaller than that certain point.
Get your idScroll value outside scrollWhere function as because it re-initiate calculation again and again and returns different values each time as because it has a fixed position. check below snippet for reference.
window.addEventListener('scroll', scrollWhere);
var idScroll = $('.me').offset().top;
function scrollWhere(e) {
var windowScroll = $(window).scrollTop();
//var height = $("#half-who").height();
if (windowScroll > idScroll) {
$('.me').addClass('me-fixed');
} else {
$('.me').removeClass('me-fixed');
}
}
.container {
height: 300vh;
width: 100%;
background-color: grey;
padding: 0;
margin: 0;
}
.content {
height: 100px;
width: 100%;
background-color: cyan;
}
.me {
height: 50px;
width: 100%;
background-color: red;
}
.me-fixed {
position: fixed;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content"></div>
<div class="me"></div>
</div>
Here's a simple example to add a class when scroll passing a certain point. Hope you can get an idea. >>> JSFiddle
$(window).scroll(function(){
var winH = $(window).scrollTop();
var ruler = $('.ruler').position().top;
if(ruler < winH){
$('.nav').addClass('me-fixed');
}
else{
$('.nav').removeClass('me-fixed');
}
});
body{
height: 1500px;
}
.nav{
height: 50px;
background: #a1bfbe;
color: #000;
width: 100%;
position: relative;
top: 250px;
text-align: center;
}
.nav.me-fixed{
background: #c2debf;
}
p{
font-size: 20px;
display: none;
}
.me-fixed p{
display: block;
}
.ruler{
position: fixed;
top: 150px;
border-bottom: 1px solid red;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav">
<p>
Fixed
</p>
</div>
<div class="ruler">
</div>
Also if you can provide the html and css structure, it will be easy to identify the issue.

Resize a div to largest possible square in container [duplicate]

This question already has an answer here:
CSS square with dynamic height
(1 answer)
Closed 5 years ago.
How can I resize a div to be the largest possible square within its container using CSS? If it is not possible with CSS, how can it be done with JavaScript?
If the container has height > width I would like the size of the square to width x width. If the container has width > height I would like the size the square to be height x height.
When the dimensions of the container changes the dimensions of the child should adjust accordingly.
I found this answer to be helpful to maintain the aspect ratio of the child. This approach doesn't work when the width of the container is larger than the height as the child overflows the parent as demonstrated in the following snippet.
.flex {
display: flex;
}
.wide,
.tall {
flex: none;
border: 3px solid red;
}
.wide {
width: 150px;
height: 100px;
}
.tall {
width: 100px;
height: 150px;
}
div.stretchy-wrapper {
width: 100%;
padding-bottom: 100%;
position: relative;
background: blue;
}
div.stretchy-wrapper>div {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
color: white;
font-size: 24px;
text-align: center;
}
<div class="flex">
<div class="wide">
<div class="stretchy-wrapper">
<div>Wide container</div>
</div>
</div>
<div class="tall">
<div class="stretchy-wrapper">
<div>Tall container</div>
</div>
</div>
</div>
Get width and height of all .stretchy-wrapper and parent of the same using map().
Now using a for loop assign max value to it parent.
Then $(window).resize call resizeDiv function whenever browser window size changes.
$(document).ready (function () {
function resizeDiv () {
var stretchyWrapper = $(".stretchy-wrapper"),
sWrapperWidth = stretchyWrapper.map (function () {
return $(this).width ();
}),
sWrapperHeight = stretchyWrapper.map (function () {
return $(this).height ();
}),
container = stretchyWrapper.map (function () {
return $(this).parent ();
});
for (var i in container) {
var maxVal = Math.max (sWrapperWidth[i], sWrapperHeight[i]);
$(container[i]).css ({"width": maxVal, "height": maxVal});
}
}
resizeDiv ();
$(window).resize (function () {
resizeDiv ();
});
});
.flex {
display: flex;
}
.wide,
.tall {
flex: none;
border: 3px solid red;
}
.wide {
width: 150px;
height: 100px;
}
.tall {
width: 100px;
height: 150px;
}
div.stretchy-wrapper {
width: 100%;
padding-bottom: 100%;
position: relative;
background: blue;
}
div.stretchy-wrapper>div {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
color: white;
font-size: 24px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex">
<div class="wide">
<div class="stretchy-wrapper">
<div>Wide container</div>
</div>
</div>
<div class="tall">
<div class="stretchy-wrapper">
<div>Tall container</div>
</div>
</div>
</div>

How do I loop multiple scripts in javascript?

I have some code here and I want the squares to go blue, green, indigo then go back to the beginning. Each time I click the button the colour will change. The code here goes blue, green, indigo and then changes between indigo and black while I want it to go to blue again. Is there a way of restarting the entire code again?
<--code for animated squares!-->
<!DOCTYPE html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
background: Black;
}
div#animate {
width: 50px;
height: 50px;
position: absolute;
left: 175px;
top: 0px;
background-color: Blue;
}
</style>
<style>
#containertwo {
width: 400px;
height: 400px;
position: relative;
background: Black;
}
div#animatetwo {
width: 50px;
height: 50px;
position: absolute;
left: 175px;
top: 175px;
background-color: Black;
}
</style>
<body>
<style>
#containerthree {
width: 400px;
height: 400px;
position: relative;
background: Black;
}
div#animatethree {
width: 50px;
height: 50px;
position: absolute;
left: 175px;
top: 350px;
background-color: Black;
}
</style>
<body>
<p>
<button onClick="button_click();button_clicktwo();button_clickthree()">Change Colour</button>
</p>
<div id ="container">
<div id ="animate"></div>
<div id ="animatetwo"></div>
<div id ="animatethree"></div>
</div>
<div id="box" onClick="button_click(j)();"></div>
<script>
var colors = ["Black","Black","Blue"];
function button_click() {
var box = document.getElementById("animate");
var background_color = box.style.backgroundColor;
var i = colors.indexOf(background_color);
if (i === colors.length-1) {
i = -1;
}
animate.style.backgroundColor = colors[i+1];
}
</script>
<div id="box" onClick="button_clicktwo();"></div>
<script>
var colorstwo = ["Green","Black","Black",];
function button_clicktwo() {
var box = document.getElementById("animatetwo");
var background_color = box.style.backgroundColor;
var i = colorstwo.indexOf(background_color);
if (i === colorstwo.length-1) {
i = -1;
}
animatetwo.style.backgroundColor = colorstwo[i+1];
}
</script>
<div id="box" onClick="button_clickthree();"></div>
<script>
var colorsthree = ["Black","Indigo","Black"];
function button_clickthree() {
var box = document.getElementById("animatethree");
var background_color = box.style.backgroundColor;
var i = colorsthree.indexOf(background_color);
if (i === colorstwo.length-1) {
i = -1;
}
animatethree.style.backgroundColor = colorsthree[i+1];
}
</script>
There's quite a bit of invalid and repetitive code, so for simplicity, I just reworked the entire thing. I'll note some of the problems below.
Since there were so many changes made to the HTML, CSS and JS, I won't list them all, but will leave it to you to observe the differences.
// Gather the colors and elements, and set a shared `i` to `0`
var colors = ["Blue", "Green", "Indigo"];
var elems = document.querySelectorAll(".animate");
var i = 0;
// Have a single function that makes the current element black and the next
// one a different color
function button_click() {
elems[i].style.backgroundColor = "Black";
if (++i === colors.length) {
i = 0
}
elems[i].style.backgroundColor = colors[i];
}
#container {
width: 400px;
height: 400px;
position: relative;
background: Black;
}
.animate {
width: 50px;
height: 50px;
left: 175px;
position: absolute;
}
.animate:nth-child(1) {
top: 0px;
background-color: Blue;
}
.animate:nth-child(2) {
top: 175px;
}
.animate:nth-child(3) {
top: 350px;
}
<p>
<button onClick="button_click();">Change Colour</button>
</p>
<div id="container">
<div class="animate"></div>
<div class="animate"></div>
<div class="animate"></div>
</div>
Note that there are other ways to do this too, like having each color set in the CSS, and then setting the visibility to hidden or visible with JavaScript.
Some of the general problems were:
the same ID attribute used more than once
an extra <body> tag
lots of repeating CSS, JS and HTML that was able to be greatly reduced

Div Moving position and z index

Hope someone can help me, I don't know where to look it up
I'm trying to do an onclick event that will change the position of 3 Divs.
The DIVS are placed like on a hoizontal circle, which means the one in the middle should be z-index: 1
left and right z-index: -1
onclick, the left should slide to the middle and change z-index
right go to the left and middle to the right.
How can I try to do that?
Started like this, but will not change position correctly.
jsFiddle
code snippet:
var i = 0;
while(i < (threeleft-50)){
var plus = (i)%2;
three.style.left = (threeleft-i)+'px';
two.style.left = (twoleft+plus)+'px';
one.style.left = (oneleft+plus)+'px';
i++;
}
Also still need a little of animation if there is a better way to do that, let me know
Thanks so far
One issue is that during the while the screen is not updated so you will only see the final position and not the animation. Then the plus = i%2 will always return 0 or 1. so that is what gets added to the two and one positions. (you most likely need var plus = i/2; there)
In general i would use CSS for positioning/animating (through transitions) the elements and just changes classes with JS. Much cleaner and more maintainable.
function goleft() {
var one = document.querySelector('.pos-one'),
two = document.querySelector('.pos-two'),
three = document.querySelector('.pos-three');
one.classList.remove('pos-one');
one.classList.add('pos-two');
two.classList.remove('pos-two');
two.classList.add('pos-three');
three.classList.remove('pos-three');
three.classList.add('pos-one');
}
function right() {
var one = document.querySelector('.pos-one'),
two = document.querySelector('.pos-two'),
three = document.querySelector('.pos-three');
one.classList.remove('pos-one');
one.classList.add('pos-three');
two.classList.remove('pos-two');
two.classList.add('pos-one');
three.classList.remove('pos-three');
three.classList.add('pos-two');
}
.wrapper {
position: relative;
width: 800px;
height: 400px;
margin-top: 100px;
margin-left: auto;
margin-right: auto;
background-color: grey;
}
.pic {
width: 300px;
height: 300px;
position: absolute;
border: 3px solid black;
transition: all 0.5s;
}
#one {
background-color: red;
}
#two {
background-color: blue;
}
#three {
background-color: green;
}
.pos-one {
z-index: 150;
top: 50px;
left: 250px;
}
.pos-two {
z-index: 50;
top: 40px;
left: 50px;
}
.pos-three {
z-index: 50;
top: 40px;
left: 450px;
}
#bot {
position: absolute;
bottom: 0px;
left: 360px;
}
<div class="wrapper">
<div class="pic pos-one" id="one">1</div>
<div class="pic pos-two" id="two">2</div>
<div class="pic pos-three" id="three">3</div>
<div id="bot">
<button onclick="goleft()">left</button>
<button onclick="right()">right</button>
</div>
</div>

Categories