Applying a border to a CSS transform perspective image - border

So I'm trying to skew a static Google map result so it looks like you're looking down "into it". Anyway, i've got it working using CSS3 transforms:
<html><head>
<style>
.container {
margin-left: 200px;
-webkit-perspective: 600;
-moz-perspective: 600;
-ms-perspective: 600;
-o-perspective: 600;
perspective:600;
-webkit-perspective-origin: top;
-moz-perspective-origin: top;
-ms-perspective-origin: top;
-o-perspective-origin: top;
perspective-origin: top;
width: 400px;
}
.test {
width: 100%;
-webkit-transform: rotateX(89deg);
-moz-transform: rotateX(80deg);
-ms-transform: rotateX(80deg);
-o-transform: rotateX(80deg);
transform: rotateX(80deg);
}
img.map {
border-radius: 200px;
}
</style></head><body>
<div class=container>
<div class=test><img class="map" src="https://maps.googleapis.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=18&sensor=false&scale=1&format=png&maptype=roadmap&size=400x400&markers=icon:http://tron.robotholocaust.com/pin2.png%7Cshadow:false%7C40.714728,-73.998672"></div>
Which gives you:
I'd like to put a border around that though.
If I add
img.map{
border: 5px solid;
border-radius: 200px;
}
I instead get:
How can I get that border to apply properly? Do I need to do some other CSS trick? (And yes, this only works in Chrome & Safari regardless of the other extensions I've added sadly).

The following works, if you apply the same radius to the .test element, and put the border there (but you may prefer the border on the actual img tag; I couldn't solve that.
.test {
border: 3px solid black;
border-radius: 200px;
}

Related

Make child element unaffected by rotation of parent element

I have two div elements: one parent element, which is rotated, and one child element that I need to be unaffected by the rotation of the parent element.
To achieve this, I have attempted to rotate the child element in the opposite direction of the parent element. This works in some cases. For instance, if I rotate the elements like this ...
.parent {
transform: rotate(30deg);
}
.child {
transform: rotate(-30deg);
}
... the child element will appear straight and undistorted. But if I rotate them with rotateX ...
.parent {
transform: rotateX(30deg);
}
.child {
transform: rotateX(-30deg);
}
... the child element still looks rather distorted.
The actual code uses both rotateX and rotateZ in order to make the parent element appear isometric. It currently looks like this:
.happy_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotate(30deg);
}
.happy_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotate(-30deg);
}
.sad_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotateX(-60deg) rotateZ(45deg);
}
.sad_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotateX(60deg) rotateZ(45deg);
}
<div class="happy_parent">
<div class="happy_child"></div>
</div>
<div class="sad_parent">
<div class="sad_child"></div>
</div>
Notice that the upper divs are both rendered correctly, but the lower child-div is still distorted.
What am I missing here?
It is not possible to have the innerElement (childElement) to remain in initial state when rotated in 3D by rotating back in -ve deg.
It will work when rotation takes place in 2D .
But you can give a try to transform-style: preserve-3d to see the shapes in 3D effect when rotated with Z coordinate also and preserve the shape instead of just showing in 2D .
You have to reverse the order of rotation too in 3D rotation
You can try to remove the transform-style: preserve-3d and see the effect
.happy_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotate(30deg);
}
.happy_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotate(-30deg);
}
.sad_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotateX(-60deg) rotateZ(45deg);
transform-style: preserve-3d;
}
.sad_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotateZ(-45deg) rotateX(60deg);
}
<div class="happy_parent">
<div class="happy_child"></div>
</div>
<br><br><br><br>
<div class="sad_parent">
<div class="sad_child"></div>
</div>

Can I calculate the size of my transformed element?

For example, I apply to my element perspective(200px), transform: scale(1.5); and translateZ(100px) properties. So, how can I calculate what size will have my transformed element? Is there any formula?
I think this question is more relevant when we use perspective together with translateZ, because mainly in these situations I don't know for sure how my element will look like.
.green {
width: 300px;
height: 300px;
outline: 1px solid black;
background: yellowgreen;
margin: 50px;
transform-origin: 400px 0px;
transform: perspective(200px) scale(1.5) translateZ(100px);
}
<div class="green"></div>
I'm not completely clear whether this fulfills your requirements, but it appears that Element.getBoundingClientRect() will return the transformed dimensions of the element:
const elWithTransforms = document.querySelector('#elementWithTransforms');
const elWithoutTransforms = document.querySelector('#elementWithoutTransforms');
const transDimensions = elWithTransforms.getBoundingClientRect();
const noTransDimensions = elWithoutTransforms.getBoundingClientRect();
console.log(`Green element dimensions:\n width: ${transDimensions.width}\n height: ${transDimensions.height}`);
console.log(`Purple element dimensions:\n width: ${noTransDimensions.width}\n height: ${noTransDimensions.height}`);
.green {
width: 300px;
height: 300px;
outline: 1px solid black;
background: yellowgreen;
margin: 50px;
transform-origin: 400px 0px;
transform: perspective(200px) scale(1.5) translateZ(100px);
}
.purple {
width: 300px;
height: 300px;
outline: 1px solid black;
background: purple;
margin: 50px;
}
<div class="green" id="elementWithTransforms" ></div>
<div class="purple" id="elementWithoutTransforms" ></div>
I wasn't certain if this was something you needed to do ahead of time on paper, or something you could do with JS in the browser. If the latter, this should fulfill your needs.
If it is important that this happen before the element is visible, you have some options. getBoundingClientRect() will return all zeroes if called before the element is attached to the DOM, but you can attach the element to the DOM offscreen/invisible and get the dimensions from getBoundingClientRect(), and then remove the element, do any additional work you need to do, and reattach it after unhiding it.
const body = document.querySelector('body');
const div = document.createElement('div');
div.classList.add('green');
div.classList.add('hideOffScreen');
body.appendChild(div);
console.log(div.getBoundingClientRect());
.green {
width: 300px;
height: 300px;
outline: 1px solid black;
background: yellowgreen;
margin: 50px;
transform-origin: 400px 0px;
transform: perspective(200px) scale(1.5) translateZ(100px);
}
.hideOffScreen {
position: absolute;
left: -9999px;
z-index: -1;
visibility: hidden;
}

input top border disappears in windows chrome

code
<div class="center">
<div class="parent">
<label>姓名</label>
<input type="text">
</div>
</div>
.center {
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
}
.parent {
padding: 8px 0;
}
label {
margin-left: 20px;
}
input {
width: 100px;
height: 41px;
}
I want to know why the top border of the input disappears.I would be appreciated if someone answers me.
os: win10
browser: chrome 51.0.2704.84m
Thanks.
The problem is occurring because of transform: translate(-50%, -50%);
You can modify your css to removing transform
.center {
position: relative;
width: 100%;
}
.parent {
padding: 8px 0;
margin: 15% auto;
width: 100px;
}
label {
margin-left: 20px;
}
input {
width: 100px;
height: 41px;
}
This is a graphical glitch caused by your element being rendered on a sub-pixel by the translation transform (ie: 10.5px or the like).
There are some known solutions to fix this issue, though I haven't had much luck with them:
1) Use transform: transform: translate(-50%, -50%) perspective(1px);
2) On the parent element, add.
.parent {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
}
source: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
If you do not require support for older browsers, you may use flexbox:
https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/

Saffari border radius overflow issue

I have a situation like this: http://jsfiddle.net/uqhwt1wj/
HTML:
<div class="activity_rounded">
<img class="image" src="http://i.imgur.com/059cOzT.png?1" />
</div>
CSS:
.activity_rounded{
width: 165px;
height: 165px;
border-radius: 165px;
-moz-border-radius: 165px;
overflow: hidden;
margin: 0 auto;
position: relative;
margin-bottom: 30px;
background: #FFDE15;
}
.image{
max-width: 226px;
height: auto;
position: absolute;
left: 50%;
transform: translateX(-50%);
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
}
It works all good in all browsers, however in safari it seems like overflow: hidden ignores border radius of the block and hides overflow only for full div block(square). Tried to Google around, but haven't seen any solutions with horizontal centering that would work properly in my case.
Any suggestions, links or comments would help a lot.
in this case cross-browser solution that I decided to use was: using image as background image of a div instead of wrapping image element inside a div.
So now code looks like this(DEMO):
HTML:
<div class="activity_rounded"></div>
CSS:
.activity_rounded{
width: 165px;
height: 165px;
border-radius: 165px;
-moz-border-radius: 165px;
overflow: hidden;
margin: 0 auto;
position: relative;
margin-bottom: 30px;
background: url('http://i.imgur.com/059cOzT.png?1') no-repeat center #FFDE15;
}
Hope this helps to anyone as well.

How do I create 3D perspective using CSS3?

I have been trying to create a 3D looking card-flip type of animation for a project I've been working on. Unfortunately my animation doesn't look entirely 3D.
I've been using this guide. In the first example the person managed to make it look like the windows background was flipping. However when I tried to use the same code on JSFiddle the result was not the same as his.
His demo code made the effect below. When the card is being flipped it causes one side to get smaller giving the impression of perspective:
On my JSFiddle using his code (except a different background), the sides appear to stay the same size the entire time:
Can someone explain to me what I have missed, or how to get the same perspective effect he had on his website? Thanks in advance.
His HTML code:
<div id="f1_container">
<div id="f1_card" class="shadow">
<div class="front face">
<img src="/images/Windows%20Logo.jpg"/>
</div>
<div class="back face center">
<p>This is nice for exposing more information about an image.</p>
<p>Any content can go here.</p>
</div>
</div>
</div>
His CSS code:
#f1_container {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
}
#f1_container {
perspective: 1000;
}
#f1_card {
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: all 1.0s linear;
}
#f1_container:hover #f1_card {
transform: rotateY(180deg);
box-shadow: -5px 5px 5px #aaa;
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.face.back {
display: block;
transform: rotateY(180deg);
box-sizing: border-box;
padding: 10px;
color: white;
text-align: center;
background-color: #aaa;
}
See where he says he's stripped the vendor prefixes out of his CSS to keep things clean? I'm betting that's your problem. Some of those CSS properties aren't fully standard, but are implemented in different browsers with different vendor prefixes. I'm not actually sure which ones, but Google can help with that.
Edit: Hmm. Well, the CSS is the culprit anyway, but I don't actually see a lot of vendor prefixes. I pulled his actual CSS off of the page, and pasted it in place of the "clean" CSS you used, which makes the fiddle work. His real CSS is:
#f1_container {
height: 281px;
margin: 10px auto;
position: relative;
width: 450px;
z-index: 1;
}
#f1_container {
perspective: 1000px;
}
#f1_card {
height: 100%;
transform-style: preserve-3d;
transition: all 1s linear 0s;
width: 100%;
}
#f1_container:hover #f1_card, #f1_container.hover_effect #f1_card {
box-shadow: -5px 5px 5px #AAAAAA;
transform: rotateY(180deg);
}
.face {
backface-visibility: hidden;
height: 100%;
position: absolute;
width: 100%;
}
.face.back {
-moz-box-sizing: border-box;
background-color: #AAAAAA;
color: #FFFFFF;
display: block;
padding: 10px;
text-align: center;
transform: rotateY(180deg);
}
They had some CSS incorrect...in the example, he had class .back.face, which should have been .face.back (not why it wasn't working, as pointed out. Just cleaned it up). Other issues were the culprit as other posters pointed out. I've created a new jsFiddle. I'd go the jQuery flip plug-in over this though, as IE will have a hard time rendering such effect.
http://jsfiddle.net/JJrHD/1/