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

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;
}

Related

How to Circumscribe a square in a circle CSS [duplicate]

I've looked into this a fair bit but can't seem to find a good, solid answer to find how to make a responsive circle around a div element of variable height.
It's easy to make a simple responsive circle using vw units.
<div style="height:20vw; width:20vw"></div>
However, I'm looking to use a min-height of an element and have a circle around this div.
Another way to create a responsive circle is using something like the snippet below, but again I can't adapt this to work for a variable height (again, I can't use vh units as the div will change in height.
.square {
position: relative;
width: 10%;
background: gray;
border-radius: 50%;
}
.square:after {
content: "";
display: block;
padding-bottom: 100%;
}
.content {
position: absolute;
width: 100%;
height: 100%;
}
<div class="square">
<div class="content">
</div>
</div>
I am trying to create something like the below, where the circle will never cut into the corners of the div (with around a 10px padding). I personally was trying to avoid javascript and would have preferred a css only approach, but it seems it's unavoidable. Maybe the only solution is to use a jquery to calculate the height of the element in order to apply this to a wrapper element?
I was playing around with this:
.square {
position: absolute;
top: 50%;
display: inline-block;
left: 50%;
transform: translate(-50%, -50%);
min-height: 100px;
border-radius: 50%;
background: url('https://i.imgur.com/2dxaFs9_d.webp?maxwidth=640&shape=thumb&fidelity=medium');
background-size: 100% 100%;
padding: 20px;
}
.content {
width: 300px;
min-height: 100px;
background: tomato;
}
<div class="square">
<div class="content">
Hello!<br>
<br><br><br>This has a variable height but fixed width<br><br><br>Hello
</div>
</div>
Clip-path can easily do this if you consider solid coloration.
Resize the element and the circle will follow:
.box {
width: 200px;
height: 200px;
overflow: hidden;
resize: both;
background: blue;
box-shadow: 0 0 0 200vmax red;
clip-path: circle(71%);
margin: 100px auto;
}
<div class="box"></div>
Related question to understand the magic number 71%: clip-path:circle() radius doesn't seem to be calculated correctly
To use an image we can consider pseudo elements. You can also rely on calc() to add the offset:
.box {
width: 200px;=
resize: both;
clip-path: circle(calc(71% + 10px));
margin: 100px auto;
position: relative;
font-size:35px;
color:#fff;
}
/* the background layer */
.box::before {
content:"";
position: absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
background:blue;
}
/* the image layer */
.box::after {
content:"";
position: fixed; /* to make sure the image cover all the screen */
z-index:-2;
top:0;
bottom:0;
left:0;
right:0;
background:url(https://picsum.photos/id/1015/1000/1000) center/cover no-repeat;
}
<div class="box" contenteditable="true"> Edit this<br>text </div>
I tried my hardest to figure this out with pure css. Though the problem with css I could not figure out how to calculate the diameter of the circle based on the content div size; the length from top left corner to bottom right corner of the variable height div.
I'm not sure if can be done using the calc() css function.
But I did manage to do it with a little jquery (which could easily be changed to pure javascript if you are not using jquery).
See working resizable example below (follow my comments in code)
Note: If you are using internet explorer the resizable demo content div will not resize.
// circumscriber for variable size divs
function circumscriber() {
// for each variable size div on page
$(".variable-size").each(function() {
// get the variable size div content width and height
let width = $(this).outerWidth();
let height = $(this).outerHeight();
// get the diameter for our pefect circle based on content size
let diameter = Math.sqrt(width ** 2 + height ** 2);
// extra 15 pixel circle edge around variable size div
let edge = 15;
// add current circle size width css
$('.circle', this).css({
'width': (diameter + (edge * 2)) + 'px'
})
});
}
// run the circumscriber (you might wana do this on ready)
circumscriber();
// if the window is resized responsively
$(window).on('resize', function() {
circumscriber();
});
// for demo purpose to fire circumscriber when resizing content
// not needed for real thing
$('.content').on('input', function() {
this.style.height = "";
this.style.height = ( this.scrollHeight - 30 ) + "px";
circumscriber();
}).on('mouseup', function() {
circumscriber();
});
/* variable size container to be circumscribed by circle */
/* none of these styles are required, this just to center the variable size div in the window for demo purposes */
.variable-size {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* resizable text area for demo */
/* again not needed */
.variable-size .content {
padding: 15px;
background: #fff;
resize: both;
overflow: auto;
color: #000;
border: none;
width: 200px;
font-weight: bold;
}
.variable-size .content:focus {
outline: 0;
}
/* child circle div css */
.variable-size .circle {
position: absolute;
background-image: url('https://i.imgur.com/2dxaFs9_d.webp?maxwidth=640&shape=thumb&fidelity=medium');
background-position: center center;
z-index: -1;
border-radius: 50%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
transition: all 0.5s ease;
width: 0;
}
/* fast way to make circle height the same as current width */
.variable-size .circle:before {
display: block;
content: '';
width: 100%;
padding-top: 100%;
}
/* demo window css */
HTML,
BODY {
height: 100%;
min-height: 100%;
background: black;
position: relative;
font-family: "Lucida Console", Courier, monospace;
}
<div class="variable-size">
<textarea class="content" rows="1" placeholder="TYPE TEXT OR RESIZE ME ↘"></textarea>
<div class="circle"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
See jsfiddle here... https://jsfiddle.net/joshmoto/6d0zs7uq/
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(100, 75, 50, 0, 2 * Math.PI);
ctx.stroke();
Source: https://www.w3schools.com/
You could use flex display and insert empty flex-items around the inner div and use flex-basis to fix their width.
Try this
.square {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-height: 100px;
border-radius: 50%;
background: black;
background-size: 100% 100%;
padding: 20px;
}
.content {
width: 300px;
min-height: 100px;
background: tomato;
}
.emptyDiv {
flex-basis: 120px
}
<div class="square">
<div class="emptyDiv"></div>
<div class="content">
Hello!<br>
<br><br><br>This has a variable height but fixed width<br><br><br>Hello
</div>
<div class="emptyDiv"></div>
</div>

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 to get a background color low opacity overlay on a featured image? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
He everyone i am strugling to find a css that will work to get a overlay on my feautured image so you can see my title more clear. For the site www.quinstudio.nl/gallery. Any idea how i can get this to work?
? {
background: #000;
opacity: .1;
}
There are several ways you could approach this. There's no real difference in how they'll turn out; you can use whichever works better with the markup you have. The first option is a little simpler because there's no empty div being added as a color overlay.
Option 1: Make the colored background opaque, and the image partially transparent.
.image-wrapper {
display: inline-block;
background: #0cd;
/* You need this line for the centered h1 below to work. */
position: relative;
}
.image-wrapper img {
opacity: 0.5;
display: block;
}
.image-wrapper h1 {
/* Here's a trick for centering your title, if you want. */
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
margin: auto;
color: #fff;
}
<div class="image-wrapper">
<img src="https://loremflickr.com/320/240" alt="Kitten">
<h1>Kitty!</h1>
</div>
Option 2: Make the image opaque, and put a partially transparent overlay on top of it.
.image-wrapper {
display: inline-block;
position: relative;
}
.image-wrapper img {
display: block;
}
.image-overlay {
background: #000;
opacity: 0.5;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 2; /* puts this div 'in front' of the image */
}
.image-wrapper h1 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
z-index: 3; /* puts the text in front of the dark overlay */
}
<div class="image-wrapper">
<img src="https://loremflickr.com/320/240" alt="Kitty!">
<div class="image-overlay"></div>
<h1>Kitty?</h1>
</div>
While #jack's answer is good, I'd like to share an alternative one that doesn't use an <img> element and instead uses the :after pseudo-element.
This allows you to use the CSS background image on the container and essentially add a fake element that has the color overlay on it:
.container {
background: url(https://loremflickr.com/320/240);
width: 320px;
height: 240px;
position: relative;
}
.overlay > * {
z-index: 1;
position: relative;
color: #fff;
}
.overlay:after {
content: "";
background: #0095ee;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: .65;
}
<div class="overlay container">
<h1>Title</h1>
</div>
Edit:
Your situation is a little different. You can just lower the opacity of the image and add a black background to it's parent container. Try the following:
.edgt-justified-layout .edgt-ni-inner .edgt-ni-image-holder .edgt-post-image img {
opacity: .75;
}
.edgt-justified-layout .edgt-ni-inner .edgt-ni-image-holder .edgt-post-image {
background: #000;
}
It will lower the opacity of the image (which will make it look "whiter", so we can add a black (or whatever color you want) background to it's parent container to compensate and darken it instead.

How can i add an overlay to an image in css or any other way [duplicate]

This question already has answers here:
Black transparent overlay on image hover with only CSS?
(8 answers)
Closed 4 years ago.
For example in the following image, there are no changes made to the actual photo but just a black color overlay is added.
How can i do it using css?
or
How can i do it using any other software?
Here's one simple method, using a pseudo-element (::before) with a semi-transparent background (black with 50% opacity, defined by rgba) overlayed above an image.
.dark-img {
position: relative;
width: 300px;
}
.dark-img img {
display: block;
width: 100%;
}
.dark-img::before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
background: rgba(0, 0, 0, .5);
}
<div class="dark-img">
<img src="https://i.imgur.com/qLRD0OC.jpg" />
</div>
Quick and simple
<html>
<head>
<style>
.your-div {width: 500px; height: auto; background-color: #000;}
.your-div img {width: 500px; height: auto; opacity: 0.3}
</style>
</head>
<body>
<h2>Hello</h2>
<div class="your-div">
<img src="http://img1.juimg.com/140915/330518-14091516335670.jpg"></div>
</body>
</html>
codepen: https://codepen.io/anon/pen/XYPWXx
<div id="overlay"></div>
CSS:
#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: 2; /* Specify a stack order in case you're using a different order for other elements */
cursor: pointer; /* Add a pointer on hover */
}

Positioning a button on top of a canvas

I'm trying to position a font-awesome button on top of a canvas. My current markup:
<li id="container">
<i class="fa fa-plus"></i>
<canvas></canvas>
</li>
The container and the canvas are visible by default. When the user mouse-overs the container, the button also appears. However, it pushes the canvas downward, causing it to spill out of the container:
The container has position: absolute and I don't have any control over that (it's part of a plugin I'm using). I do have full control over the styling of the canvas and the button.
What makes this tricky is that the user can resize the container, and the button has to remain on the top center of it at all times. Currently that works fine, but I can't get it to also appear on top of the canvas.
Hover to see i.
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #F72F4E;
}
#container {
position: absolute;
width: 50vmin;
height: 50vmin;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,.2);
}
#container:hover i {
opacity: 1;
transition: opacity .2s ease-out;
}
#container i {
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 3;
text-align: center;
opacity: 0;
transition: opacity .2s ease-in;
}
#container canvas {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
border: 5px solid green;
}
<li id="container">
<i class="fa fa-plus">i</i>
<canvas></canvas>
</li>
Have you tried to utilize the z-index?
If you don't know what it is you can read up on it here: http://www.w3schools.com/cssref/pr_pos_z-index.asp
Essentially, you will have the button sit on top of all other elements.
Hope this gives some guidance.
Also! Just thought of this, try to mess around with the position property.
http://www.w3schools.com/cssref/pr_class_position.asp
The 'fixed' value will position your button relative to the DOM window, meaning other elements shouldn't have an effect on its position.
Resolved it by changing the font-awesome element to a div and setting its height to 0. It's z-index was already larger than that of the canvas.

Resources