adjust css of gauge element without breaking - css

I am simply trying to make this gauge smaller. When I try and do that (modify the container class) it warps the whole gauge element. I change the position to relative and the edge of the gauge seems to break. Any ideas on how to scale this without breaking the gauge? I eventually will nest this inside of a column in bootstrap and just trying to get this working on a basic level. Any advice on this css issue would be helpful
const Gauge = Vue.extend({
template: `
<div class="container">
<div class="gauge-bg"></div>
<div class="gauge-middle"></div>
<div class="gauge-overlay" :style="{ transform: rotate }"></div>
<div class="gauge-data">
<span>{{ percentage }}%</span>
</div>
</div>
`,
props: ['percentage'],
computed: {
rotate() {
const v = this.percentage * 180 / 100;
return `rotate(${v}deg)`;
} } });
new Vue({
el: '#app',
components: {
Gauge
}
});
body {
background-color: #4d4d4d;
}
.container {
width: 400px;
height: 200px;
position: absolute;
top: 0;
overflow: hidden;
}
.gauge-bg {
z-index: 1;
width: 400px;
height: 200px;
position: absolute;
background-color: #a3f6ba;
border-radius: 250px 250px 0 0;
}
.gauge-middle {
z-index: 3;
position: absolute;
background-color: #4d4d4d;
width: 250px;
height: calc(250px / 2);
top: 75px;
margin-left: 75px;
margin-right: auto;
border-radius: 250px 250px 0 0;
}
.gauge-overlay {
z-index: 2;
position: absolute;
background-color: #5df086;
width: 400px;
height: 200px;
top: 200px;
border-radius: 0 0 200px 200px;
transform-origin: center top;
}
.gauge-data {
z-index: 4;
color: #5df086;
position: absolute;
width: 400px;
bottom: 0;
text-align: center;
font-size: 24px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<gauge percentage="33"></gauge>
</div>

The quick and dirty solution is to use transform: scale():
.container {
transform: scale(.5) translateY(-100%);
transform-origin: 0 100%;
}
combined with a font-size increase (optional).
Vue.config.devtools = false;
Vue.config.productionTip = false;
const Gauge = Vue.extend({
template: `
<div class="container">
<div class="gauge-bg"></div>
<div class="gauge-middle"></div>
<div class="gauge-overlay" :style="{ transform: rotate }"></div>
<div class="gauge-data">
<span>{{ percentage }}%</span>
</div>
</div>
`,
props: ['percentage'],
computed: {
rotate() {
const v = this.percentage * 180 / 100;
return `rotate(${v}deg)`;
} } });
new Vue({
el: '#app',
components: {
Gauge
}
});
body {
background-color: #4d4d4d;
}
.container {
width: 400px;
height: 200px;
position: absolute;
top: 0;
overflow: hidden;
transform: scale(.5) translateY(-100%);
transform-origin: 0 100%;
}
.gauge-bg {
z-index: 1;
width: 400px;
height: 200px;
position: absolute;
background-color: #a3f6ba;
border-radius: 250px 250px 0 0;
}
.gauge-middle {
z-index: 3;
position: absolute;
background-color: #4d4d4d;
width: 250px;
height: calc(250px / 2);
top: 75px;
margin-left: 75px;
margin-right: auto;
border-radius: 250px 250px 0 0;
}
.gauge-overlay {
z-index: 2;
position: absolute;
background-color: #5df086;
width: 400px;
height: 200px;
top: 200px;
border-radius: 0 0 200px 200px;
transform-origin: center top;
}
.gauge-data {
z-index: 4;
color: #5df086;
position: absolute;
width: 400px;
bottom: 0;
text-align: center;
font-size: 48px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<gauge percentage="33"></gauge>
</div>
The proper solution would be to rewrite its CSS so that it takes a variable ($gaugeWidth !?) and factors in all its hard-coded sizes so it scales correctly (what the original dev should have done in the first place).

Related

Flexbox not working correctly - seems that dom is recalculated

I have this menu (this happens also with the website text)
<div id="container" class='container'>
<div class='meta-background'></div>
<section class='meta-container'>
<div class="meta-menu meta-menu-top">
<ul>
<li>testsas</li>
<li>fdadasdasdas</li>
<li>dsdasdsadasdsa</li>
</ul>
<span class="meta-title">WEBSITE</span>
</div>
<div class="meta-menu meta-menu-bottom"></div>
</section>
</div>
css:
/* contaner */
/* * { padding:0; margin:0; box-sizing: border-box;} */
.container {
max-width: 2380px;
margin-left: auto;
margin-right: auto;
}
.meta-container {
display: flex;
/* -webkit-box-pack: center; */
/* -ms-flex-pack: center; */
justify-content: center;
}
.meta-background {
position: fixed;
margin-left: auto;
margin-right: auto;
z-index: -1;
background-size: cover;
background-repeat: no-repeat;
-webkit-filter: blur(10px);
filter: blur(10px);
top: 0;
right: 0;
bottom: 0;
left: 0;
/* background-image: url('./assets/img/3.jpg'); */
}
.meta-title {
color: white;
position: absolute;
bottom: 10px;
display: block;
}
/* menus */
.meta-menu-top {
background: #252422;
color: #959595;
border-radius: 0px 0px 10px 10px;
/* top: 0px; */
position: absolute;
height: 48%;
width: 360px;
opacity: 0.7;
display: flex;
justify-content: center;
}
.meta-menu-top ul {
padding: 0;
margin-top: 30%;
}
.meta-menu-top li {
list-style-type: none;
display: block;
}
.meta-menu-bottom {
background: #eef1f5;
color: white;
border-radius: 10px 10px 0px 0px;
/* bottom: 0px; */
position: absolute;
height: 48%;
width: 360px;
}
and the JS to hide/show the menu
let menutop = $('.meta-menu-top'),
menubottom = $('.meta-menu-bottom');
//set cookie for future preference
//
//
//get cookie if first run or not
//
//
let upDown = 0,
duration = 1;
let tlshow = new TimelineMax({ paused: true });
tlshow.fromTo(menutop, duration, {top: '-40%' } ,{ top: 0, ease: Power3.easeInOut })
.fromTo(menubottom, duration, { bottom: '-40%' },{ bottom: 0, ease: Power3.easeInOut }, '-=' + duration);
let tlhide = new TimelineMax({ paused: true });
tlhide.fromTo(menutop, duration, { top: 0 } ,{ top: "-40%", ease: Power3.easeInOut })
.fromTo(menubottom, duration, { bottom: 0 },{ bottom: "-40%", ease: Power3.easeInOut }, '-=' + duration);
menutop.on("click",function(){
console.log("CLICKED MENUTOP");
if(upDown == 0) {
tlhide.restart();
upDown = 1;
}
else {
tlshow.restart();
upDown = 0;
}
});
codepen here: https://codepen.io/giventofly/pen/RxMRMR
on chrome works okay, on firefox the meta-menu-top/bottom are pushed to the left and rearranged to center again.
tried with the webkit/moz prefix and even using normalize.css with no results.
what could be?
Since you use position: absolute for top and bottom menus, you have no need to use display: flex for the parent element. Below is an example of working code (a little simplified).
var metaContainer = document.querySelector('.meta-container');
var menuTop = document.querySelector('.meta-menu-top');
menuTop.onclick = close;
function close() {
metaContainer.classList.toggle('closed');
}
body {
overflow: hidden;
}
.meta-menu {
left: 50%;
transform: translateX(-50%);
}
.meta-menu-bottom,
.meta-menu-top {
height: 48%;
position: absolute;
width: 360px;
transition: 300ms;
}
.meta-menu-top {
align-items: center;
background: #252422;
color: #959595;
display: flex;
border-radius: 0px 0px 10px 10px;
justify-content: center;
opacity: 0.7;
text-align: center;
top: 0;
}
.meta-menu-top ul {
padding: 0;
margin-bottom: 30px;
}
.meta-menu-top li {
list-style-type: none;
}
.meta-title {
color: white;
bottom: 10px;
left: 0;
position: absolute;
width: 100%;
}
.meta-menu-bottom {
background: #eef1f5;
bottom: 0;
border-radius: 10px 10px 0px 0px;
color: white;
}
.closed .meta-menu-top {
top: -48%;
margin-top: 35px;
}
.closed .meta-menu-bottom {
bottom: -48%;
margin-bottom: 30px;
}
<div id="container" class='container'>
<div class='meta-background'></div>
<section class='meta-container'>
<div class="meta-menu meta-menu-top">
<ul>
<li>testsas</li>
<li>fdadasdasdas</li>
<li>dsdasdsadasdsa</li>
</ul>
<div class="meta-title">WEBSITE</div>
</div>
<div class="meta-menu meta-menu-bottom"></div>
</section>
</div>
It seems that there is a Firefox-specifc bug TweenMax
The way that the elements are centered in your page is by the use of the flex display, which is totally fine. However, Firefox rendering has major issues when the left style being unspecified. This is what causes both animated elements to randomly move.
A simple way to overcome this issue is to specify a left value for your element; i.e. add the css below. Or alternatively, you can avoid the use of display flex, unless it is important for you.
.meta-menu-top {
left: calc(50% - 180px);
}
.meta-menu-bottom {
left: calc(50% - 180px);
}
Here is an updated CodePen

css circle with text overlayed on an image

I am trying to overlay a circle over a square image. The text needs to be centered hoziontally and verticaly in the circle.
I have almost got it right with a square div, but as soon as I put an image into the mix, the circle moves below the image.
My code.
.Container {
width: 300px;
height: 300px;
}
.Square {
height: 100%;
width: 100%;
background-color: yellow;
}
.Square img {
width: 100%;
height: 100%;
}
.Circle {
position: relative;
height: 70%;
width: 70%;
top: 15%;
left: 15%;
background-color: rgba(0, 0, 200, 0.5);
border-radius: 50%;
/*80px;*/
margin-bottom: 50%;
/*30px; */
float: left;
margin-right: 20px;
}
.Circle h3 {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 50%;
height: 30%;
margin: auto;
text-align: center;
}
<div class="Container">
<div class="Square">
<img src="SiteData/Images/ProfilePics/ProfileImg.png" />
<div class="Circle">
<h3>Words Here</h3>
</div>
</div>
</div>
The Container will ultimately be of variable width, determined by bootstrap col
Since you want to position your circle over the image, you have to use position: absolute instead of relative. This will take it out of the document flow and you can position it anywhere you want within the parent element.
In order for this to work, you will also have to declare position: relative on the parent.
See proof-of-concept example below:
.Container {
width: 300px;
height: 300px;
}
.Square {
height: 100%;
width: 100%;
background-color: yellow;
position: relative; /* To allow children to be absolutely positioned */
}
.Square img {
width: 100%;
height: 100%;
}
.Circle {
position: absolute; /* Use absolute positioning */
height: 70%;
width: 70%;
top: 15%;
left: 15%;
background-color: rgba(0, 0, 200, 0.5);
border-radius: 50%;
/*80px;*/
margin-bottom: 50%;
/*30px; */
float: left;
margin-right: 20px;
}
.Circle h3 {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 50%;
height: 30%;
margin: auto;
text-align: center;
}
<div class="Container">
<div class="Square">
<img src="SiteData/Images/ProfilePics/ProfileImg.png" />
<div class="Circle">
<h3>Words Here</h3>
</div>
</div>
</div>

bootstrap make divs overlap

I am trying to achieve below layout using bootstrap. I am able to do it otherwise but problem occurs on small screens where the middle most box(smallest one) will not appear where it should be, it goes up. so want to try using bootstrap.enter image description here
how about this solution. I have made few changes in your code.
please have look carefully
DEMO
* {
margin: 0;
padding: 0;
box-sizing: border-box;
border: 0.5px solid black;
}
.top-cover {
width: 100%;
height: 300px;
background-image: url('IMG_0044.JPG');
background-size: cover;
background-position: center;
}
.main-cover {
width: 90%;
position: relative;
height: 700px;
left: 5%;
top: -60px;
z-index: 1;
background-color: brown;
border: solid 5px green;
}
#dp {
width: 20%;
position: absolute;
left: 40%;
top: -10%;
z-index: 2;
display: none;
}
.dp-pic {
width: 20vw;
min-width: 75px;
max-width: 150px;
position: absolute;
left: 40%;
top: -8%;
}
<div class="top-cover">
</div>
<div class="main-cover">
<div id="dp"></div>
<img class="dp-pic" src="https://camo.githubusercontent.com/9e39276ad39fe3cda7ac61dd0f1560dc5ad1ab95/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f752f3737343835392f4769744875622d5265706f732f7465737464756d6d792f63726173687465737464756d6d792e6a7067">
</div>
Following should generate your desired layout. Add borders or other fancy styles as you want.
body {
margin: 0;
padding: 0;
}
.top-cover {
width: 100%;
height: 300px;
background: #eee;
}
.main-cover {
width: 90%;
height: 700px;
position: relative;
margin: -60px auto 0;
z-index: 1;
background-color: brown;
}
#dp {
width: 20%;
position: absolute;
left: 50%;
margin: -10% 0 0 -10%;
z-index: 2;
}
.dp-pic {
width: 100%;
}
<div class="top-cover">
</div>
<div class="main-cover">
<div id="dp">
<img class="dp-pic" src="https://camo.githubusercontent.com/9e39276ad39fe3cda7ac61dd0f1560dc5ad1ab95/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f752f3737343835392f4769744875622d5265706f732f7465737464756d6d792f63726173687465737464756d6d792e6a7067">
</div>
</div>

CSS 3D transform acting strange, DIV goes blank

Fiddle: http://jsfiddle.net/y7d4kkxz/
HTML:
<div class="app">
<div class="content">
<div class="wrapper">
Content here.
<button class="doit">...</button>
</div>
</div>
</div>
CSS:
.app {
background: #003;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
width: auto;
height: auto;
}
.content {
background: #fff;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: auto;
height: auto;
overflow-x: hidden;
overflow-y: auto;
transition: 500ms;
}
.menu-open .content {
transform: translate3d(40%, 0px, 0px) scale3d(0.85, 0.85, 0);
}
.wrapper {
margin: 5%;
}
JS:
$(function () {
$('.doit').on('click', function () {
$('.app').toggleClass('menu-open');
});
});
scale3d(0.85, 0.85, 0) will scale the Z axis of the element to 0, and it will disappear. You could use 1 instead, but it doesn’t look like you need 3D transformations at all up to this point:
.menu-open .content {
transform: translateX(40%) scale(0.85);
}
Updated fiddle

CSS Keyframes: How to move div to certain position

I have a div I want to move to a certain position (say [200,200]) when I add the class remove. I have a lot of divs from different places and I want them to meet at [200,200].
.remove { -webkit-animation: swoopOut 2s 1 ease forwards; }
#-webkit-keyframes swoopOut {
0% {position: relative; left: 0px; top: 00px; opacity: 1}
80% {position: absolute; left: 200px; top: 200px; opacity: 1}
100% {position: absolute; left: 200px; top: 200px; opacity: 0}
}
When I use top/left, it moves relative (200 down, 200 right) though I want absolute (to [200,200]). I've tried position: absolute but that won't work.
Any help?
EDIT: I've tried to make an example in fiddle where I want the two boxes to meet at 150,50. What can I do?
Lot of divs? With CSS, I'm pretty sure it's not possible without a keyframe rule for each element. With JS, however:
window.onload = function() {
TweenLite.to(document.getElementsByClassName("box"), 1, {
top: 50,
left: 150,
onComplete: function() {
TweenLite.to(this.target, 0.2, {
opacity: 0,
onComplete: function() {
TweenLite.set(this.target, {
opacity: 1
});
this.restart();
}.bind(this)
});
}
});
};
body {
margin: 0px;
}
#container {
position: relative;
}
.wrapper {
/*position: relative;*/
width: 100px;
height: 100px;
border: 1px solid black;
}
.meet {
position: absolute;
top: 50px;
left: 150px;
width: 100px;
height: 100px;
border: 1px solid black;
}
.box {
position: absolute;
width: 100px;
height: 100px;
background-color: coral;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/CSSPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenLite.min.js"></script>
<div id="container">
<div class="wrapper">
<div class="box"></div>
</div>
<div class="wrapper">
<div class="box"></div>
</div>
<div class="meet"></div>
</div>
Here's with CSS only but with multiple keyframe and animation rules.
body {
margin: 0px;
}
#container {
position: relative;
}
.wrapper {
position: relative;
width: 100px;
height: 100px;
border: 1px solid black;
}
.meet {
position: fixed;
top: 50px;
left: 150px;
width: 100px;
height: 100px;
border: 1px solid black;
}
.box {
position: absolute;
width: 100px;
height: 100px;
background-color: coral;
}
.box1 {
-webkit-animation: boxOne 1s infinite;
}
.box2 {
-webkit-animation: boxTwo 1s infinite;
}
#-webkit-keyframes boxOne {
0% {
left: 0px;
top: 0px;
opacity: 1
}
80% {
left: 150px;
top: 50px;
opacity: 1
}
100% {
left: 150px;
top: 50px;
opacity: 0
}
}
#-webkit-keyframes boxTwo {
0% {
left: 0px;
top: 0px;
opacity: 1
}
80% {
left: 150px;
top: -50px;
opacity: 1
}
100% {
left: 150px;
top: -50px;
opacity: 0
}
}
<div id="container">
<div class="wrapper">
<div class="box box1"></div>
</div>
<div class="wrapper">
<div class="box box2"></div>
</div>
<div class="meet">
</div>
</div>

Resources