I have a div that acts as drawer that the user can pull down from the top of the window, that contains a dozen of buttons with some styling.
the code for expanding/collapsing that div while pulling on it is:
drawer.style.height = `${Math.min(drawerParams.maxheight,drawerParams.startHeight + event.y - drawerParams.startY)}px`;
It works fine on a computer, but I have serious lagging on a mobile phone. Here is a picture of the chrome devtools for mobile devices:
Here is the structure and CSS for that layout:
<style>
.main {
position: relative;
width: 100%;
height: 100%;
}
.drawer {
position: absolute;
top: 0;
width: 100vw;
background-color: lightgreen;
min-height: 7px;
z-index: 4;
}
.drawer-content {
position: absolute;
bottom: 7px;
display: flex;
flex-wrap: wrap-reverse;
justify-content: space-between;
}
.handle {
position: absolute;
width: 100%;
bottom: 0;
height: 7px;
}
</style>
<div class="main">
<div class="drawer">
<div class="drawer-content">
<div class="button">button1</div>
<div class="button">button2</div>
<div class="button">button3</div>
<div class="button">button...</div>
<div class="button">button10</div>
</div>
<div class="handle">
<!-- some svg -->
</div>
</div>
</div>
If I set the initial drawer's position to "top:200px", I see that the content is already there, and when pulling on it from that position, I have the same performance issues.
I tried to use transform:translateY() like in this article:link, but it had no effect. (I assume it is because instead of having one translate from the begining of the transition to the end, I have one for each pixel of mouse movement..?)
So the questions are (from the picture):
1: is the browser repainting the div each time the drawer element's height changes?
2: why?
3: what can I change to avoid that?
Related
I have some web page to fetch the user related data and huge count of images. The problem is while load the page it took more time due to images , Images are rendered in separate div in the page. So i want loader spinner for that particular div.
Note: I know how to implement for page load. Just need for particular div.
Just look the below my implementation idea.
<body>
<div id="divUserContent">
</div>
<div id="divuserimages">
</div>
</body>
Just make sure the parent element to the loading element has a position set to relative. See this example below.
body {
margin: 0px;
font-size: 16px;
}
.container {
background: rgba(0,0,0,.2);
height: 100vh;
align-items: center;
justify-content: center;
display: flex;
position: relative;
}
.loading-container {
padding: 10rem;
border: 1px solid #000;
position: relative; /* this keeps .loading-text inside it */
width: 5rem;
}
.loading-text {
position: absolute;
top: 50%;
left: 50%;
margin-top: -9px; /* take .loading-text height, divide by -2 */
margin-left: -35px; /* take .loading-text width, dividide by -2*/
}
<div class="container">
<div class="loading-container">
<div class="loading-text">Loading...</div>
</div>
</div>
I have this HTML structure:
<div class="container">
<img class="image" />
<div class="overlay">
<div class="insides">more elements here</div>
</div>
</div>
and this CSS code:
.container {
position: relative;
height: 88vh;
margin: 0;
}
.image {
height: 100%;
position: absolute;
margin-right: auto;
margin-left: auto;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
.overlay {
position: absolute;
}
My requirements are as follows:
Make image fill the available vertical space and center it horizontally. (Works)
Make image overlay of the same size as the image - without using an absolute width attribute. (Does not work - problem)
Fix icons to specific spots on the image. (Using percentages for top and left attributes ... Not sure if this is going to be as easy as I currently think.)
How can I have it all - a horizontally centered image expanded to fill the vertical space, an exact overlay and elements fixed to specific spot of the image?
While I would prefer a CSS hack, a Javascript solution will be considered, too, in case the width of the image needs to be transferred to the overlay programmatically.
One way of doing it would be to wrap the Image and the Overlay in a div and center that.
.container {
position: relative;
height: 88vh;
margin: 0;
text-align: center;
}
.imagecontainer
{
position: relative;
display: inline-block;
height: 100%;
}
.image {
height: 100%;
}
.overlay {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
<div class="container">
<div class='imagecontainer'>
<img class="image" src='imageurlhere'/>
<div class="overlay">
<div class="insides">more elements here</div>
</div>
</div>
</div>
Like this, the Image will set the width of its parent and in doing so also the width of the Overlay.
I am looking to make digital wedding invitations, even though I'm not a web developer.
I'm trying to create a page with a very simple animation where there is an envelope that shows the invitation. I have three simple images overlapped using html and css:
the front envelope - https://i.ibb.co/HBZsxLt/optipng.png
the invitation - https://i.ibb.co/h7SfR5L/part.png
the opend envelope - https://i.ibb.co/HtkgNPy/all.png
I was able to create the code (listed below) for what I want to achieve.
There are the three images overlapped and I'm able to shift the envelope with two simple lines of JavaScript. The overlapping works perfectly when I open it with Chrome. However, my issues came with the following point:
When I open the website with Firefox some pixels of the invitation come out the envelope
When I open the website from any smartphone in addition to the envelope-invitation dimension problems all the images are zoomed or moved on the left.
I tried to search if there is any way to overlap the images in an adaptive way (from the device/browser point of view), maybe using only JavaScript but I didn't find anything. I found only the css and html approach the I implemented already below. The simplest thing that I found for solving the issues was to insert a gif in the body but I don't like it very much.
My simple code is:
<!DOCTYPE html>
<html lang="it">
<head>
<title>Invitation wedding</title>
<style>
body {
margin: 0;
background-color: white;
}
#container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
img {
height: 50%;
padding: 80px 0;
overflow: visible; /* For Firefox */
}
.env {
position: absolute;
}
.partecipazione{
height: 130%;
padding-top: 20%;
position: absolute;
padding-right: 22px;
}
.allEnvelope{
padding-top: 20%;
position: absolute;
}
</style>
</head>
<body>
<div id="container">
<div class="allEnvelope">
<img id="allEnv" src="all.png"></img>
</div>
<div class="partecipazione">
<img id="part" src="part.png"></img>
</div>
<div class="env">
<img id="envelope" src="optipng.png"></img>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>
<script>
var timeline = new TimelineMax();
timeline.to('#envelope, #allEnv', .6, {y:290}, '+=.7');
</script>
</body>
</html>
Here I changed some things:
I removed
img {
height: 50%;
padding: 80px 0;
overflow: visible; /* For Firefox */
}
Then added a extra container around all divs inside the envelope for placement:
<div id="container">
<div class="envelopeWrapper">
<div class="allEnvelope">
<img id="allEnv" src="all.png"></img>
</div>
<div class="partecipazione">
<img id="part" src="part.png"></img>
</div>
<div class="env">
<img id="envelope" src="optipng.png"></img>
</div>
</div>
</div>
The styles:
.envelopeWrapper{
width: 603px;
max-width: 95%;
height: 500px;
position: relative;
}
the height here is just to place it in the middle of the screen.
The max-width is for mobile devices o if its smaller than the width of 603px it will adapt. Also added position: relative to adjust the div's within.
Added the styles for all divs/images inside the new wrapper:
.env, .partecipazione, .allEnvelope {
position: absolute;
right: 0;
left: 0;
bottom: 0;
}
.envelopeWrapper img{
max-width: 100%;
height: auto;
}
.partecipazione{
padding-left: 2%;
padding-right: 6%;
padding-bottom: 7%;
}
With position absolute I placed it at the corners of the bottom of the new wrapper-div.
I needed to add padding with percent for .partecipazione because the images wherent properly cut out. It's in percent so it will scale right for mobile devices.
Heres your changed code:
<!DOCTYPE html>
<html lang="it">
<head>
<title>Invitation wedding</title>
<style>
body {
margin: 0;
background-color: white;
}
#container {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.envelopeWrapper{
width: 603px;
max-width: 95%;
height: 500px;
position: relative;
}
.env, .partecipazione, .allEnvelope {
position: absolute;
right: 0;
left: 0;
bottom: 0;
}
.envelopeWrapper img{
max-width: 100%;
height: auto;
}
.partecipazione{
padding-left: 2%;
padding-right: 6%;
padding-bottom: 7%;
}
</style>
</head>
<body>
<div id="container">
<div class="envelopeWrapper">
<div class="allEnvelope">
<img id="allEnv" src="all.png"></img>
</div>
<div class="partecipazione">
<img id="part" src="part.png"></img>
</div>
<div class="env">
<img id="envelope" src="optipng.png"></img>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>
<script>
var timeline = new TimelineMax();
timeline.to('#envelope, #allEnv', .6, {y:290}, '+=.7');
</script>
</body>
</html>
But I think now you jsut have to adjust the script for the animation a little bit.
You can add browser prefix with your CSS. Here is new CSS code.
<style type="text/css">
body {
margin: 0;
background-color: white;
}
#container {
height: 100vh;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
position: relative;
}
img {
height: 50%;
padding: 80px 0;
overflow: visible; /* For Firefox */
}
.env {
position: absolute;
}
.partecipazione{
height: 130%;
padding-top: 20%;
position: absolute;
padding-right: 22px;
}
.allEnvelope{
padding-top: 20%;
position: absolute;
}
</style>
Elements can overlap for a variety of reasons, by using the property z-index we can make sure that the Letter stays in the vertical order we want it. It is the same as Layers in Photoshop if you have used that.
Using the above example by Puschi, we can add z-index to the following classes:
.partecipazione {
z-index: 1
}
.env {
z-index: 2;
}
The .env class will stay in the default layer at the bottom, placing the letter above it, then the open envelope above that again. This makes sure that the elements don't overlap.
Here is a Codesandbox using CSS & Javascript
https://codesandbox.io/s/sparkling-resonance-49b2w?file=/index.html:591-627
By using JavaScript we can fire off the animations after the browser is done loading all the images, making sure that it plays well.
Or we could add interactivity so that when the user clicks or hovers the Envelope it opens.
I've this code here (Please open in expanded mode):
#wrapper {
position: fixed;
background: gray;
color: #fff;
bottom: 0;
left: 0;
right: 0;
border-radius: 12px 12px 0 0;
width: 100%;
}
#title {
text-align: center;
padding: 15px;
border-bottom: 1px solid white;
}
#notifications {
display: flex;
flex-direction: column;
overflow: scroll;
overflow-x: hidden;
}
.entry {
padding: 15px;
}
<div id="wrapper">
<div id="title">Notifications</div>
<div id="notifications">
<div class="entry">Test</div>
<div class="entry">Test</div>
<div class="entry">Test</div>
<div class="entry">Test</div>
<div class="entry">Test</div>
<div class="entry">Test</div>
<div class="entry">Test</div>
</div>
</div>
It should be like in Google Maps when you explore the nearby. So like a slide up div from the bottom. The title should be visible when it's not expanded but not the notifications. When I click the title, I want to smoothly expand the element up to 85 percent of the viewport so that the user can scroll trough the notifications. When he clicks the title again, it should go back down to the initial state.
Is this possible? If yes, how?
To change between two states, expanded and collapsed, you'll need some kind of JavaScript.
As far as the CSS, I'd suggest for #wrapper instead of using bottom: 0, using something like top: calc(100% - 42px) (the 42px should be whatever the height you want to be visible) for the collapsed state, and then top: 15% for the expanded state.
For the "smooth" part of it, you just need to add a transition animation.
Here's a basic codepen showing what I mean: https://codepen.io/milesgrover/pen/gOpbrpd
I am trying to vertically center some text over an image that appears on a mouseover. I have come to a solution that works with chrome (15.0.874.106) on a mac (10.7.2), but it seems to have issues in Safari (5.1.1), odd since they are both webkit based. I believe it also has the same problem in Firefox.
The text is vertically centered in relation to the parent div in chrome, but seems to center to the body or window in Safari. Am I doing something wrong or does anyone have a better solution?
jsbin: http://jsbin.com/iceroq
CSS:
.content {
width: 300px;
position: relative;
}
.content-text {
width: 100%;
height: 100%;
background: black;
position: absolute;
top: 0;
left: 0;
text-align: center;
display: none;
}
HTML:
<div class="content">
<div class="content-image">
<img src="http://placehold.it/300x500/E01B4C" />
</div>
<div class="content-text">
Google
</div>
</div>
.content-text a {
color: white;
position: relative;
top: 50%;
margin-top: -0.5em;
}
JS:
$(document).ready(function() {
$('.content').hover(
function() {
$(this).children('.content-text').show();
}, function() {
$(this).children('.content-text').hide();
});
});
I edited your jsbin: http://jsbin.com/iceroq/3
The edits were all CSS changes to .content-text a. Making the link absolutely positioned and giving it a height allows you to know what margin-top to give it (half of the height).
.content-text a {
display: block;
width: 100%;
height: 20px;
position: absolute;
top: 50%;
margin-top: -10px;
color: white;
}