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>
Related
I'm trying to achieve this effect:
And as the screen is being reduced in size, and more letters of my H1 start to overlap the image, I would like them to change color to white. Eventually, when the screen is small enough, the text can just be inside the container that has a background image.
Here's the code I have so far:
.container {
max-width:1350px;
margin:0 auto;
background-image: url(https://houniqueconstruction.com/wp-content/uploads/2023/02/kam-idris-_HqHX3LBN18-unsplash-scaled.jpg);
background-position: bottom left;
background-repeat: no-repeat;
background-size: cover;
padding-top:15em;
padding-bottom:15em;
position:relative;
}
.overlay {
background-color: transparent;
background-image: linear-gradient(90deg, #FFFFFF 30%, #F2295B00 0%);
opacity: 1;
transition: background 0.3s, border-radius 0.3s, opacity 0.3s;
height: 100%;
width: 100%;
top: 0;
left: 0;
position: absolute;
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
}
h1 {
font-size:60px;
letter-spacing:9px;
text-transform:uppercase;
}
.custom-cta {
display:block;
max-width:100px;
margin-top:10px;
text-align:center;
background:gold;
padding:20px 40px;
}
<div class="container">
<div class="overlay">
<div class="text-box">
<h1>Complete </br>Remodeli<span style="color:white;">ng</span></h1>
<p style="max-width:300px;">With 30 years of experience and a track record of successful projects, we have the skills and expertise to remodel your house with precision, efficiency, and minimal stress for you.</p>
<a class="custom-cta">Contact Us</a>
</div>
</div>
</div>
I would solve this by making layers. Consider having 2 layers:
A front layer with black text
A back layer with white text and the image.
Now the trick is getting the texts of both the texts to overlap perfectly. Use CSS Grid to create the layout and place the text and image where you need them. With some creative clipping (overflow: hidden) and layer ordering (z-index) you can control where the black text stops and where the white continues.
This will create an illusion of the color changing based on the screen size.
*, *::before, *::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
.container {
display: grid;
max-width: 1350px;
width: 100vw;
height: 100vh;
}
.layer {
grid-area: 1 / 1;
display: grid;
grid-template-columns: 30vw 70vw;
}
:is(.layer--front, .layer--back) .layer__title {
display: block;
font-weight: 700;
font-size: 60px;
letter-spacing: 9px;
text-transform: uppercase;
margin: 0 0 1rem;
}
.layer--front {
z-index: 2;
}
.layer--front .layer__title {
color: black;
}
.layer--back .layer__title {
color: white;
}
.layer__content {
grid-area: 1 / 1;
padding: 6rem 2rem;
z-index: 1;
}
.layer--front .layer__content {
overflow: hidden;
}
.layer__image {
grid-area: 1 / 2;
position: relative;
}
.layer__image img {
position: absolute;
inset: 0;
height: 100%;
width: 100%;
padding: 1rem 1rem 1rem 0;
object-fit: cover;
object-position: left;
}
.custom-cta {
display: block;
margin-top: 10px;
text-align: center;
background: gold;
padding: 10px 20px;
}
<div class="container">
<div class="layer layer--front">
<div class="layer__content">
<h1 class="layer__title">Complete <br>Remodeling</h1>
<p style="max-width: 300px;">With 30 years of experience and a track record of successful projects, we have the skills and expertise to remodel your house with precision, efficiency, and minimal stress for you.</p>
<a class="custom-cta">Contact Us</a>
</div>
</div>
<div class="layer layer--back">
<div class="layer__content">
<span class="layer__title" aria-hidden="true">Complete <br>Remodeling</span>
</div>
<div class="layer__image">
<img src="https://houniqueconstruction.com/wp-content/uploads/2023/02/kam-idris-_HqHX3LBN18-unsplash-scaled.jpg" alt="" />
</div>
</div>
</div>
Be sure to watch the example in Full page mode.
Here is an approach using flexbox, three overlapping containers, and backdrop-filter: invert(100%).
Basically, the solution is to create three overlapping containers (using z-index) to put one on top of the other.
The image goes as a background image on the under container. The image is then inverted using backdrop-filter: invert(100%) twice to avoid getting a negative. However, when when the text slides over the top of the image, then it is inverted only once, giving the sliding negative effect that is asked for.
The effect is best seen in a fiddle of the solution below as the vertical bar can be dragged left or right to see the sliding effect.
The yellow button changes to blue on sliding over the image, but I am sure that this is not a critical issue.
:root {
--image-height: 500px;
--image-width: 600px;
--top-offset: 350px;
--sidebar-width: 100px;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
h1 {
margin-top: 50px;
font-size: 60px;
letter-spacing: 9px;
text-transform: uppercase;
}
p {
max-width: 300px;
}
.text-container {
margin-left: 20px;
}
.container {
display: flex;
align-items: stretch;
height: var(--image-height);
position: relative;
}
.sidebar {
flex: 1 1 var(--sidebar-width);
height: var(--image-height);
}
.image {
flex: 0 0 var(--image-width);
height: var(--image-height);
}
.container-under {
top: calc(0px - var(--top-offset));
z-index: -2;
}
.image-under {
background-image: url("https://houniqueconstruction.com/wp-content/uploads/2023/02/kam-idris-_HqHX3LBN18-unsplash-scaled.jpg");
background-size: cover;
}
.container-middle {
top: calc(0px - calc(var(--top-offset) + var(--image-height)));
z-index: -1;
}
.image-middle {
background-color: transparent;
backdrop-filter: invert(100%);
}
.container-over {
top: calc(0px - calc(var(--top-offset) + var(--image-height) * 2));
}
.image-over {
background-color: transparent;
backdrop-filter: invert(100%);
}
.custom-cta {
display: block;
margin-top: 10px;
background: gold;
padding: 10px 20px;
width: 150px;
}
<div class="text-container">
<h1>Complete<br/>Remodeling</h1>
<p>With 30 years of experience and a track record of successful projects, we have the skills and expertise to remodel your house with precision, efficiency, and minimal stress for you.</p>
<a class="custom-cta">Contact Us</a>
</div>
<div class="container container-under">
<div class="sidebar"></div>
<div class="image image-under"></div>
</div>
<div class="container container-middle">
<div class="sidebar"></div>
<div class="image image-middle"></div>
</div>
<div class="container container-over">
<div class="sidebar"></div>
<div class="image image-over"></div>
</div>
I have this CSS, where I want the footer div displayed after all content on the page. At this moment it doesnt show on the page, when I have the height of the page set to "auto", but if I set a height of any sorts or min-height it shows up till that height as it should. Can I do this, or do I have to set a manual height on each page? The CSS looks like this:
body
{
position: absolute;
top: 0;
left: 0;
right: 0;
height: auto;
background-image: url("background.jpg");
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
/* Dette er css til vores footer div boks */
div.footer
{
position: absolute;
bottom: 0;
height: 250px;
left: 0;
right: 0;
padding: 1%;
background-color: rgb(255, 255, 255);
color: rgb(0, 0, 0);
line-height: 200%;
border: 1px solid black;
}
I have tried using flexbox, containers and grids, but it only seems to work, if I insert a manual height of the body.
Try this example:
.my-contnet element has min-height of 100% to take the full height of the page.
This way the footer is always displayed at the bottom of the page regardless of the amount of content on the page.
The content will fill the remaining space above the footer.
html,
body {
height: 100%;
margin: 0;
}
.my-contnet {
min-height: 100%;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
}
What about this?
div.header {
position: relative;
display: flex;
justify-content: center;
align-items: normal;
}
video.header {
position: relative;
width: 100%;
filter: brightness(60%);
left: 50%;
top: 50%;
transform: translate(-50%,0%);
}
div.headline {
position: absolute;
left: 50%;
border-radius: 50px;
transform: translate(-50%,150%);
}
h1.headline {
font-size: 500%;
text-align: center;
-webkit-text-stroke-width: 2px;
-webkit-text-stroke-color: black;
}
div.about {
position: relative;
background-color: rgba(255, 255, 255, 0.9);
border: solid black 2px;
border-radius: 40px;
padding: 2%;
display: flex;
align-items: flex-start;
margin-bottom: 280px;
}
table.text {
width: 60%;
padding-bottom: 1%;
}
table.img {
padding-top: 5%;
}
div.footer {
position:fixed;
}
The absolute positioning of your elements was causing the footer visibility problems.
Also, if you don't want the footer to be displayed at all times, just replace the fixed position in my example with relative - the footer will only be showing once your visitors scroll down to it. If you do that, however, be sure to remove the margin-bottom: 280px; rule from div.about selector.
Please note that these were just some quick fixes - I have not considered whether your site will look good (enough) on various resolutions (mobile, tablets, 4:3, etc).
You might want to look up some boilerplates, for example, the ones Bootstrap offers.
For me, this code works great.
Please pay attention to the link I sent you in the comments.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style type="text/css">
html, body {
/* IE 10-11 didn't like using min-height */
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
.content {
flex: 1 0 auto; /* Prevent Chrome, Opera, and Safari from letting these items shrink to smaller than their content's default minimum size. */
padding: 20px;
background-color: lightblue;
}
.footer {
flex-shrink: 0; /* Prevent Chrome, Opera, and Safari from letting these items shrink to smaller than their content's default minimum size. */
padding: 20px;
background-color: blue;
}
</style>
</head>
<body>
<div class="content">
<h1>Sticky Footer with Flexbox</h1>
</div>
<footer class="footer">
Footer
</footer>
</body>
</html>
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.
Maybe you can help me. Specifically, I want that the text is always in the same container position depending on the screen resolution. Are there any solutions for this? Do I need a JS function for this? I don't know what to search in order to fix this…
<style>
.logoBar {
border: 1px solid;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
br {
line-height: 10%;
}
.container{
border: 1px solid;
width: 90%;
height:90%;
min-width: 960px;
display:block;
margin-left: auto;
margin-right: auto;
top: 50%;
}
img {
max-width: 100%;
max-height: 100%;
}
#text {
z-index: 100;
position: absolute;
top: 29.5%;
left: 11%;
font-size: 115%;
font-family: Arial, Helvetica, sans-serif;
}
.divider{
width: 2%;
height: auto;
display: inline-block;
}
</style>
<body>
<script>
$(document).ready(function() {
//Call a variable to know the width of the window
var screenWidth = $(window).width();
$('container').css('width', screenWidth + 'px');
});
</script>
<div class="logoBar">
<img src="picture1.png" style="height: 15%; width: 15%">
<div class="divider"></div>
<img src="Log-05.png" style="height: 15%; width: 15%">
</div>
<br></br>
<div class="container">
<center><img src="Picture.png"></center>
<p id="text">20.5</p>
</div>
</body>
I would be very grateful for any kind of help.
Probably the solution is quite simple.
You are on the right track using %s to position the text box(es).
We do absolutely everything that we can in terms of % of width and height of the image. That way responsiveness is automatic.
There is no need to use Javascript. Measure the width and height of the image, the distance down and to the left of the 3 text boxes and the width and height of a text box and put the measurements into CSS variables. CSS can then calculate the correct % top, bottom, width and height as needed. It doesn't matter what units you use to do this measurement, as long as the same unit is used for all of them.
This snippet has measurements to give the idea. You may want to re-measure everything to get better accuracy.
The one outstanding thing that requires thought is the font size. This needs to be responsive rather than be defined in px etc. It is set to 1vw.
The minimum width requirement of the img has been removed so that the image can be seen in its entirety on smaller devices (the user can always zoom if they want). If the minimum is reinstated then there will have to be further thought on the font size to stop it decreasing not in relation to the img size.
<head>
<style>
* {
margin: 0;
padding: 0;
}
.logoBar {
border: 1px solid;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
br {
line-height: 10%;
}
.container{
border: 1px solid;
width: 90%;
height: auto;
/*min-width: 960px;*/
display:block;
margin-left: auto;
margin-right: auto;
position: relative;
box-sizing: border-box;
--w: 1354;
--h: 665;
--x: 106;
--boxw: 113;
--boxh: 20;
--yvib: 230;
--ytemp: 294;
--yspeed: 354;
}
img {
width: 100%;
height: auto;
}
#vib {
--y: var(--yvib);
}
#temp {
--y: var(--ytemp);
}
#speed {
--y: var(--yspeed);
}
.text {
z-index: 100;
position: absolute;
text-align: center;
padding: 2px;
font-size: 1vw;
width: calc((var(--boxw) / var(--w)) * 100%);
height: calc((var(--boxh) / var(--h)) * 100%);
font-family: Arial, Helvetica, sans-serif;
top: calc((var(--y) / var(--h)) * 100%);
left: calc((var(--x) / var(--w)) * 100%);
color: red;
}
.divider{
width: 2%;
height: auto;
display: inline-block;
}
</style>
</head>
<body>
<!-- The top bit commented out as the question is about the main image not this bit
<div class="logoBar">
<img src="picture1.png" style="height: 15%; width: 15%">
<div class="divider"></div>
<img src="Log-05.png" style="height: 15%; width: 15%">
</div>
<br></br>
-->
<div class="container" onclick="console.log(event);">
<img src="https://i.stack.imgur.com/I9R3S.png">
<div id="vib" class="text">20.5</div>
<div id="temp" class="text">100</div>
<div id="speed" class="text">50</div>
</div>
</body>
I am making an image viewer in my website and currently stuck with one particular issue.
How can I resize parent div to a child image size? I made an example of the problem https://jsfiddle.net/hf0ca2z1/19/
* {
box-sizing: border-box;
}
body {
background-color: tomato;
}
.picture-viewer {
position: fixed;
display: flex;
width: 100%;
height: 100%;
z-index: 20;
top: 0px;
justify-content: center;
align-items: center;
}
.picture-viewer-frame {
position: relative;
display: flex;
width: 85%;
height: 85%;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.25);
}
.picture-viewer-frame img {
max-width: 100%;
max-height: 100%;
box-shadow: 0px 0px 15px 2px rgba(0, 0, 0, 0.35);
}
.picture-viewer-frame-header {
position: absolute;
display: flex;
top: 0px;
left: 0px;
width: 100%;
height: 65px;
background-color: rgba(255, 255, 255, 0.1);
color: white;
align-items: center;
padding-left: 15px;
}
<div class="picture-viewer">
<div class="picture-viewer-frame">
<!--Element to position to fit the child image size -->
<img src="https://post.greatist.com/wp-content/uploads/sites/3/2020/02/325466_1100-1100x628.jpg">
<div class="picture-viewer-frame-header">
Header Text
</div>
</div>
</div>
The image is responsive to the screen size, so that it would look proper on any device / screen and I want the image parent div element to resize to the size of the image. How can I achieve that?
I suppose I have to resize the div and then make an image the size of the div, but how do I resize the div to the image size? Also there could be any image with any kind of dimensions.
Not sure what you want to accomplish exactly.
Generally a div adjusts to the size of its contents.
To illustrate, if you change the background color of the immediate parent div, to say blue, you will see no change (nothing is blue) because the parent div adjusts to fit the image and is taken up completely by the picture.
So, do you mean the parent of the image, or the parent of that parent?
EDIT:
Have you tried padding around the image?
Remove the Width and Height from parent Div and it will be fine.
* {
box-sizing: border-box;
}
body {
background-color: tomato;
}
.picture-viewer {
margin:0 auto;
display: flex;
width: 80%;
height: 60vh;
z-index: 20;
justify-content: center;
align-items: center;
}
.picture-viewer-frame {
max-width:100%;
max-height:100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.25);
}
.picture-viewer-frame img {
max-width: 100%;
max-height: 100%;
box-shadow: 0px 0px 15px 2px rgba(0, 0, 0, 0.35);
}
.picture-viewer-frame-header {
position: absolute;
display: flex;
top: 0px;
left: 0px;
width: 100%;
height: 65px;
background-color: rgba(255, 255, 255, 0.1);
color: white;
align-items: center;
padding-left: 15px;
}
<div class="picture-viewer">
<div class="picture-viewer-frame">
<!--Element to position to fit the child image size -->
<img src="https://post.greatist.com/wp-content/uploads/sites/3/2020/02/325466_1100-1100x628.jpg">
<div class="picture-viewer-frame-header">
Header Text
</div>
</div>
</div>
You can use clientWidth or clientHeight to get your width and height of your div tag and have your specific ratio.
You can learn more in:
https://www.w3schools.com/JSREF/prop_element_clientwidth.asp
So, you need to have the parent be padded.
And use vw units for the sizes.
Here is an example:
(the image and the border resize as you resize the page)
<!DOCTYPE html>
<html>
<body>
<h1>The img height attribute</h1>
<div style="padding: 20vw; background-color:blue;">
<img src="https://images.pexels.com/photos/1855349/pexels-photo-1855349.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500" width="100%" height="100%">
</div>
</body>
</html>