Background image increase size with scroll - javascript

I am trying to make the background image on a div change its scale as per the amount of page scrolled. Works well on desktop screens but on mobile screen, the BG image's height reduces and shrinks the image. This behaviour is apparent as I am trying to resize a sized cover image in % values. I have added a red background-color too to the div for better debugging. Any way to make it work flawlessly even on mob screens? The code is below as well as on Codepen.
HTML:
<main>
<div class="section_1">
<div class="welcome_message">
<div class="welcome_text">
<p class="welcome">Welcome to</p>
<h1>My</h1>
<p class="tagline">DIRECTORY</p>
</div>
</div>
</div>
</main>
CSS:
main{
min-height: 200vh;
}
.section_1{
position: relative;
width: 100%;
height: 90vh;
background: red url(https://images.pexels.com/photos/9467294/pexels-photo-9467294.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260) 40% 10%/cover no-repeat;
display: flex;
justify-content: flex-end;
align-items: flex-end;
}
.section_1 .welcome_message{
width: 80%;
min-height: 100%;
display: flex;
justify-content: flex-end;
align-items: flex-end;
background: none;
padding: 0 1rem 10rem 0;
.welcome_text{
z-index: 3;
// color: white;
background-color: rgba(1, 55, 131, 0.5);
border-bottom: 0.5rem solid white;
padding: 1rem 2rem;
border-end-start-radius: 2rem;
}
.welcome{
color: white;
font-weight: 400;
}
h1{
font-size: 2rem;
color: white;
font-weight: 600;
margin-block: -0.3em;
}
.tagline{
color: white;
font-weight: 400;
}
}
JS:
let bg = document.querySelector('body .section_1')
document.addEventListener('scroll', () => {
let x = window.pageYOffset
bg.style.backgroundSize = (100 + x/10)+'% auto'
})

you almost made it instead of using auto use the calculated width and set the height to 100%
bg.style.backgroundSize = ''+(130 + x/10)+'% 100%'
Codepen :)

Because you scroll all the way top again, bg.style.backgroundSize = 'auto 130%', The value of bg.style.backgroundSize should null.

Related

How to start my progress bar counting after navigating the container section of my web page

How to start my progressbar counting when i will go to container section of my webpage.I think i have to change my javascript code a bit please help me.
HTML CODE
<div class="container">
<div class="circular-progress">
<span class="progress-value">100%</span>
</div>
<span class="text">HTML & CSS</span>
</div>
<!-- JavaScript -->
<script src="js/script.js"></script>
CSS CODE
/* Google Fonts - Poppins */
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#300;400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body{
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #7d2ae8;
}
.container{
display: flex;
width: 420px;
padding: 50px 0;
border-radius: 8px;
background: #fff;
row-gap: 30px;
flex-direction: column;
align-items: center;
}
.circular-progress{
position: relative;
height: 250px;
width: 250px;
border-radius: 50%;
background: conic-gradient(#7d2ae8 3.6deg, #ededed 0deg);
display: flex;
align-items: center;
justify-content: center;
}
.circular-progress::before{
content: "";
position: absolute;
height: 210px;
width: 210px;
border-radius: 50%;
background-color: #fff;
}
.progress-value{
position: relative;
font-size: 40px;
font-weight: 600;
color: #7d2ae8;
}
.text{
font-size: 30px;
font-weight: 500;
color: #606060;
}
Javascriptcode
let circularProgress = document.querySelector(".circular-progress"),
progressValue = document.querySelector(".progress-value");
let progressStartValue = 0,
progressEndValue = 90,
speed = 100;
let progress = setInterval(() => {
progressStartValue++;
progressValue.textContent = `${progressStartValue}%`
circularProgress.style.background = `conic-gradient(#7d2ae8 ${progressStartValue * 3.6}deg, #ededed 0deg)`
if(progressStartValue == progressEndValue){
clearInterval(progress);
}
}, speed);
When i load my page at first then progressbar is count value But i want to start the counting after i go to that section of that webpage.
You could use Intersection Observer. You choose an HTML element to observe and once this element is in view, that will trigger the start of the progress bar.

How to stop pages from creating scrollbar

I am having this trouble with my game in where the screen creates a small scroll bar and the page won't fit on one screen. When I try changing the height in my body and html tags it seems like nothing is happening and when I try overflow:hidden it just stops me from getting to my play again button and doesn't actually fit the game onto one single page.
Here is the game link
https://jobaa11.github.io/connect-4-project-1/
This is my CSS for my body and main
body {
margin: 0;
height: 100vh;
display: grid;
justify-content: stretch;
align-items: center;
background-color: var(--blue);
}
main {
display: grid;
justify-content: center;
margin: 0;
}
I've tried several different options, but that scrollbar has been very persistent. Any suggestions?
This is also my footer which holds my play-again button that keeps causing the scroll bar issue I believe.
footer {
display: flex;
justify-content: space-evenly;
font-family: 'Press Start 2P', sans-serif;
color: rgb(75, 57, 57);
}
footer>button {
margin-top: 10px;
outline-style: groove;
background-color: #FEDF49;
border-radius: 5%;
font-family: 'Press Start 2P', sans-serif;
font-size: small;
}
footer>button:hover {
transform: scale(1.1);
opacity: 80;
color: red
}
#replay-again-btn {
cursor: pointer;
}
add to your css :
body {
margin: 0;
height: 100vh;
overflow:hidden;
display: grid;
justify-content: stretch;
align-items: center;
background-color: var(--blue);
}

Scroll 100vh within a div?

I'm trying to make a button that scrolls down 100vh (one window height) on click. I have it so that 30vh of width is fixed and the scrolling portion is the 70% on the right. I'm wondering why my code doesn't do anything when I use window.scrollBy?
HTML:
<Content>
<Intro />
<TypewriterSpace>
<Typewriter />
<Button onClick={this.handleClick}>View my work</Button>
</TypewriterSpace>
</Content>
CSS:
let TypewriterSpace = styled.div`
margin-left: 6rem;
margin-right: 20rem;
margin-top: -1rem;
position: relative;
`
let Content = styled.div`
height: 100vh;
width: 70vw;
display: flex;
flex-direction: column;
float: right;
overflow: auto;
`
const Button = styled.button`
font-family: "Avenir";
height: 3em;
width: 10em;
color: white;
border: 2px solid white;
background: #1d1d20;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
position: absolute;
transition: 0.5s;
margin-top: 4em;
left: 35%;
margin-top: 60vh;
&:hover{
color: #1d1d20;
border: 2px #1d1d20;
background: white;
}
`;
My handeClick function:
handleClick(e) {
let pageHeight = window.innerHeight;
window.scrollBy(0, pageHeight);
}
notice that you are keeping your div height to 100vh and also scrolling for the same!
as div height is 100vh which is equal to the browser screen height, so there ll not be a scope for scroll,
so the point is that you trying to scroll in the div which does not have any content more than screen height...
If you want to try you can try to by setting height: 110vh; of the content and then scrollby window.innerHeight which ll have some content to scroll so it ll scroll!
I hope this would help you!
thank you!
Keep Coding!

Calculate height of div based off width & maintain proportion [duplicate]

This question already has answers here:
Maintain the aspect ratio of a div with CSS
(37 answers)
Closed 3 years ago.
I am looking for a pure CSS solution to what I have here done using jQuery to help.
Basically I have 3 divs that spread evenly in width in a container. They maintain a 3/4 ration with the height being calculated off of the width. Furthermore, each div has a background image that stays proportional and some text that is centered horizontally and vertically.
$(document).ready(function() {
function setw() {
var footdivwidth = $('footer div').width();
var footdivheight = footdivwidth * .75;
$('footer div').css({
'height': footdivheight + 'px'
});
$('footer div span').html('w: ' + footdivwidth + '<br>h: ' + footdivheight);
}
setw();
$(window).resize(function() {
setw();
})
});
FOOTER {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
FOOTER DIV {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
FOOTER DIV SPAN {
display: inline-block;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
Here is a pen showing what I have.
https://codepen.io/nom3d/pen/arGpBV
Here is a gif showing the effect when resized. Note the background image staying proportional and text staying centered.
Also wondering if it's not possible with just CSS, how to do this with plain javascript, would I need to add id's to my divs?
Update: here is a plain javaScript function to handle this task
function setHeight(el,val){
var box = document.querySelectorAll(el);
var i;
for(i = 0;i < box.length;i++){
var width = box[i].offsetWidth;
var height = width * val;
box[i].style.height = height + 'px';
}
}
// set your element to target and the ratio value
setHeight('footer div',.75);
window.onresize = function(event) {
setHeight('footer div',.75);
};
Maintaining specific height:width ratios in CSS is usually done by exploiting the fact that padding percentage is always calculated based on the element's width.
For example, let's say you had an element with width: 500px, height: 300px and padding: 10%. Now you might expect the top and bottom paddings to be 10% of height, and the left and right paddings to be 10% of width. However this would give unequal vertical and horizontal paddings which is counter-intuitive to what is intended - equal paddings of 10%. To make sense of this we need to base the padding percentage on the save dimension, and that dimension has been chosen to be the width.
Thus to have an element with height:width ratio of 3:4 at all times we can set the height to 0 and the bottom (or top) padding to 3/4 of the width.
In your example each item is given a width of 33% by Flex. For a ratio of 3:4 the bottom padding should be 33% * 3 / 4, or 24.74%. Your CSS might look like:
width: 33%;
height: 0;
padding-bottom: 24.75%;
Note that since the height is 0, the element will need to be relatively positioned with an absolutely positioned wrapper inside it. If you attempt to put content directly in the div, it will break the ratio. Your code above could be modified thus:
footer {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
footer div {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
position: relative;
width: 33%;
height: 0;
padding-bottom: 24.75%;
}
footer div span {
/* Used as content wrapper, with flex to centre content */
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
Here's a more generic way to go about this for anyone who doesn't want to dig through the OP's code and just needs a solution to responsive fixed ratio elements with CSS.
The basic idea is that padding as a percentage is calculated based on the element's width. This means that padding-bottom: 100% == element.width (In this case a square). We can hijack that trick by calculating the ratio and using that for padding.
Image Example
Images are a bit odd in that they already have an aspect ratio so you could simply set the height: auto and be good to go.
Ratio: 4:3
img {
--aspectRatio: calc(3/4 * 100%);
display:block;
width: 300px; // this one needs a width to work.
height:var(--aspectRatio);
}
<img src="https://images.unsplash.com/photo-1559666126-84f389727b9a" />
Image Background
But let's say you want the container to manage the size regardless of the original content ratio? Simply use a background image.
This one is 16:9 (typical widescreen)
.fixedAspect {
--aspectRatio: calc(9/16 * 100%);
height: 0;
padding-bottom: var(--aspectRatio);
background-size: cover;
background-position: center center;
}
<div class="fixedAspect" style="background-image: url(https://images.unsplash.com/photo-1559662780-c3bab6f7e00b)"></div>
HTML Element with content
Adding content to an element with a height:0 and a bunch of padding is probably not the best solution. But we can solve this by using a pseudo-class. To force a "minimum height".
Bonus: This won't break if your content is bigger than the aspect ratio you've defined the way a position: absolute; wrapper would.
.fixedAspect {
margin: 20px;
background-color: #f6f3f0;
}
p {
font-family: Helvetica, Arial, Sans-Serif;
padding: 10px;
}
.fixedAspect:before {
--aspectRatio: calc(5/20 * 100%);
content: "";
height:0;
padding-top: var(--aspectRatio);
/* so you can see the element */
background-color: #F47E20;
/* get this out of the way */
float: left;
width: 1px;
margin-left:-1px;
}
.fixedAspect:after {
/* we need to clear the float so its container respects height */
content: "";
display: table;
clear: both;
}
<div class="fixedAspect">
<p>My default size is a ratio of 20:5 but I'll grow if there's too much content.</p>
</div>
You can simply consider the basic trick for maitaining the aspect ratio using padding.
Here is an example where I kept both examples so you can compare, the one using jQuery and the other using pure CSS.
$(document).ready(function() {
function setw() {
var footdivwidth = $('footer div').width();
var footdivheight = footdivwidth * .75;
$('footer.no-padd div').css({
'height': footdivheight + 'px'
});
$('footer div span').html('w: ' + footdivwidth + '<br>h: ' + footdivheight);
}
setw();
$(window).resize(function() {
setw();
})
});
FOOTER {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
FOOTER DIV {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex
}
FOOTER:not(.no-padd) DIV:before {
content:"";
padding-top: 75%;
}
FOOTER DIV SPAN {
margin:auto;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer class="no-padd">
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
<footer >
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
A quick pure CSS solution would involve to add to FOOTER DIV
max-width: 333px;
width: calc(100vw/3);
height: calc(100vw*0.75/3);
max-height: calc(333px*0.75);
and add to FOOTER
width: 100vw;
// Javascript is only used in order to check the width/height ratio in console live.
$(document).ready(function() {
$(window).resize(function() {
console.log('width: ' + $('footer div').width() + ', height: ' + $('footer div').height());
});
});
FOOTER {
max-width: 1000px;
width: 100vw;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
/*justify-content: space-between;*/
}
FOOTER DIV {
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
max-width: 333px;
width: calc(100vw/3);
height: calc(100vw*0.75/3);
max-height: calc(333px*0.75);
}
FOOTER DIV SPAN {
display: inline-block;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
Have you tried with
footer div {
height: 20vw;
}
there is also calc property for css which could be helpful
https://developer.mozilla.org/en-US/docs/Web/CSS/calc
Probably a bit late, but will add my solution as well.
I thought I should keep it a general solution, so I decided to not use your Footer classes. But I'm sure you'll get the trick.
In my opinion the easiest way is to use the padding calculation to get a fixed ratio and some divs.
Flex container
Flex items (with the padding on it): This container is used to maintain the resolution. The amount of padding for it depends on the width of the item.
For example: Item width = 100% --> Padding = (100/4)*3 --> 75% padding
Content container inside Flex-Item where you can put your stuff
Background-Div inside the content container
put everything you need as sibling to the background-div
Here's a fiddle to play around, some comments are in the code: https://jsfiddle.net/Hoargarth/Lry5gbsq/
Feel free to ask if you need anything
Just a quick note on all of those containers:
You could do it with just the flex-item and one other container. But in my opinion, with the extra container it get's more flexible if you need any hover-events, animations or som other exotic stuff.
For the simple solution see this fiddle: https://jsfiddle.net/Hoargarth/m57b9jcw/
.container {
width: 100%;
display: flex;
flex-wrap: wrap;
}
/* padding bottom gives the height of the container, 33.33% padding would be a quadratic box. 100% would be the same height as the container's width. Therefore simple trignomometry, (100/4) * 3 = 75%; or for screen width > 500px: (33.33 / 4) * 3 for a 4/3 resolution. You'll find the media query at the end of the css. It's just to demonstrate that it's working with media queries as well. */
.item {
position: relative;
width: 100%;
padding-bottom: 75%;
}
/* Overflow hidden so nothing can overlap to the other items */
.content-wrapper {
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
}
.image-holder {
position: relative;
height: 100%;
background-image: url("https://previews.123rf.com/images/happydancing/happydancing1706/happydancing170600014/80282512-flat-lay-photo-of-workspace-desk-with-laptop-smartphone-blank-notebook-and-green-plant-with-copy-spa.jpg");
background-size: cover;
background-position: 50%;
background-repeat: no-repeat;
}
/* Absolute positioned by 50% top, left; To completely center it, you have to translate the holder back by it's own half width and height transform: translate(-50%, -50%) */
.text-holder {
position: absolute;
top: 50%;
left: 50%;
padding: 10px;
width: 70%;
background-color: rgba(255, 255, 255, 0.5);
transform: translate(-50%, -50%);
text-align: center;
}
/* Simple media Query to test it. Be aware: If the item's width is changing, the padding has to change as well */
#media (min-width: 500px) {
.item {
width: 33.33%;
padding-bottom: 24.75%;
}
}
<div class="container">
<div class="item">
<div class="content-wrapper">
<div class="image-holder"></div>
<div class="text-holder">
<p>
Some Centered Text
</p>
</div>
</div>
</div>
<div class="item">
<div class="content-wrapper">
<div class="image-holder"></div>
<div class="text-holder">
<p>
Some Centered Text but larger and longer so we see a difference
</p>
</div>
</div>
</div>
<div class="item">
<div class="content-wrapper">
<div class="image-holder"></div>
<div class="text-holder">
<p>
Groot
</p>
</div>
</div>
</div>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
FOOTER {
max-width: 1000px;
margin: 0 auto;
background-color: rgba(0, 0, 0, 0.171);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
FOOTER DIV {
position: relative;
width: calc(100vw / 3);
height: calc(100vw / 3 * 0.75 );
max-height: calc(1000px / 3 * 0.75 );
background-image: url('https://learnwebdesign.online/img/bg.jpg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
flex: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
FOOTER DIV SPAN {
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
text-align: center;
background-color: rgba(165, 165, 165, 0.282);
padding: 7px 15px;
border-radius: 3px;
color: #FFFFFF;
text-transform: uppercase;
font-weight: bold;
letter-spacing: 2px;
font-size: 21px;
}
</style>
</head>
<body>
<footer>
<div><span>left photo</span></div>
<div><span>center photo</span></div>
<div><span>right photo and more text</span></div>
</footer>
</body>
</html>
You can Directly use given code, For making propostional width height, You have 2 different ways, one of them given below, you can use width in percentage and height with calc with the same,
another way give width in %, and instead of height you can give padding-bottom in percentage, the all are in same propostion.
PURE CSS FIX
Adjust width and height accordingly
footer {
display: flex;
width: 100vw;
align-items: center;
justify-content: center;
}
.responsive-box {
width: 33vw;
border: 1px solid blue;
max-width: 333px;
min-width: 35px;
flex-flow: row;
height: 60vh;
position: relative;
}
.responsive-box span {
position: absolute;
top:40%;
bottom:0;
left:0;
right:0;
text-align: center;
}
<footer>
<div class="responsive-box left"><span>left photo</span></div>
<div class="responsive-box center"><span>center photo</span></div>
<div class="responsive-box right"><span>right photo and more text</span></div>
</footer>

responsive width of (float left) div according to distance to adjacent (float right) div

I am trying to use text ellipsis on a (float left) div which is 'sandwiched' between a (float left) div and a (float right) div.
[float left][float left (needs width for elipsis)] [float right]
My problem is that to use text ellipsis I need to specify width or max-width of the 'sandwiched' div. But I do not know how to do this, because that width depends on the distance to the adjacent (float right) div, which depends on browser window width.
Please check the codepen below. If you shrink the browser window's width you will see that the info icon jumps to next line when colliding with the text I need to ellide.
To put it simply, I would like both L/R arrows and info icon to stay leftmost and rightmos respectively, no matter window width, and the text in the middle to elide according to window width.
I searched and I see I could do this with calc, but I am looking for a not so experimental solution.
Thank you very much.
http://codepen.io/anon/pen/vLMBMJ
here is HTML code
<div id="footer">
<div id="subie">
<div id="control">
<button id="prv" class="button">←</button>
<button id="pos" class="button">→</button>
</div>
<div id="title">
<span id="page">Gloria Anzaldúa- Borderlands, La Frontera, The New Mestiza</span>
</div>
<div id="info">
<button id="" class="button"><img src="http://findicons.com/files/icons/2232/wireframe_mono/32/info.png" width="33px"></button>
</div>
</div>
</div>
and CSS
#footer {
position: fixed;
margin: 0px;
padding: 0px;
bottom: 0px;
height: 5.5vh;
width: 100vw;
background-color: #ffffff;
z-index: 100;
}
#subie {
position: absolute;
left: 51vw;
width: 42vw;
height: 5.5vh;
margin: 0px;
padding: 0vh 1vw 0vh 1vw;
}
#control {
float: left;
text-align: left;
display: flex;
align-items: center;
height: 5.5vh;
}
#title {
float: left;
text-align: left;
display: flex;
align-items: center;
height: 5.5vh;
width: ;
}
#info {
float: right;
display: flex;
align-items: center;
height: 5.5vh;
}
.button {
background-color: transparent;
border: none;
margin: none;
padding: none;
color: black;
text-align: left;
text-decoration: none;
display: inline-block;
cursor: pointer;
outline: 0;
font-size: 1em;
}

Categories

Resources