CSS: Position loading indicator in the center of the screen - css

How can I position my loading indicator in the center of the screen. Currently I'm using a little placeholder and it seems to work fine. However, when I scroll down, the loading indicator stays right in that predefined position. How can I make it follow the scrolling so that it always sits on top??
#busy
{
position: absolute;
left: 50%;
top: 35%;
display: none;
background: transparent url("../images/loading-big.gif");
z-index: 1000;
height: 31px;
width: 31px;
}
#busy-holder
{
background: transparent;
width: 100%;
height: 100%;
}

use position:fixed instead of position:absolute
The first one is relative to your screen window. (not affected by scrolling)
The second one is relative to the page. (affected by scrolling)
Note : IE6 doesn't support position:fixed.

.loader{
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url('//upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Phi_fenomeni.gif/50px-Phi_fenomeni.gif')
50% 50% no-repeat rgb(249,249,249);
}
<div class="loader"></div>

This is what I've done for Angular 4:
<style type="text/css">
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transform: -webkit-translate(-50%, -50%);
transform: -moz-translate(-50%, -50%);
transform: -ms-translate(-50%, -50%);
color:darkred;
}
</style>
</head>
<body>
<app-root>
<div class="centered">
<h1>Loading...</h1>
</div>
</app-root>
</body>

Here is a solution using an overlay that inhibits along with material design spinner that you configure one time in your app and you can call it from anywhere.
app.component.html
(put this somewhere at the root level of your html)
<div class="overlay" [style.height.px]="height" [style.width.px]="width" *ngIf="message.plzWait$ | async">
<mat-spinner class="plzWait" mode="indeterminate"></mat-spinner>
</div>
app.component.css
.plzWait{
position: relative;
left: calc(50% - 50px);
top:50%;
}
.overlay{
position: absolute;
top:0px;
left:0px;
width: 100%;
height: 100%;
background: black;
opacity: .5;
z-index: 999999;
}
app.component.ts
height = 0;
width = 0;
constructor(
private message: MessagingService
}
ngOnInit() {
this.height = document.body.clientHeight;
this.width = document.body.clientWidth;
}
messaging.service.ts
import { Injectable } from '#angular/core';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root',
})
export class MessagingService {
// Observable string sources
private plzWaitObservable = new Subject<boolean>();
// Public Observables you subscribe to
public plzWait$ = this.plzWaitObservable.asObservable();
public plzWait = (wait: boolean) => this.plzWaitObservable.next(wait);
}
Some other component
constructor(private message: MessagingService) { }
somefunction() {
this.message.plzWait(true);
setTimeout(() => {
this.message.plzWait(false);
}, 5000);
}

change the position absolute of div busy to fixed

You can use this OnLoad or during fetch infos from DB
In HTML Add following code:
<div id="divLoading">
<p id="loading">
<img src="~/images/spinner.gif">
</p>
In CSS add following Code:
#divLoading {
margin: 0px;
display: none;
padding: 0px;
position: absolute;
right: 0px;
top: 0px;
width: 100%;
height: 100%;
background-color: rgb(255, 255, 255);
z-index: 30001;
opacity: 0.8;}
#loading {
position: absolute;
color: White;
top: 50%;
left: 45%;}
if you want to show and hide from JS:
document.getElementById('divLoading').style.display = 'none'; //Not Visible
document.getElementById('divLoading').style.display = 'block';//Visible

Worked for me in angular 4
by adding style="margin:0 auto;"
<mat-progress-spinner
style="margin:0 auto;"
*ngIf="isLoading"
mode="indeterminate">
</mat-progress-spinner>

transform: translate(50%, 50%);
You may try this is in my case it will work
<div class="position-relative">
<div class="position-absolute" style="transform: translate(50%, 50%)"> loader or anything Else</div>
</div>

.loader{
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url('//upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Phi_fenomeni.gif/50px-Phi_fenomeni.gif')
50% 50% no-repeat rgb(249,249,249);
}
<div class="loader"></div>

Related

background-attachment: fixed in Firefox or Edge versus Chrome

body {
height: 150vh;
}
#hero {
position: relative;
border: none;
height: 100vh;
}
#hero .hero-image {
background-image: url(https://images.unsplash.com/photo-1518791841217-8f162f1e1131);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
height: 95%;
}
#hero .hero-image:after {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0,0,0,0.2);
}
#hero .skewhero-mask {
height: 100%;
position: absolute;
top: 0;
left: 10vw;
width: 45vw;
overflow: hidden;
transform: skew(24deg) translateX(0vh) translateY(0%);
}
#hero .skewhero-parallax {
transform: translateX(0vh);
width: 200%;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
#hero .skewhero-image {
background-image: url(https://images.unsplash.com/photo-1518791841217-8f162f1e1131);
height: 100%;
background-size: 110% auto;
background-attachment: fixed;
transform-origin: right top;
transform: skew(-24deg);
}
<section id="hero">
<div class="hero-image">
</div>
<div class="skewhero-mask">
<div class="skewhero-parallax">
<div class="skewhero-image"></div>
</div>
</div>
</section>
I am really stuck with this one. I'm designing a parallax effect where I shift the background-position property of a fixed background using jQuery. The jQuery isn't at fault here, so I won't include it here to reduce the complexity of the question.
In Chrome, I get the desired effect. In Firefox or Edge, it's a nightmare. I have not tested it on Opera as of yet. When removing the background-attachment: fixed from the class .skewhero-image in those browsers, I notice there's no difference whatsoever. The property doesn't do anything, because when I remove the same property in Chrome, I get the same undesirable result as in the other browsers.
How can I change my code as to achieve the exact same effect as I have now in Chrome, but in all other desktop browsers as well? Mobile browsers excluded.
Basically, the image of the cat must not move, only the container surrounding it. In Chrome, this works as intended. In Firefox or Edge, the cat moves with the container, it isn't fixed to the viewport.
Edit: I have found out that leaving out all transform properties, from itself and all parents, fixes the image to the viewport. Anything to remedy this?
I am not sure what version of Firefox you are using but I just created codepen and it is working fine
<https://codepen.io/anon/pen/ZgpgZP>
If you are still have problem, please describe in details
$(function() {
"use strict";
var $skp = $('.skewhero-parallax');
var $skm = $('.skewhero-mask');
var $hi = $('.hero-image');
function calcParallax() {
var $scroll = $(document).scrollTop();
$skm.css({'transform':'skew(24deg) translateX(-' + (0.445 * $scroll) + 'px)'});
$skp.css({'transform':'translateY(' + $scroll + 'px)'});
$hi.css({'transform':'translateY(' + $scroll + 'px)'});
}
$(window).on('scroll', function () {
calcParallax();
});
$(window).resize(function() {
calcParallax();
});
});
body {
height: 150vh;
}
#hero {
position: relative;
border: none;
height: 100vh;
}
#hero .hero-container {
height: 95%;
overflow: hidden;
}
#hero .hero-container:after {
content: "";
position: absolute;
background: rgba(0,0,0,0.2);
height: 95%;
top: 0;
left: 0;
right: 0;
}
#hero .hero-image {
height: 100%;
background-image: url(https://images.unsplash.com/photo-1518791841217-8f162f1e1131);
background-repeat: no-repeat;
background-size: cover;
will-change: transform;
}
#hero .skewhero-mask {
height: 100%;
position: absolute;
top: 0;
left: 10vh;
width: 45vw;
overflow: hidden;
transform: skew(24deg) translateX(0vh);
will-change: transform;
}
#hero .skewhero-parallax {
width: 200%;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transform: translateY(0px);
will-change: transform;
}
#hero .skewhero-image {
background-image: url(https://images.unsplash.com/photo-1518791841217-8f162f1e1131);
background-repeat: no-repeat;
height: 100%;
background-size: 110% auto;
background-position: 0px -35px;
transform-origin: right top;
transform: skew(-24deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="hero">
<div class="hero-container">
<div class="hero-image"></div>
</div>
<div class="skewhero-mask">
<div class="skewhero-parallax">
<div class="skewhero-image"></div>
</div>
</div>
</section>
I have found an alternative solution to fix my problem. Also, it seems browsers are able to deal with this solution a lot better. background-attachment:fixed is causing serious performance issues. This is because the browsers have to repaint the entire image when scrolled. Source #1 and Source #2. I have tested this myself and can confirm there's heavy lag when scrolling. I have started using the transform: translate() property, which is a lot more optimized for this as browsers don't have to repaint the entire image.
As I want to animate my parallax effect with jQuery, I've mimicked the fixed background effect in my code. I have added a code snippet of the desired effect, which works in Chrome, Firefox and Edge.

Why does the linear-gradient disappear when I make an element position:absolute?

I made a gradient background and I want to centralize this block of text. My objetive is to create a header that centralizes in the middle of the screen no matter the resolution of the viewport.
So I made this header an absolute position and used this centralization method I found online. It centralized perfectly, the problem is, the gradient background turns white (looks like the header is above the background on the body, I don't know).
I've already tried using position fixed, but the problem persists, other types of position don't centralize.
* {
margin: 0px;
padding: 0px;
}
body {
background: linear-gradient(20deg, #B7B0F6, #B1D5F9);
}
header {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
}
<header>
<h1>Hello!</h1>
</header>
You can run the code here: https://jsfiddle.net/Jhugorn/dsknqp7x/1/
If you take out the header in the CSS, the background appears just fine.
How can I make the background appear and centralize this element at the same time?
Add some height to the body to see the background:
* {
margin: 0px;
padding: 0px;
}
body {
background: linear-gradient(20deg, #B7B0F6, #B1D5F9);
min-height: 100vh;
}
header {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
<header>
<h1>Hello!</h1>
</header>
Your body contain no in-flow element so its height is equal to 0 (same thing for the html height) and this will make the background with a size of 0 thus you will see nothing.
You are not obliged to give a height of 100vh. Even a small padding can be enough due to background propagation. The visual won't be exactly the same but you will hardly notice this in this case.
* {
margin: 0px;
padding: 0px;
}
body {
background: linear-gradient(20deg, #B7B0F6, #B1D5F9);
padding:5px;
}
header {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
<header>
<h1>Hello!</h1>
</header>
A small padding on the html too is fine:
* {
margin: 0px;
padding: 0px;
}
body {
background: linear-gradient(20deg, #B7B0F6, #B1D5F9);
}
html {
padding:2px;
}
header {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
<header>
<h1>Hello!</h1>
</header>
A big padding will make things look different!
* {
margin: 0px;
padding: 0px;
}
body {
background: linear-gradient(20deg, #B7B0F6, #B1D5F9);
}
html {
padding:40px;
}
header {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
<header>
<h1>Hello!</h1>
</header>
You can check this answer to better understand how the propagation is done and how it works with gradient.

How can I overlay a ProgressSpinner in PrimeNG?

I have a progressBar spinner like this :
<p-progressSpinner></p-progressSpinner>
I want to make it center and overlay. How can I do that ?
Thanks .
This works for me: Original Url
html
<div class="progress-spinner" *ngIf="true">
<p-progressSpinner></p-progressSpinner>
</div>
css
.progress-spinner {
position: fixed;
z-index: 999;
height: 2em;
width: 2em;
overflow: show;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
/* Transparent Overlay */
.progress-spinner:before {
content: '';
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.53);
}
Not sure what you mean by overlay, but if you want to have a progress spinner inside dialog then
<p-dialog [(visible)]="display" [showHeader]="false" [resizable]="false" [modal]="true" [focusOnShow]="false" >
<i class="pi pi-times" style="float:right" (click)="onCancel()"></i>
<div style="width: 900px;height: 500px;padding-top: 20%;">
<p-progressSpinner></p-progressSpinner>
</div>
</p-dialog>
I'm using PrimeVue (similar to PrimeNG, I think) and this is what I do to get a full-screen overlay with a progress spinner.
In my HTML, I have this...
<BlockUI :blocked="isLoading" :fullScreen="true"></BlockUI>
<ProgressSpinner v-show="isLoading" class="overlay"/>
Then in my css file I have this style...
.overlay {
position:fixed !important;
top: 0;
left: 0;
width: 100% !important;
height: 100% !important;
z-index: 100; /* this seems to work for me but may need to be higher*/
}
In my TypeScript, I have a reactive variable...
const isLoading = ref(false)
Then in various functions, I set the state of that variable as needed...
isLoading.value = true /* to show overlay + spinner */
isLoading.value = false /* to hide overlay + spinner */

CSS, how to center vertically text inside an overlay in Angular 2

I have an overlay, used to show a spinner (an Angular material component) and a text. This overlay is all over the page and you can't click the elements below.
The spinner is in the middle of the page, and I want the "loading" text to be vertically aligned with the spinner, at the bottom of it-, and of course, to be centered horizzontally.
here are my HTML code and CSS styles:
<div id="overlay" [style.display]="this.showOverlay">
<div id="overlay-spinner">
<mat-spinner [diameter]="80" color="accent"></mat-spinner>
</div>
<div id="overlay-text">
<span>Loading ...</span>
</div>
</div>
#overlay {
position: fixed; /* Sit on top of the page content */
display: none; /* Hidden by default */
width: 100%; /* Full width (cover the whole page) */
height: 100%; /* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5); /* Black background with opacity */
z-index: 1; /* Specify a stack order in case you're using a different
order for other elements */
cursor: default; /* Add a pointer on hover */
}
#overlay-spinner {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
#overlay-text {
position: absolute;
top: 65%;
left: 50%;
font-size: 40px;
color: white;
transform: translate(-65%,-50%);
-ms-transform: translate(-65%,-50%);
}
You have not to care about [] attributes inside the tags because those are Angular code. They are used to set spinner properties or to show the entire overlay.
I tried with position absolute, top 65% and left 50% but the spinner and the text are not well aligned. How Can I do ?
I believe your best shot is display:flex on the overlay with it's direction and alignments (see snippet below). On flex you can read more here in this quite comprehensive and great guide. I hope this is what you expected to achieve!
p.s.: I used 'spinner is here' to make sure it is visible
p.s.2.: Do not let your eyes trick you, with the '...' at the end of 'Loading' it is actually centered right below the spinner text
#overlay {
position: fixed;
display: flex;
justify-content:center;
align-items:center;
flex-direction:column;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
z-index: 1;
cursor: default;
}
#overlay-text {
font-size: 40px;
color: white;
}
<div id="overlay" [style.display]="this.showOverlay">
<div id="overlay-spinner">
<p>spinner is here</p>
</div>
<div id="overlay-text">
<span>Loading ...</span>
</div>
</div>
I would just place your loading text into your overlay-spinner div.
<div id="overlay" [style.display]="this.showOverlay">
<div id="overlay-spinner">
<mat-spinner [diameter]="80" color="accent"></mat-spinner>
<span id="overlay-text">Loading ...</span>
</div>
</div>
#overlay {
position: fixed; /* Sit on top of the page content */
display: none; /* Hidden by default */
width: 100%; /* Full width (cover the whole page) */
height: 100%; /* Full height (cover the whole page) */
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5); /* Black background with opacity */
z-index: 1; /* Specify a stack order in case you're using a different
order for other elements */
cursor: default; /* Add a pointer on hover */
}
#overlay-spinner {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
#overlay-text {
font-size: 40px;
color: white;
}

Perfect Circle internal content height unknown

I'm having issues figuring out how to make a perfect circle without knowing the exact height of the content (image) inside the circle.
I have multiple images (jumbo titles) with circles around them but the image inside is of different height. How would I have it so it appears as a perfect circle? for each one.
css below
.jumbo-title {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
background-color: red;
padding: 50px;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
border-radius: 50%;
}
Here is my fiddle http://jsfiddle.net/HA3bQ/49/
EDIT2: Updated.
EDIT: FORGOT THE width! Hold up!
If you are open to JavaScript solution (no jQuery) with a CSS trick to center it:
HTML:
<div class="jumbo-title">
<div class="living-icon"></div>
<span class="middle"></span>
<img src="http://placehold.it/350x150" alt="Relaxed Living">
</div>
JS:
function init() {
var images = document.getElementsByTagName('img');
for(var i = 0; i < images.length; i++) {
images[i].parentElement.style.height = Math.max(images[i].width, images[i].height) + "px";
images[i].parentElement.style.width = Math.max(images[i].width, images[i].height) + "px";
}
}
window.onload = init;
CSS:
.jumbo-title {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
background-color: red;
padding: 50px;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-ms-border-radius: 50%;
border-radius: 50%;
white-space: nowrap;
text-align: center;
}
.jumbo-title img {
vertical-align: middle;
}
.middle {
display: inline-block;
height: 100%;
vertical-align: middle;
}
http://jsfiddle.net/HA3bQ/54/
you could use this simple jquery:
var cw = $('.jumbo-title').width();
$('.jumbo-title').css({
'height': cw + 'px'
});
Basically jquery will check your element width and will add the same number (px) to height
FIDDLE
In the fiddle it may look bad because of the padding you have used. then you may need just to center the image inside the container

Resources