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
Related
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>
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.
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;
}
I use owl carousel and I want the navigation above the slide in order to navigate easily. Now they are hidden or below the slider. I don't know how to put them above. I tried z-index in the CSS for the carousel and navigation but nothing happens. Need help thank you !
JS
<script>
$(document).ready(function() {
$("#owl-demo2").owlCarousel({
navigation : true, // Show next and prev buttons
slideSpeed : 300,
paginationSpeed : 400,
items : 1,
itemsDesktop : false,
itemsDesktopSmall : false,
itemsTablet: false,
itemsMobile : false
});
});
</script>
CSS
#owl-demo2 .item img{
display: block;
width: 100%;
height: auto;
position: relative;
z-index: 1;
}
.owl-theme .owl-controls .owl-buttons div{
color: #FFF;
display: inline-block;
zoom: 1;
position: fixed;
z-index: 2000;
*display: inline;/*IE7 life-saver */
margin: 90px;
padding: 20px 0px;
font-size: 12px;
-webkit-border-radius: 30px;
-moz-border-radius: 30px;
border-radius: 30px;
background: #869791;
filter: Alpha(Opacity=50);/*IE7 fix*/
opacity: 0.5;
}
.owl-buttons {
position: absolute !important;
top: -45px !important;
left: 50% !important;
transform: translateX(-50%)!important;
}
z-index doesn't put items like you wish it would. I think you need to change positions of these buttons rather than setting different z-index.
Here you have an example of how z-index work. Change z-index as you wish and check how the alignement work on these boxes:
https://jsfiddle.net/grmcfb7z/
You can try this CSS for your solution:
.owl-buttons{
position: absolute;
top: -45px;
left: 50%;
transform: translateX(-50%);
}
You might want to tweak it if it doesn't look as you wish. I tried it on your example from the comments and it looks great to me.
UPDATE
After digging into the exact problem, here is the full solution:
#owl-demo2 .item img {
display: block;
width: 100%;
height: auto; //we don't need position or z-index property here
}
.owl-theme .owl-controls .owl-buttons div {
color: #FFF;
display: inline-block;
zoom: 1;
*display: inline; /*IE7 life-saver */
margin: 10px; //fixed margin to not mess our buttons alignement
padding: 5px 15px; //smaller padding for better look
font-size: 12px;
-webkit-border-radius: 30px;
-moz-border-radius: 30px;
border-radius: 30px;
background: #869791;
filter: Alpha(Opacity=50); /*IE7 fix*/
opacity: 0.5;
}
.owl-buttons, .owl-pagination {
position: absolute !important;
left: 50% !important;
transform: translateX(-50%) !important; //here we override our buttons
//positions
}
.owl-buttons {
top: 0 !important; //nav position
}
.owl-pagination {
bottom: 0 !important; //pagination position
}
Working jsfiddle: https://jsfiddle.net/43wo7g98/3/
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>