On hover animate a html element along the parent element boundaries/path - html

Is it possible to on hover animate an html element (a div) along the boundary of a parent element (a div)? Actually I have kind of answered the first part of this question, but I am having trouble getting the animation to occur from a certain point, then animate back to the starting point on mouse off. I may be trying to push CSS a little too far. But is this possible? If you notice in the sample code when you mouseover the little box jumps to the corner and starts animating smoothly, then off mouse off it abruptly snaps to back to the original position. I have tried animating the position attribute as well, still no go. This is the closest I have been able to get.
html, body {
height: 100%;
background-color: #000000;
color: #ffffff; }
.container {
height: 100%;
display: flex;
border: 1px solid green;
align-items: center;
justify-content: center; }
.container > div {
position: relative;
text-align: center; }
.sqwr-orbit {
height: 10px;
width: 10px;
background: #ffffff;
margin: 0 auto; }
.ignite:hover #square {
animation-duration: 12s;
animation-name: squareorbit;
animation-timing-function: linear;
animation-iteration-count: infinite; }
#keyframes squareorbit {
0% {
margin: 0 50% 0 0; }
25% {
margin: 90% 0 0 0; }
50% {
margin: 90% 0 0 90%; }
75% {
margin: 0 0 0 90%; }
100% {
margin: 0;
transform: rotateZ(1800deg); } }
<div class="container">
<div>
<div class="ignite" style="padding: 5px;height: 100px; width: 100px; position: relative;">
<div class="sqwr-orbit" id="square"></div>
<div style="position: absolute; border: 1px solid #fff; top: 8px; left: 10px; width: 80%; height: 84%;">
</div>
</div>
</div>
</div>
example image

Related

curtain effect on text only - text showing from middle to outer edges

I am trying to create a curtain effect on some text. I want the text to be hidden at first and then have an animated reveal from the middle of the text to the outer edges. I want this to work even if there is an odd number of letters. In other words, breaking up the string would not work. If there is only one giant character in the string I want it to reveal from the center of the character to the outer edges of the character. I do not want a curtain effect on the background, since I don't know what I want to have for a background yet. I want it only on the text.
Here is what I have so far:
HTML
<div class="container">
<div class="my-name">The Incredible Houdini</div>
</div>
CSS
body {
margin: 0;
}
.container {
position: relative;
font-size: 3vh;
width: 100%;
height: 100vh;
background: lightblue;
}
.my-name {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 2em;
font-weight: bold;
color: darkblue;
width: 0;
overflow: hidden;
white-space: nowrap;
animation: showName 5s linear 3s forwards;
}
#keyframes showName {
from {
width: 0;
}
to {
width: 15ch;
}
}
The overflow:hidden and the width from 0 to 100 give me what I want in terms of the individual characters gradually being revealed instead of popping in like a typewriter. The problem is that it generates from the left to the right. Is there any way I can start expanding the width from the middle to the outer edges?
Firstly, you would need a keyframe to auto width which you can't do. I'd suggest rethinking your methodology.
I'd go with animating a clip path
body {
margin: 0;
}
.container {
position: relative;
font-size: 25vh;
width: 100%;
height: 100vh;
background: lightblue;
display:flex;
justify-content:center;
align-items:center;
}
.my-name {
font-weight: bold;
color: white;
overflow: hidden;
padding: .25em;
background: rebeccapurple;
clip-path: inset(0 100% 0 100%);
animation: showName 5s linear forwards;
}
#keyframes showName {
0% {
clip-path: inset(0 100% 0 100%);
}
100% {
clip-path: inset(0);
}
}
<div class="container">
<div class="my-name">The Incredible Houdini</div>
</div>

How to center a absolute element in another absolute element, that could be used for rotation and animation purposes

To make it clear, I have two squares they both have position: absolute and are inside another div that has a relative position.
This is related more to a UI design and not about centering two divs into each other and use if for web, it's more a UI thing or an animation thing for popups or similar.
That means it could be that I have a circle that is bigger than box1 somewhere. Then I use an invisible box that has position relative that contains box2 as a child
Both of the squares have a different size.
New example of issue here: https://jsfiddle.net/mgznef98/2/
The red box is not allowed to change position The border somehow has to be centered. And I put it inside a box2-container to support it, because box1 could be another shape and not a simple box if I would edit it
"some-container" is just the "thing" that would move around the website and carry all of the "boxes", so it can't be used with table-cell.
If you would look at this Rotate objects around circle using CSS?
On this page they rotate elements around the center of another element, but they're not inside the center. And I'm trying to put something in a center. That would be as example a square with a border that would rotate around.
I've managed to center the blue square inside the red square, somehow. I'm not even sure if it is exactly centered. https://jsfiddle.net/mgznef98 on this one before, but for the border one, I don't really know.
My question is, I think there is some math behind it. I think there has to be some formula to find out what to put inside "top" and "left" so I can center the blue "border" box exactly inside the red box when the red box changes the width and height.
What I know is that it changes depending on the size of box2 and its container and box1.
Example:
Let's say again I have two boxes but one of them is invisible, in this case the container of box2. And box2 is not a box instead it is "something" that rotates. And box1 is not a box, instead it is an element a shape or something that has a center. And box2 has a border instead of a background color, and that border has to rotate around the center of the element. The thing is that box2 is bigger than box1.
.some-container {
top: 30px;
left: 30px;
position: relative;
}
.box1 {
width: 20px;
height: 20px;
background: red;
position: absolute;
}
.box2-container {
position: relative;
height: 20px;
width: 20px;
}
.box2 {
width: 40px;
height: 40px;
border: 2px solid blue;
position: absolute;
top: -50%; /* These values have to be changed when I want to recenter a new width and height from box1 */
left: -50%;
border-radius: 50%;
border-color: blue blue blue transparent;
border-width: 2px;
animation: box2-rotation 3s linear infinite;
}
#keyframes box2-rotation {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
<div class=some-container>
<div class=box1>
</div>
<div class=box2-container>
<div class=box2>
</div>
</div>
</div>
I think this is what you wanted.
https://jsfiddle.net/5zun4tqr/
I've used the example from there: Center element inside div (circle)
It will always remain in the center like that, size shouldn't cause any problems when used with that flexbox method.
body {
background: #0a0a0a;
}
.some-container {
position: relative;
display: inline-block;
}
.some-container2 {
position: relative;
display: inline-block;
margin-left: 80px;
}
.some-container3 {
position: relative;
top: 30px;
left: 30px;
}
.box1 {
width: 50px;
height: 50px;
background: red;
position: absolute;
}
.box2-container {
display: flex;
position: relative;
height: 50px;
width: 50px;
justify-content: center;
align-items: center;
border: darkgreen solid 1px;
box-sizing: border-box; /* Because of the border */
}
#keyframes box2-rotation {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
.box2 {
width: 40px;
height: 40px;
border: 2px solid blue;
position: absolute;
border-radius: 50%;
border-color: blue blue blue transparent;
border-width: 2px;
animation: box2-rotation 3s linear infinite;
}
.replace1 {
width: 30px;
height: 30px;
}
.replace2 {
width: 30px;
height: 30px;
}
.replace3 {
width: 60px;
height: 60px;
}
.box3 {
width: 80px;
height: 80px;
border: 2px solid;
position: absolute;
border-radius: 50%;
border-color: green green green transparent;
border-width: 2px;
animation: box2-rotation 4s linear infinite;
}
.box4 {
width: 120px;
height: 120px;
position: absolute;
animation: box4-rotation 6s linear infinite;
}
#keyframes box4-rotation {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
.box4-circle {
stroke-dasharray: 52.275;
stroke-width: 2px;
animation: box4-rotateion 6s linear infinite;
animation-fill-mode: both;
transform-origin: center;
}
<div class=some-container3>
<div class=some-container>
<div class=box1>
</div>
<div class=box2-container>
<div class=box2>
</div>
</div>
</div>
<div class=some-container2>
<div class="box1 replace1">
</div>
<div class="box2-container replace2">
<div class="box2 replace3"></div>
<div class="box3"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 107 107" class="box4">
<circle class="box4-circle" cy=50% cx=50% r=50 stroke=white fill=none></circle>
</svg>
</div>
</div>
</div>
</div>
Personally I wouldn't do it with absolute positions if all you are doing is trying to center a div within another. Doing some like this with flex will perfectly center your box 2 within box 1.
<div>
<div class=box1>
<div class=box2>
</div>
</div>
.box1 {
width: 40px;
height: 40px;
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.box2 {
width: 20px;
height: 20px;
background: blue;
}

Creating a option-choice landing page

I want to create a landing page like a game. The visitor gets the option either to chose "Professioneel" or "Speels".
Telling it is easy but programming it is hard for me, so this is what I want:
2 div's with 2 different background-image when someone hover over one of the divs I want the background-image to scale (ONLY THE IMAGE) and the opacity placed on the div to change from 50% to 80%.
And a really nice future would be to display a snow falling gif over the image.
This is what I want to create:
Before
After:
What I have achieved till now is making the 2 divs with a background-image and I'm not even sure if that is the right way.
Can someone please help me out?
This is what happens when I hover with my current code: (the whole div scales, not only the image)
As an user asked, here some code:
#containerEntree {
height: 100vh;
width: 1920px;
padding-left: 0;
padding-right: 0;
}
#professioneelContainer {
background-color: red;
text-align: center;
width: 1920px;
height: 475px;
}
#speelsContainer {
background: red;
width: 100%;
height: 475px;
text-align: center;
}
.entreeTekst:hover {
transform: scale(1.2);
}
.entreeTekst {
width: 100%;
height: 100%;
position: relative;
transition: all .5s;
margin: auto;
}
.entreeTekst > span {
color: white;
/* Good thing we set a fallback color! */
font-size: 70px;
position: absolute;
}
<div class="container" id="containerEntree">
<div id="professioneelContainer">
<div class="entreeTekst">
<span>professioneel</span>
<img src="img/professioneel.jpg" />
</div>
</div>
<div id="speelsContainer">
<div class="entreeTekst">
<span>Speels</span>
<img src="img/speels.jpg" />
</div>
</div>
</div>
Please note that I'm still working on it so don't say that this (of course) won't work.
You can do this by using 2 divs with background images and use padding on the div to replicate the aspect ratio of the background image. Scale the image using background-size on :hover. Then use a pseudo element to create the color overlay and transition the opacity on :hover, then use the other pseudo element on top of that with the text and the "snow" gif as a background.
body {
width: 600px;
max-width: 80%;
margin: auto;
}
div {
background: url('https://static.tripping.com/uploads/image/0/5240/towns-funny-names-us_hero.jpg') center center no-repeat / 100%;
height: 0;
padding-bottom: 33.33333%;
position: relative;
transition: background-size .25s;
}
.speel {
background-image: url('http://www.luketingley.com/images/large/The-Punchbowl-Web-Pano.jpg');
}
div::after, div::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
}
div::before {
opacity: .5;
transition: opacity .25s;
}
.pro::before {
background: blue;
}
.speel::before {
background: red;
}
div::after {
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-family: sans-serif;
font-size: 1.5em;
font-weight: bold;
}
.pro::after {
content: 'PROFESSIONEEL';
}
.speel::after {
content: "SPEELS";
}
div:hover::after {
background: url('https://media.giphy.com/media/26BRyql7J3iOx875u/giphy.gif') center center no-repeat / cover;
}
div:hover::before {
opacity: 0.8;
}
div:hover {
background-size: 150%;
}
<div class="pro">
</div>
<div class="speel">
</div>
You can simply increase the background-size: height width; and opacity: value; property when you hover over an element. You can, if you want to, add some transition to make it smooth. This only scales the background image, not the div itself.
#d {
background-image: url(https://cdn.pixabay.com/photo/2016/10/29/20/52/cincinnati-1781540_960_720.png);
height: 200px;
width: 200px;
background-size: 100px 100px;
background-repeat: no-repeat;
background-position: center;
/*To make the transistion smooth*/
-o-transition:.5s;
-ms-transition:.5s;
-moz-transition:.5s;
-webkit-transition:.5s;
transition:.5s;
opacity: 0.5;
}
#d:hover {
background-size: 110px 110px;
opacity: 0.8;
}
<div id='d'>
</div>

CSS: How to accomplish a div which is blurred at the edges?

I have an idea for an Ajax-loader.
This is what I have accomplished so far:
body {
background-color: lightGrey;
counter-reset: h1-counter;
}
.wrap {
max-width: 200px;
height: 50px;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.wrap div {
background: linear-gradient(#0032f0, white, #0032f0);
position: absolute;
width: 100%;
height: 100%;
z-index: 1000;
opacity: .8;
}
.wrap div.dark-bar {
position: absolute;
width: 10%;
height: 100%;
animation: moveDarkBar 3s linear infinite;
z-index: 1;
}
#keyframes moveDarkBar {
from {
left: -20%;
}
to {
left: 120%;
}
}
<div class="wrap">
<div></div>
<div class="dark-bar"></div>
</div>
I want the moving indicator (.dark-bar) to be "melted" with foreground-div. Currently there is a hard line which is visually distinguishable.
Is there a way to get the moving indicator (.dark-bar) to be blurred on the left-, right edge?
You could make use of CSS filter to add blur to top layer which is animated as below,
filter - The filter property provides graphical effects like blurring,
sharpening, or color shifting an element. Filters are commonly used to
adjust the rendering of images, backgrounds, and borders.
Do include vendor prefixes for other browsers such as -webkit-,-o-,-moz-,-ms- to filter.
body {
background-color: lightGrey;
counter-reset: h1-counter;
}
.wrap {
max-width: 200px;
height: 50px;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.wrap div {
background: linear-gradient(#0032f0, white, #0032f0);
position: absolute;
width: 100%;
height: 100%;
z-index: 1000;
opacity: .8;
}
.wrap div.dark-bar {
position: absolute;
width: 10%;
height: 100%;
animation: moveDarkBar 3s linear infinite;
z-index: 1;
-webkit-filter:blur(2px); /*Add this*/
}
#keyframes moveDarkBar {
from {
left: -20%;
}
to {
left: 120%;
}
}
<div class="wrap">
<div></div>
<div class="dark-bar"></div>
</div>
Try using the box-shadow property and set the vertical and horizontal axis values to 0. Something like this:
div {
box-shadow: 0 0 10px black;
}
This might be a similar effect for the one you want.

Preventing blurry rendering with transform: scale

I'm scaling a div up with the transform property, but I want to keep its children (which have 1px width or height) the same size. I counter-scaled them by .5, with the expected result that an element of 1px scaled by 2, and then .5, should end up back at 1px, but they wind up a blurry 2px.
Here's the box before scaling it:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
As you can see, the elements at the edges are a clear, dark 1px blue. Here's what the box looks like after scaling, though:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
transform: scale(.5);
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1,.5);
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
And here's a post-scaled render from Chrome 41.0.2272.89 Mac, which is what I'm running.
Adding transform-3d(0, 0, 0) didn't appear to help. A solution was found using the zoom property, but since zoom isn't well supported I'd like to avoid that. Adding filter: blur(0px); didn't appear to have any effect either.
It was posited in chat that perhaps the children are first scaled to .5 and then doubled in size, causing them to be scaled down to .5px and then back up from there. Is there any way to ensure the order that they're rendered in causes them to first be scaled up to 2px and then halved? Against my better judgement, I tried forcing the render order with JS, but unsurprisingly, that didn't have any effect (though, interestingly, the bottom element did maintain its original color).
Failing that, are there any other solutions floating around out there? I can't be the only one who's run into this problem.
It is to do with the default transform-origin on the scaled elements. It defaults to 50% 50% for any element being transformed, but this has issues when scaling down 1px values as it has to centre the scale on a half pixel and the rendering of the elements has issues from here on out. You can see it working here with the transform-origin moved to the relevant extremes for each item.
A bit of playing about shows that this same blurring happens on scaled elements for any dimension where the scaling ends up halving a pixel.
body {
padding: 1em;
}
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1, 0.5);
}
.outlineBottom {
bottom: 0;
transform-origin: 0 100%;
}
.outlineTop {
transform-origin: 0 0;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
transform-origin: 100% 0;
}
.outlineLeft {
left: 0px;
transform-origin: 0 0;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>