Inherit transform-value from other state - css

I've got an image which will scale on hover. However, at the same time the image get's translated to -50% on both the X and Y axis, or in some cases, only on the X axis.
Is there a way to inherit the previous transform while still changing one of the values?
.container {
position: relative;
height: 400px;
width: 640px;
overflow: hidden;
}
img {
-webkit-transform: translate(-50%,-50%) scale(1);
transform: translate(-50%,-50%) scale(1);
position: absolute;
top: 50%;
left: 50%;
transition: 500ms;
}
img.special {
-webkit-transform: translateX(-50%) scale(1);
transform: translateX(-50%) scale(1);
top: 0;
}
img:hover {
-webkit-transform: translate(-50%, -50%) scale(1.1);
transform: translate(-50%, -50%) scale(1.1);
}
<div class="container">
<img src="http://www.lorempixel.com/640/400/nature" alt="test image" />
</div>
<div class="container">
<img src="http://www.lorempixel.com/640/400/abstract" class="special" alt="test image" />
</div>
TL:DR;
Is there a way to inherit the original transform settings, while still changing one of the values?
I'm not looking for answers adding extra css, classes or whatever. I'm just looking for a way to keep this as short as possible. I've already solved this using extra classes and CSS.

Is there a way to inherit the original transform settings, while still changing one of the values?
No, there is no way to do this in CSS. CSS transform property declarations (like all other properties) are not additive. The latest setting (or) the one which is more specific will completely override anything else specified and hence there is no chance to inherit some values and add on top of it.
The only alternative with pure CSS is to add an extra wrapper and apply one of the transforms to it. In this way, the img:hover styling (the scale) need not be repeated and can be left as common for all.
.container {
position: relative;
height: 400px;
width: 640px;
overflow: hidden;
}
.wrapper {
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
}
.special.wrapper {
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
top: 0;
}
.wrapper img {
transition: 500ms;
}
img:hover {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
<div class="container">
<div class="wrapper">
<img src="http://www.lorempixel.com/640/400/nature" alt="test image" />
</div>
</div>
<div class="container">
<div class="wrapper special">
<img src="http://www.lorempixel.com/640/400/people" alt="test image" />
</div>
</div>
The other way would be to use JavaScript, find out what is the current transform on the element, then append the extra transform on hover and apply it via inline styles.

Related

Bootstrap center an image inside the div but without resizing

I need to place the image inside the div. I know there are img-responsive center-block classes but they resize the given image for some reason. Is there a way to achieve the same goal but without size distortions.
Note: the containing div is a bootstrap column with given classes: hidden-xs col-lg-9 col-md-6 col-sm-6.
Thank you
CSS is my friend
can you try this CSS class
HTML
<img class="centerd-image" src="">
or
<div class="centerd-image">
<img src="">
</div>
CSS
.centerd-image {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
Use css for the img class as
width: --%;
margin-left:auto;
margin-right:auto;

CSS Solution For Ignoring Transform Of Parent Div

I have a layout like this:
<div class="parent">
<div class="wrapper">
<div class="child">
<h1>Sticky text</h1>
</div>
</div>
</div>
CSS:
.parent {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.wrapper {
width: 1024px;
display: block;
}
.child {
-webkit-transform: translateY(-80px);
-ms-transform: translateY(-80px);
transform: translateY(-80px);
transition: transform .5s ease;
z-index: 31;
position: fixed;
left: 0;
right: 0;
top: 100%;
}
Since parent has transform of 0 my child wont stay fixed. However if i remove parent transform the child get's sticked just fine. is there any way around this? without deleting the transform of the parent? Maybe flex?

What is the difference between perspective and transform's perspective properties in CSS?

In our application we use a temporary css transform as a page transition.
With the latest build of google chrome (37) this stopped working. The transformation has no longer a perspective.
Fiddling with the developer tools I was able to restore the correct behavior by changing the definition of the perspective on the parent element from
perspective: 2000px;
to
transform: perspective(2000px);
My question is: is something wrong with our existing declaration (using the perspectice property) or is this a bug in google chrome?
I tried to recreate the problem below, but in the reduced example I see the reverse effect, that now perspective works and transform:perspective not.
Any thoughts?
.perspective-Parent {
/*-moz-transform: perspective(2000px);
-ms-transform: perspective(2000px);
-o-transform: perspective(2000px);
-webkit-transform: perspective(2000px);
transform: perspective(2000px);*/
-moz-perspective: 2000px;
-ms-perspective: 2000px;
-webkit-perspective: 2000px;
perspective: 2000px;
-moz-perspective-origin: 50% 50%;
-ms-perspective-origin: 50% 50%;
-webkit-perspective-origin: 50% 50%;
perspective-origin: 50% 50%;
}
.page {
background-color: red;
-moz-transform-origin: right center;
-ms-transform-origin: right center;
-o-transform-origin: right center;
-webkit-transform-origin: right center;
transform-origin: right center;
-ms-transform: rotateY(75deg);
-moz-transform: rotateY(75deg);
-o-transform: rotateY(75deg);
-webkit-transform: rotateY(75deg);
transform: rotateY(75deg);
width: 200px;
height: 100px;
}
<p>
<div class="perspective-Parent">
<div class="page">
</div>
</div>
My basic understanding of perspective vs transform perspective is simply that the plain perspective attribute is what you usually use on a parent element to give multiple children the same perspective, while transform perspective would be used on a child element or an individual element to give it its own perspective.
This is most easily seen when you are applying these effects to more than one element:
perspective: ; on a parent element:
.perspective-Parent {
-moz-perspective: 2000px;
-ms-perspective: 2000px;
-webkit-perspective: 2000px;
perspective: 2000px;
-moz-perspective-origin: 50% 50%;
-ms-perspective-origin: 50% 50%;
-webkit-perspective-origin: 50% 50%;
perspective-origin: 50% 50%;
}
.page {
background-color: red;
-moz-transform-origin: right center;
-ms-transform-origin: right center;
-o-transform-origin: right center;
-webkit-transform-origin: right center;
transform-origin: right center;
-ms-transform: rotateY(75deg);
-moz-transform: rotateY(75deg);
-o-transform: rotateY(75deg);
-webkit-transform: rotateY(75deg);
transform: rotateY(75deg);
width: 200px;
height: 100px;
margin: 10px; /* added to make difference more visible */
}
<div class="perspective-Parent">
<div class="page"></div>
<div class="page"></div>
<div class="page"></div>
</div>
Notice that all three "pages" in the above example are being viewed from a common perspective.
transform: perspective(); on the individual elements:
.page {
background-color: red;
-moz-transform-origin: right center;
-ms-transform-origin: right center;
-o-transform-origin: right center;
-webkit-transform-origin: right center;
transform-origin: right center;
-ms-transform: perspective(2000px) rotateY(75deg);
-moz-transform: perspective(2000px) rotateY(75deg);
-o-transform: perspective(2000px) rotateY(75deg);
-webkit-transform: perspective(2000px) rotateY(75deg);
transform: perspective(2000px) rotateY(75deg);
width: 200px;
height: 100px;
margin: 10px; /* added to make difference more visible */
}
<div class="perspective-Parent">
<div class="page"></div>
<div class="page"></div>
<div class="page"></div>
</div>
Notice on this example that the three "pages" each have their own perspective.
Now that that's all out of the way...
Neither approach is incorrect they just offer different visual effects, just pick the one that you prefer.
Accepted answer here is not correct.
You can indeed do a perspective transform on a parent element. For this to work, you need to set transform-style: preserve-3d; on the parent.
.perspective-Parent{
transform: perspective(2000px);
transform-style: preserve-3d;
}
.page {
background-color: red;
transform-origin: right center;
transform: rotateY(75deg);
width: 200px;
height: 100px;
margin: 10px;
}
<div class="perspective-Parent">
<div class="page">
</div>
<div class="page">
</div><div class="page">
</div>
</div>
When I test out different perspectives in chrome, the perspective property gives some strange distortions.
.box{
width: 100px;
height: 100px;
margin-left: 100px;
}
.no-perspective-box{
transform-style: preserve-3d;
transform: rotateX(-15deg) rotateY(15deg);
}
.perspective-prop-box{
perspective: 7.5cm;
transform-style: preserve-3d; /*This is required here too*/
transform: rotateX(-15deg) rotateY(15deg);
}
.perspective-box{
transform-style: preserve-3d;
transform: perspective(7.5cm) rotateX(-15deg) rotateY(15deg);
}
.face{
position: absolute;
width: 100px;
height: 100px;
line-height: 100px;
font-size: 100px;
text-align: center;
}
.top{
background-color: blue;
transform: rotateX(90deg) translate3d(0, 0, 50px);
}
.left{
background-color: red;
transform: rotateY(-90deg) translate3d(0, 0, 50px);
}
.front{
background-color: green;
transform: translate3d(0, 0, 50px);
}
<p>Without Perspective:</p>
<div class="box no-perspective-box">
  <div class="face front">A</div>
  <div class="face top">B</div>
  <div class="face left">C</div>
</div>
<br /><br />
<p>With Perspective Property:</p>
<div class="box perspective-prop-box">
  <div class="face front">A</div>
  <div class="face top">B</div>
  <div class="face left">C</div>
</div>
<br /><br />
<p>With Perspective Function:</p>
<div class="box perspective-box">
  <div class="face front">A</div>
  <div class="face top">B</div>
  <div class="face left">C</div>
</div>
<br /><br />
The order matters in case of declaring the property and the function, the "perspective" function must come right after the "transform" property!
WRONG CODE
transform:rotateX(45deg) perspective(100px);
CORRECT CODE
transform:perspective(100px) rotate(45deg);
To activate 3D space, an element needs perspective. This can be applied in two ways: using the transform property, with the perspective as a functional notation.
transform: perspective( 600px );
or using the perspective property:
perspective: 600px;
Perspective Projection vs. Perspective Transformation
Perspective Projection calculates the perspective view (i.e., foreshortening) of a 3D object onto a 2D projection plane. The effect
of viewing in perspective is achieved, and, of course, the z-values
(depth information) are discarded in the process.
Perspective Transformation allows us to see how the perspectively foreshortened and projected polygons will overlap, without discarding
the z-values (which we need to use later for depth comparison).

Element with lower zindex and rotation applied ignores higher zindexes in Google Chrome

I am trying to create a box which I can hover and additionally I need to rotate image behind the hover hitbox. But it seems that in Google Chrome specifically one part of image is in front of hitbox and the other one is behind despite the fact that hitbox is z-index:2 and image is z-index: 1.
Here is a demo.
CSS:
.hitbox {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 2;
background-color: rgba(255,50,0,0.3);
}
img.img-ele {
position: absolute;
top: 0;
left: 0;
z-index: 1;
-webkit-transform: rotateX(15deg) rotateY(12deg);
-moz-transform: rotateX(15deg) rotateY(12deg);
-ms-transform: rotateX(15deg) rotateY(12deg);
-o-transform: rotateX(15deg) rotateY(12deg);
transform: rotateX(15deg) rotateY(12deg);
}
HTML:
<div class="container">
<div class="box">
<div class="hitbox"></div>
<img src="http://placehold.it/111x89/000" class="img-ele" />
</div>
</div>
<div class="inside-container">Inside container</div>
<div class="inside-hitbox">Inside hitbox</div>
Is there a workaround or a different html markup I should try?

Prevent children from inheriting rotate transformation in CSS

I am performing a CSS transform: rotate on a parent, yet would like to be able to negate this effect on some of the children - is it possible without using the reverse rotation?
Reverse rotation does work, but it affects the position of the element, and it may have a negative performance impact (?). In any case, it doesn't look like a clean solution.
I tried the "transform: none" suggestion from this question prevent children from inheriting transformation css3, yet it simply doesn't work - please see the fiddle here: http://jsfiddle.net/NPC42/XSHmJ/
May be you have to write like this:
.child {
position: absolute;
top: 30px;
left: 50px;
background-color: green;
width: 70px;
height: 50px;
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
transform: rotate(-30deg);
}
Check this for more http://jsfiddle.net/XSHmJ/1/
Updated:
You can use:after & :before psuedo class for this.
check this http://jsfiddle.net/XSHmJ/4/
I believe that you are going to need to fake it using a second child, the specification does not seem to allow for the behavior you would like, and I can understand why the position of a child element has to be affected by a transform to its parent.
This isn't the most elegant of solutions, but I think you're trying to do something that the specification is never going to allow. Take a look at the following fiddle for my solution:
.parent {
position: relative;
width: 200px;
height: 150px;
margin: 70px;
}
.child1 {
background-color: yellow;
width: 200px;
height: 150px;
-webkit-transform: rotate(30deg);
-moz-transform: rotate(30deg);
-o-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
.child2 {
position: absolute;
top: 30px;
left: 50px;
background-color: green;
width: 70px;
height: 50px;
}
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
If you want to apply transforming effects on a parent without affecting its children, you can simply animate a parent's pseudo-element like this:
.parent {
display: inline-block;
position: relative;
}
.parent::before {
content: "";
background: #fab;
/* positioning / sizing */
position: absolute;
left: 0;
top: 0;
/*
be aware that the parent class have to be "position: relative"
in order to get the width/height's 100% working for the parent's width/height.
*/
width: 100%;
height: 100%;
/* z-index is important to get the pseudo element to the background (behind the content of parent)! */
z-index: -1;
transition: 0.5s ease;
/* transform before hovering */
transform: rotate(30deg) scale(1.5);
}
.parent:hover::before {
/* transform after hovering */
transform: rotate(90deg) scale(1);
}
This actually worked for me. JSFiddle

Resources