How can I fix a div relative to a scrollable container? - css

Please see this minimum example
.container {
position: relative;
width: 200px;
height: 200px;
border: 3px solid gray;
overflow: scroll;
}
.box {
width: 100%;
height: 800px;
background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
}
.loading-cover {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
opacity: 0.5;
display: flex;
justify-content: center;
align-items: center;
}
<div class="container">
<div class="loading-cover">
Loading
</div>
<div class="box"></div>
</div>
I want to fix the white overlay when scrolling.
I've tried inset: 0 or width: 100%;height:100%; on loading-cover, but no luck.
position: sticky; is also unusable in this case because it sticks to the window viewport, not the scrollable container.
Is there any way I can solve this problem?

This might not be the shortest path to a solution, but it does work. It might hold up in cross-browser testing if you don't need to support IE.
This is using a loading class on the container that applies a sticky ::before pseudo-element, with a negative bottom margin to make the content pop up underneath it. A little goofy, but it's a weird situation. I also removed some unnecessary width values and changed overflow to overflow-y, which may or may not be useful in your situation.
With this, you could turn on and off the "Loading" message by adding or removing the class to the container.
.container {
position: relative;
width: 200px;
height: 200px;
border: 3px solid gray;
overflow-y: scroll;
}
.box {
height: 800px;
background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
}
.container.loading::before {
position: sticky;
top: 0;
height: 200px;
margin-bottom: -200px;
background: white;
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
content: 'Loading';
}
<div class="container loading">
<div class="box"></div>
</div>

Related

CSS preserve ratio of circle on top of image

I have an image and i want to put 2 circles on top of it, instead of the eyes.
body {
background-color: lightgrey;
color: #fff;
padding: 0;
margin: 0;
}
main {
display: grid;
place-items: center;
position: relative;
}
#container {
min-height: 100vw;
min-width: 100vw;
background: none;
aspect-ratio: 1 / 1;
}
.eye-container {
position: relative;
border-radius: 50%;
background-color: red;
width: 12vw;
height: 12vw;
}
.eye-container.left {
top: -84%;
left: 36%;
}
.eye-container.right {
top: -96%;
left: 51%;
}
.eye {
position: absolute;
bottom: 3px;
right: 2px;
display: block;
width: 3vw;
height: 3vw;
border-radius: 50%;
background-color: #000;
}
img {
max-width: 100%;
min-width: 100%;
}
<main>
<div id="container">
<img id="sponge" src="https://upload.wikimedia.org/wikipedia/en/thumb/3/3b/SpongeBob_SquarePants_character.svg/220px-SpongeBob_SquarePants_character.svg.png">
<div class="eye-container left">
<div class="eye"></div>
</div>
<div class="eye-container right">
<div class="eye"></div>
</div>
</div>
</main>
The current issue is the image is too big, it is stretched.
The initial problem was that the layout was not responsive on mobile, and i've did some changes and now the image is this big.
I've used aspect-ratio: 1 / 1; because top was not working with negative percentage, and with pixels the eyes location is changing if is shrink the window.
Do you have another suggestion, maybe a simplified code will be better.
Thank you.
I'm a noob developer and I felt like, this was a tiny engineering job "LOL" but I did it for you.
So the most important point in this is to keep the image and the eyes in the same position. and to do that, you should position them in a parent container for image and eyes considering four important factors:
1- Parent position: relative; All children position: absolute;
2- All children's width: %; so it can stay in the same spot in its parent whatever the width of the parent is.
3- Eyes and eyeballs positioning top, left, right must be % too for the same purpose.
4- To change the image size, use the parent width. do not change the image size.
If you follow these steps, you can position any element with any image or other element.
* {
border: 1px solid blue;
margin: 0;
padding: 0;
}
.container {
width: 200px; /* use this to change the picture size. do not change it somewhere else */
position: relative;
}
.image {
width: 100%;
}
.eye-container{
position: absolute;
border-radius: 50%;
background-color: red;
width: 12%;
height: 12%;
}
.left-eye {
top: 17%;
left: 36%;
}
.right-eye {
top: 17%;
left: 51%;
}
.eyeball {
position: absolute;
bottom: 3px;
right: 2px;
display: block;
width: 30%;
height: 30%;
border-radius: 50%;
background-color: #000;
}
<div class="container">
<img class="image" src="https://upload.wikimedia.org/wikipedia/en/thumb/3/3b/SpongeBob_SquarePants_character.svg/220px-SpongeBob_SquarePants_character.svg.png">
<div class="left-eye eye-container">
<div class="eyeball"></div>
</div>
<div class="right-eye eye-container">
<div class="eyeball"></div>
</div>
</div>

CSS: placing absolute positioned element so that it touches its parent from outside

I want the absolute positioned child touch its parent from outside like this:
.parent {
background: #aaffaa;
width: 200px;
height: 200px;
margin-left: 150px;
display: flex;
align-items: center;
position: relative;
}
.child {
background: #ffaaaa;
width: 100px; // actually unknown, here for demo purposes
height: 100px;
position: absolute;
left: 0;
transform: translate(-100%);
}
<div class="parent">
<div class="child"></div>
</div>
The problem: I can't use the transform property, because it's already in use in a keyframe animation, the element may or may not be position: absolute. Is there some elegant solution to this?
Sure there is! There is just 1 line missing in your code.
You just need to use right:100% and it will be just fine.
.parent {
background: #aaffaa;
width: 200px;
height: 200px;
margin-left: 150px;
display: flex;
align-items: center;
position: relative;
}
.child {
background: #ffaaaa;
width: 100px;
height: 100px;
position: absolute;
right: 100%;
}
<div class="parent">
<div class="child"></div>
</div>

How to create this kind of card layout in css

I am looking to create this kind of card layout how to get that blue on both side of the card.
The only thing i would like to know is how to get that blue on left and right side of the card.
.card {
height: 300px;
width: 400px;
background: #f1f1f1;
}
<div class="card">
<h2>Title</h2>
</div>
You need to wrap The card with container with two childern.
1- Then add overlay div with absolute positioning (this will be the blue side)
2- The card (white div)
N.P: I've added flex to body just to center the card, no need for it.
Example:
body {
background-color: gray;
display: flex;
}
.card-container {
position: relative;
height: 300px;
width: 400px;
margin: auto;
}
.overlay {
position: absolute;
top: 5%;
left: 0;
width: 100%;
height: 90%;
background: linear-gradient(#4180B9, #42BDBB);
border-radius: 5px;
}
.card {
z-index: 2;
position: relative;
width: 90%;
height: 100%;
margin: auto;
background-color: #fff;
border-radius: 5px;
}
<div class="card-container">
<div class="overlay"></div>
<div class="card">
</div>

How to center fixed content in flexbox container in Safari?

Following code works as expected (block is centered) in Chrome and Firefox but in Safari child container is slightly off:
#container {
width: 100%;
background: yellow;
height: 20px;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
}
#content {
padding: 0px;
background: linen;
position: fixed;
}
My question would be - how to center "position: fixed" element in a "display: flexbox" parent in Safari?
Element with position: fixed (or position: absolute) won't behave in the same way in Safari as they do in Chrome/Firefox.
To center a flex item in Safari you need to use transform: translate
Updated codepen
Stack snippet
#container {
width: 100%;
background: yellow;
height: 20px;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
}
#content {
padding: 0px;
background: linen;
position: fixed;
left: 50%;
transform: translateX(-50%);
}
<div id="container">
<div id="content">THIS CONTENT IS NOT CENTERED IN SAFARI</div>
</div>

How to mask corners of static content of oval-shaped div?

Here's the HTML:
<div class="root">
<div class="oval">
<div class="val"></div>
</div>
</div>
and here's the relevant CSS, so far:
.oval {
box-sizing: padding-box;
width: 200px;
height: 100px;
border: 10px solid black;
border-radius: 60px;
position: relative;
}
.oval .val {
width: 93%;
height: 100%;
position: absolute;
}
Go here to see what it looks like at the moment.
I want to mask the square corners of the .oval .val element, so that they appear to be behind the "opening" suggested by the .oval element's border.
The right edge of .oval .val element should run vertically from top to bottom, without any rounding.
NOTE: The width of the .oval .val can be anything between 0% and 100%, including problematic values such as 93%.
Add overflow: hidden; to the .oval class.
Add
.oval {
overflow: hidden;
}
to your CSS.
To explain this, I've added a background-color to .val class
.oval {
box-sizing: padding-box;
width: 200px;
height: 100px;
border: 10px solid black;
border-radius: 60px;
position: relative;
overflow: hidden;
}
.oval .val {
width: 93%;
height: 100%;
position: absolute;
}
.val {
background-color: red;
}
<div class="root">
<div class="oval">
<div class="val"></div>
</div>
</div>

Resources