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>
Related
I'm trying to make it so that when you click on the button with the class .booking__button, the block scrolls up under the header. Position should not change, only scroll. This is done so that the search results of the booking module, which, would be visible to the user. I found the code that does the scrolling, but it works with the exact number, now 100px, but you understand that this distance will be different for everyone, depending on the height of the screen.
document.querySelector('.booking__button').addEventListener('click', () => {
window.scrollTo(0, 100);
});
body {
margin: 0;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
background: #002164;
}
.hero {
min-height: calc(100vh - 100px);
background: #fff;
}
.booking__module {
display: flex;
justify-content: center;
align-items: center;
background: #BC0B3C;
}
.booking__search {
height: 600px;
background: #ccc;
}
.booking__button {
height: 20px;
margin: 40px;
}
.others {
height: 200vh;
}
<header class="header"></header>
<main class="hero"></main>
<section class="booking">
<div class="booking__module">
<button class="booking__button">booking</button>
</div>
<div class="booking__search"></div>
</section>
<section class="others"></section>
One approach is below, with explanatory comments in the code. Note that while I changed the background-color of the <header> element, that's simply to visualise the functionality and is not at all required:
// we pass a reference to the Event Object ('evt') to the function:
document.querySelector('.booking__button').addEventListener('click', (evt) => {
// we retrieve the closest ancestor <section> element of the element
// to which the event-handler is bound, and retrieve the 'top' property
// of its bounding-client rect:
let {top} = evt.currentTarget.closest('section').getBoundingClientRect();
// we then scroll to that value:
window.scrollTo(0, top);
});
body {
margin: 0;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
/*background: #002164;*/
background-color: hsl(200deg 70% 70% / 0.4);
}
.hero {
min-height: calc(100vh - 100px);
background: #fff;
}
.booking__module {
display: flex;
justify-content: center;
align-items: center;
background: #BC0B3C;
}
.booking__search {
height: 600px;
background: #ccc;
}
.booking__button {
height: 20px;
margin: 40px;
}
.others {
height: 200vh;
}
<header class="header"></header>
<main class="hero"></main>
<section class="booking">
<div class="booking__module">
<button class="booking__button">booking</button>
</div>
<div class="booking__search"></div>
</section>
<section class="others"></section>
JS Fiddle demo.
References:
Element.closest().
Element.getBoundingClientRect().
Event.
Event.currentTarget.
EventTarget.addEventListener().
Window.scrollTo.
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>
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>
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.
I'm new to using JQuery and Javascript. I can't figure out what is wrong here.
I want to h1 element to be displayed as block and to add the class as active as is parent div is showing in the window.
I'm hoping the consequent effect will be somewhat like the 'Y logo' on this site http://www.collectif-yay.com/en
HTML
<div class= "section" id="Title">
<h1 style="position: fixed; top: 10px; display: none">Title</h1>
</div>
<div id="Publications">
<h1 style="position: fixed; top: 10px; display: none">Publications</h1>
</div>
<div class= "section" id="Articles">
<h1 style="position: fixed; top: 10px; display: none">Articles</h1>
</div>
<div class= "section" id="Contributors">
<h1 style="position: fixed; top: 10px; display: none">Contributors</h1>
</div>
<div class= "section" id="Process">
<h1 style="position: fixed; top: 10px; display: none">Process</h1>
</div>
CSS
div{
height: 400px;
display: block;
width: 100%;
padding: 10px;
border: 0;
overflow: hidden;
}
h1 {
top: 10px;
padding-left: 20px;
width: 100%;
color: #0000aa;
}
.section {
padding-top: 100px;
padding-bottom: 0px;
}
.active {
color: #0000aa;
JQuery
$(document).ready(function () {
setup_section_titles();
display_section_titles();
});
$(window).scroll(function () {
display_section_titles();
});
function setup_section_titles() {
$("h1").css("position", "fixed").css("top", "10px");
}
// ----------------------------------------
function display_section_titles() {
var sectionArray = $.makeArray($(".section"));
var window_scroll_top = $(window).scrollTop();
var window_center = $(window).height()/2;
window_center = 100;
// sort sections by their relative distance to the center of the window
sectionArray.sort( function(a, b) {
return getDiff(a, window_scroll_top, window_center) > getDiff(b, window_scroll_top, window_center) ? 1 : -1;
});
$(".section h1:visible").hide();
$(sectionArray[0]).children("h1").show();
$(".active").removeClass("active");
$(sectionArray[0]).addClass("active");
}
// ----------------------------------------
function getDiff(item, window_scroll_top, window_center) {
var item_viewportoffset_top = $(item).offset().top - window_scroll_top;
var dist_of_top = Math.abs(item_viewportoffset_top - window_center);
var dist_of_bottom = Math.abs(item_viewportoffset_top + $(item).height() - window_center);
// return minimum of distances of top and bottom of an element
// to center of the window
return Math.min( dist_of_top, dist_of_bottom );
}