Transition only one kind of transform at a time in CSS - css

I can't find a way to transition only one kind of transform in CSS.
I have a bunch of images (arms, legs, head etc.), that upon loading need to have a "transform: translate" applied to them so that they are in the right place before I do anything else.
I then want to have, say an arm, do a transition on just transform: rotate(20deg) on hover. The problem is that when transitioning, it will repeat the initial translation along with that rotation, but I only want it to do the rotation on hover. How can I make it only transition that one rotation?
In the example code below you can see that I make sure that the triangle is initially touching the other shape, using transform: translate. Then I do a transform: rotate on hover. It works, but it ALSO does the translate again.
(I suppose if the images could be placed in their right location without needing a transform: translate, that could perhaps solve it, but I don't know how to do that either. And It would just be better if I could isolate the transition to only transform: rotate.)
/* INITIAL PLACING OF THE IMAGES IN THEIR RIGHT PLACES */
img#Arm {
position: relative;
transform: translate(220px, 100px);
}
img#Body {
position: relative;
transform: translate(150px, 180px);
}
/* END OF PLACING OF THE IMAGES IN THEIR RIGHT PLACES */
/* THESE ARE THE TRANSFORMATIONS ON HOVER */
img#Arm {
transform-origin: 200px 200px;
transition: 1s ease-in-out;
}
section:hover img#Arm {
transform: rotate(25deg);
}
/* END OF TRANSFORMATIONS ON HOVER */
/* THIS IS TO KEEP THE LOGO PARTS GROUPED TOGETHER DESPITE WINDOW CHANGING RESOLUTIONS */
section.wrapper {
margin: 0 auto;
/* this keeps the logo centered on the page */
min-width: 800px;
/* Minimum width of your wrapper element */
max-width: 800px;
min-height: 800px;
max-height: 800px;
}
<section class="wrapper">
<img id="Arm" src="https://i.stack.imgur.com/yCC87.png" />
<img id="Body" src="https://i.stack.imgur.com/mmzDM.png" />
</section>

As you're overwriting your non-hover transform value on hover with the rotate, your arm gets positioned to its original position (like when there wouldn't be any translate on it).
As you can set multiple values for the transform property, just also add the translate on hover to it. This will keep your arm on the right position and just rotates it.
/* INITIAL PLACING OF THE IMAGES IN THEIR RIGHT PLACES */
img#Arm {
position: relative;
transform: translate(220px, 100px);
}
img#Body {
position: relative;
transform: translate(150px, 180px);
}
/* END OF PLACING OF THE IMAGES IN THEIR RIGHT PLACES */
/* THESE ARE THE TRANSFORMATIONS ON HOVER */
img#Arm {
transform-origin: 200px 200px;
transition: 1s ease-in-out;
}
section:hover img#Arm {
transform: translate(220px, 100px) rotate(25deg);
}
/* END OF TRANSFORMATIONS ON HOVER */
/* THIS IS TO KEEP THE LOGO PARTS GROUPED TOGETHER DESPITE WINDOW CHANGING RESOLUTIONS */
section.wrapper {
margin: 0 auto;
/* this keeps the logo centered on the page */
min-width: 800px;
/* Minimum width of your wrapper element */
max-width: 800px;
min-height: 800px;
max-height: 800px;
}
<section class="wrapper">
<img id="Arm" src="https://i.stack.imgur.com/yCC87.png" />
<img id="Body" src="https://i.stack.imgur.com/mmzDM.png" />
</section>

Related

How to make text appear next to centered image after it moves?

Basically, I have this one block that I want to center in the middle of the page. This block should technically have both an image, and text. When the block isn't hovered over, I want only the image to appear centered on the page. When the block is hovered over, I want the image to move to the left a bit, and have the text appear to the right of it. So far, I've managed to make the image centered, to make it move to the left on hover, and to get the hover to display the text. The problem is, the text is under the image. I understand this is because the image and the text are in different div's, and so it would make sense that it would appear after. However, I'm not sure how to both make them in the same div, and ensure that the image is dead-center on the page when the block isn't hovered over. Is this possible?
Specifically, here's the HTML code for that section so far:
<section class="about-us">
<!-- Image division -->
<div class="chatBox">
<img src='./art/chatboxAbout.png' width= "150" height = "150" />
</div>
<!-- Text division, the actual about-us part -->
<div class="about-us-text-container">
<!-- Header part -->
<h1>about us</h1>
<!-- Horizontal line for styling -->
<hr />
<!-- Actual text -->
<p>For artists, not by artists</p>
</div>
</section>
and the CSS:
/* General sizing and format for the about-us segment */
.about-us{
width: 100%;
height: 200vh;
background-color: #fff;
}
/* Formatting for the chatBox image, basic stuff */
.about-us .chatBox{
position: relative;
margin-top: 50px;
text-align: center;
transition: transform 0.3s ease; /* Preparing for transition */
transition: translateX(0px); /* What the transition is */
}
/* Move left on hover effect */
.chatBox:hover{
transform: translateX(-200px);
}
/* Formatting for the general text div */
.about-us .about-us-text-container{
margin-top: 50px;
text-align:center;
margin-left: 15px;
opacity: 0; /* Don't display unless hovered */
transform: 1s; /* Setting duration for the hover opacity transition */
}
/* Show on hover effect */
.chatBox:hover + .about-us-text-container{
opacity: 1;
}
/* Formatting for the header */
.about-us .about-us-text-container h1{
}
/* Formatting for the horizontal line */
.about-us .about-us-text-container hr{
}
/* Formatting for the paragraph */
.about-us .about-us-text-container p{
}
Here's the JSFiddle link for the entire code so far: https://jsfiddle.net/bypvm6fu/
Any help is appreciated! Thank you so much!
Here's a possible solution for you. I changed a lot in your code, main things being: The container just contains the elements you already have (not 200vh = twice the window height). Just add another container around that, and sibling following it. The transition affects all, i.e. width, opacity and transform: scale to keep the image centered when not hovered. And the hover is on the container, not on the image, that way preventing the jumping effect you had before:
.about-us {
width: 100%;
height: 150px;
background-color: #fff;
display: flex;
justify-content: center;
align-content: center;
margin-top: 50px;
}
.about-us .chatBox {
position: relative;
text-align: center;
}
.about-us .about-us-text-container {
text-align: center;
margin-left: 15px;
opacity: 0;
transition: all 1s;
width: 0;
transform: scale(0);
}
.about-us:hover .about-us-text-container {
opacity: 1;
width: 150px;
transform: scale(1);
}
<section class="about-us">
<div class="chatBox">
<img src="https://picsum.photos/150" width="150" height="150" />
</div>
<div class="about-us-text-container">
<h1>about us</h1>
<hr />
<p>For artists, not by artists</p>
</div>
</section>

Make CSS3 spinner size match element one

I found code for a nice CSS3 Spinner (from link here: https://ihatetomatoes.net/create-css3-spinning-preloader/) which I implemented into my pages. I want to transform it to be able to render with relative percent height and width.
Demo on CodePen:
http://codepen.io/anon/pen/jBWmZY
My question
How to transform the spinner to make it use percents width and height instead of fixed 100px.
The aim is to be able to make it scale to the (wrapper on my codepen) available height.
As you see on the demo, the div is small. The loader doesn't scale as its height and width are fixed.
I tried to simply transform as follow:
.loader-spinner {
position: relative;
}
.loader {
width: 50%;
height: 50%;
min-height: 35px;
min-width: 35px;
}
But the result not as intended. If the div is too small, I use wrapper to set a 35px minimum height but it doesn't work properly. The border radius seems not to follow and the size is quite mismatching. Demo here: http://codepen.io/anon/pen/jBWmKZ
I think I miss something about the wrapper or other similar thing.
The problem is that when you change the values to percent, then the width and height don't remain in sync.
The loader works because the height and width together form a square which is rounded off by the border-radius
Change your loader class to
.loader {
display: block;
position: relative;
left: 100%;
top: 100%;
width: 14%; // These values roughly keep your
height: 98%; // width and height in sync
border-radius: 50% !important;
border: 3px solid transparent;
border-top-color: #3498db;
-webkit-animation: spin 2s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
animation: spin 2s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
&:before {
....
}
&:after {
....
}
This will work for a 1920x1080 resolution. You will have to define different values for each resolution using media queries.

CSS animation moving and changing color

I am not that familiar with CSS animations. My client want to achieve the following result when hovering the contact button:
so to be clear:
the square's move from left to right and vice versa
when the square moves, the line underneath it changes color
the top image it the start state, the middle is during the effect (50%) and the bottom image is the end stage.
Is this achievable with only CSS or do I need JS as well?
How would I approach this?
I created a quick and dirty JSFiddle here: https://jsfiddle.net/x0b397pb/
As you can see, it is possible with just CSS. In this example I used pseudo elements (::before and ::after) to create most of the elements.
You mentioned "Im not that familiar with CSS animations". For this I used transitions.
transition: left 1000ms, right 1000ms, box-shadow 1000ms;
Each comma separated element is a value that will transition between 2 points. This transition happens on a change of the div, this can be on a hover, but also when applying another div (Through JS).
To created the effect of the lines gradually shifting in color I used another element that slides on top of the original two lines. The new lines originally have 0 width, but on hover they gain 100% width. With a transition transition: width 1000ms; this happens gradually.
Try not to use my code as your final example, as it is somewhat ugly. But I hope it gets the point across.
Here is a small demonstration of css transition:
Consider this HTML:
<div class="container">
<div class="box"></div>
</div>
With this CSS:
.container {
position: relative;
width: 400px;
height: 400px;
border: solid 1px black;
}
.box {
position: absolute;
width: 40px;
height: 40px;
top: 10px;
left: 10px;
background-color: red;
transition: all 1s;
}
.container:hover {
border-color: blue;
.box {
top: 200px;
left: 200px;
width: 160px;
height: 160px;
background-color: blue;
}
}
Or, check it on JsFiddle: https://jsfiddle.net/ronency/75ozjq3s/
.box {
background: linear-gradient(80deg, #f3efef, #90009f, #01060d);
background-size: 600% 600%;
animation: AnimationName 29s ease infinite;
}
#keyframes AnimationName {
0%{background-position:0% 51%}
50%{background-position:100% 50%}
100%{background-position:0% 51%}
}

div slanted in 2 directions

Is it possible to create the following shape as a DIV in CSS.
The browser support is not important.
You cannot skew an element like this directly, you'll need to use two elements (or generated content) and hide certain overflow to make the flat bottom edge:
http://jsfiddle.net/6DQUY/1/
#skew {
height: 240px;
overflow: hidden;
}
.skew {
background: #000;
display: inline-block;
height: 300px;
width: 500px;
margin-top: 100px;
transform: skew(-8deg, -8deg);
}
Note: I removed the cross browser definitions for better readability.
UPDATE: This would be a more fluid example which resizes in set dimensions: http://jsfiddle.net/6DQUY/3/. Note the padding-bottom on the wrapper which defines the ratio. You may have to play around with the percentage amounts.
#skew {
padding-bottom: 20%;
overflow: hidden;
position: relative;
}
.skew {
background: #000;
position: absolute;
top: 30%;
right: 8%;
left: 8%;
height: 100%;
transform: skew(-8deg, -8deg);
}
Using SVG:
Below is a sample using SVG polygon which can also be scaled easily. Text (if required) can be absolutely positioned on top of the shape.
.shape-svg {
position: relative;
height: 100px;
width: 300px;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
polygon {
fill: black;
}
/* Just for demo*/
.shape-svg{
transition: all 1s;
}
.shape-svg:hover {
height: 200px;
width: 600px;
}
<div class="shape-svg">
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<polygon points='5,35 100,0 95,100 0,100' />
</svg>
</div>
The shape can be created using SVG clip path also instead of polygon.
Using CSS and Single Element:
The same shape can be achieved with CSS using only one element also. The key is to set the transform-origin as the side that is required to be straight.
.shape{
height: 100px;
width: 300px;
margin-top: 50px;
background: black;
transform-origin: 0% bottom;
transform: perspective(300px) rotateY(-15deg) skewX(-10deg);
transition: all 1s;
}
.shape:hover{
width: 350px;
height: 150px;
transform: perspective(450px) rotateY(-15deg) skewX(-10deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="shape"></div>
The shape achieved using this method can also be scaled. However as the height of the shape increases, the right side becomes taller and pushes the top-right corner even more higher. So, either the rotation angle needs to be decreased (or) the perspective needs to be increased (shape needs to be moved farther away) for the height of the right side to remain small enough and be within the viewing area. Or else, the margin-top should be increased.
Below is an explanation on why this happens:
Consider a rectangle positioned 300px in front of the viewer's eye. It is being rotated towards to the viewer and as the rotation happens, the side which is getting closer to the user will appear taller than the other side.
We have fixed the transform origin's x coordinate as 0% and so the height of the left side of the shape would be constant and that of the right side would keep increasing based on the rotation angle.
Because the transform origin's y coordinate is bottom, the bottom side of the shape would be kept straight and any height increase on the right side of the element would be projected upwards resulting in the shape going outside of the screen.
There is no such problem if only the width increases because the rotation angle is too minimal and so the shape's right side will never get anywhere close enough to the viewer to look very tall.
The shape in question is not an exact duplicate of the one discussed here but you can get some more ideas by looking at it :)
You could look into CSS transformations (transform) I have created a JsFiddle with a quick example.
HTML
<div class="skew"></div>
CSS
/* Skew the container one way */
.skew {
background: #000;
display: inline-block;
height: 50px;
width: 500px;
margin-top: 100px;
-webkit-transform: skewY(-5deg);
-moz-transform: skewY(-5deg);
-ms-transform: skewY(-5deg);
-o-transform: skewY(-5deg);
transform: skewY(-5deg);
}
NOTE:
You may need to include other transformations to get the unbalanced look.
--EDIT--
Here is another solution but using :before and :after CSS. JsFiddle.

overflow:hidden ignored with border-radius and CSS transforms (webkit only)

I want to have a square image inside a circle.
When the user hovers over the image, the image should scale (zoom in).
The circle should remain the same size.
Only during the CSS transition, the square image overlaps the circle (as if overflow:hidden weren't there at all).
Here's a demo with the weird behavior in Chrome and Safari:
http://codepen.io/jshawl/full/flbau
Working ok in firefox.
You need to add this code to the parent of your img :
position:relative;
z-index:1;
Example here : http://codepen.io/DavidN/pen/dIzJK
I removed some superfluous markup (the circle and square containers... only needs one) and styled the img itself:
#wrapper {
width: 500px;
height: 500px;
border-radius: 50%;
overflow: hidden;
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
#test {
width: 100%;
height: 100%;
transition: all 2s linear;
}
#test:hover {
transform: scale(1.2);
}
<div id="wrapper">
<img src="http://rack.3.mshcdn.com/media/ZgkyMDEzLzA1LzA4L2JlL2JhYmllc193aXRoLjA5NGNjLnBuZwpwCXRodW1iCTg1MHg1OTA-CmUJanBn/8f195417/e44/babies_with_swagg.jpg" id="test">
</div>
Add this code to your parent div and solve problem :
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
It appears as though you were styling one too many elements! I've created a fork here
I edited some of your SASS code to utilize the compass library and make better use of the transition and transform properties which can be seen here:
body { padding: 3em; }
.circle {
height: 500px;
width: 500px;
border: 1px solid black;
#include border-radius(500px);
overflow: hidden;
}
.circle img {
height: 500px;
width: 500px;
#include transition(all 0.3s ease);
&:hover { #include transform(scale(1.1)); }
}
Hopefully this helps! Just think of the circle element as the parent container which has general information about the space (e.g. 500px wide and 500px tall). The image itself has a rounded border of 500px. This is the element you want to edit! You can scale and transform this element here without interacting with the parent circle container. Reference compass for additional information about using the library! Good luck!

Resources