3d transformation, inverse transformation not symmetrical - css

I have two containers, each contains a nested div structure that are having the 3d transformations applied to them. The effect is to simulate a piece of paper being unfolded down the centre line.
You see the current state of the code in this JSFiddle.
The problem that I have encountered is attempting to reverse the right had animation on the left.
I've achieved what I have already by placing each starting segment with translate3d().
The HTML structure is as follows.
<div class="container">
<div class="left">
<div class="slice s1">
<div class="slice s2"></div>
</div>
</div>
<div class="right">
<div class="slice s1">
<div class="slice s2"></div>
</div>
</div>
</div>
The .left and .right elements are positioned absolutely within .container and set to left:50% to centre them. The first element of .left is then given a negative left:-100px to position it correctly.
.container {
position:absolute;
margin-left:-200px;
left:50%;
}
.left, .right {
width: 200px;
-webkit-perspective: 500px;
-moz-perspective: 500px;
perspective: 500px;
position: absolute;
}
.left {
left: -100px;
}
.right {
left:0;
}
The transform3d() then places each segment either 99px to the right or 99px to the left depending on their container.
If you see the JSFiddle , you'll notice that the angles are off on the left hand portion. I am not sure how to fix this to make it all evened out and symmetrical.
The 3d planes are not right as demonstrated in this inspection in Chrome:
Can anyone help guide me to making this symmetrical?

The 2 sides are symetrical, it's your point of view that isn't.
Try:
.right {
left:0;
-webkit-perspective-origin: 0px 150px;
perspective-origin: 0px 150px;
}
And will solve it.
An even better approach would be to have the left and right sides have the size that you see (they are bigger on the right).
That would make the perspective point by default (center center) to be also symetrical, and wouldn't need to set it to an arbitrary value

Related

CSS: center element between floating elements

Pretty simple question, but can't seem to find the solution. I have 5 elements: 2 floating left, 2 floating right. The fifth element is supposed to be in the perfect center of the div (#infographic), no matter what the screen width is.
example:
1,2 -- 3 -- 4,5 OR 1,2 ----- 3 ----- 4,5
HTML code:
<div id="infographic">
<div class="icon-one"></div>
<p>me</p>
<div class="arrows"></div>
<p>customer</p>
<div class="icon-two"></div>
</div>
Any suggestions to get the element in the center?
I guess this is the output you are looking for :
DEMO
html, body,p{
margin:0;
padding:0;
}
#infographic * {
width:10%;
height:30px;
background:teal;
padding:0;
margin:0 1%;
}
#infographic .icon-one, #infographic .icon-one + p {
float:left;
}
#infographic .icon-two, #infographic .icon-two + p {
float:right;
}
#infographic .arrows{
margin:0 auto;
text-align:center;
}
<div id="infographic">
<div class="icon-one"></div>
<p>me</p>
<div class="icon-two"></div>
<p>customer</p>
<div class="arrows">arrows</div>
</div>
If 12 and 45 have fixed width you can not achieve this using css float, you must use something like absolute positionning instead.
For more information qive a link to your page in its current state, or some more code.
Try this:
If you have two floated divs, then you know the margins. The problem
is that the float:right div should be put before the middle div. So
basically you will have:
left-floated | right-floated | centered
Now, about the margins: usually you can just use margin:0 auto, right?
The problem is that right now you know the values of the margins:
floated divs! So you just need to use:
margin:0 right-floated-width 0 left-floated-width
That should work...
See: this answer
Add position: relative to the container to allow the .arrows to be positioned absolutely relative to the container. Position the .arrows at the center of the container by using top: 50% and left: 50% (the percentages are relative to the container) and then move the .arrows a bit to the top left by using transform: translate(-50%, -50%) (percentages are relative to the .arrows)
.arrows {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
See http://codepen.io/ckuijjer/pen/rhEgy for an example or http://css-tricks.com/centering-css-complete-guide/ for a complete tutorial on horizonal/vertical centering.
If it's only about horizontal centering you might even be able to use
.arrows {
margin: 0 auto;
}
as floating elements are taken outside of the normal document flow
First, it should be possible to group the left and right floated elements together. What we can then do is create a 'fake' wrapper that fills up the entire container. If we know the width of the element to be centered, this can then be centered using a margin.
<div id="infographic">
<div class='leftcol left'>
<div class="icon-one left">1</div>
<p class='left'>me</p>
<div class='clear'></div>
</div>
<div class='rightcol right'>
<p class='right'>customer</p>
<div class="icon-two right">2</div>
<div class='clear'></div>
</div>
<div class='center'>
<div class="arrows">A</div>
</div>
</div>
CSS:
.left {
float: left; }
.right {
float: right;}
.center {
overflow: hidden;
position: absolute;
width: 100%;
}
.arrows {
margin: 0 auto;
display: block;
width: 30px;
}
.clear {
clear: both;
}
#infographic {
position: relative;
}
If we do not know the width of the centered element, take a look at the question Centering a div block without the width and apply the solution there.
Note that the solution presented assumes that the center width is never so wide that it will become wider than the two columns on the left and the right. If you want to have safeguards for that you should set a maximum width percentage like so (the example restricts each column to one-third of the total width):
.leftcol .rightcol .arrows {
max-width: 33.3%
}

Css overlapperd click

I'm building a strange div shaped structure and I need a hint to resolve a clicking problem.
This is a jsfiddle to show you the issue.
The structure for each element is:
<div class="views-row">
<div class="diamonds-container">
CONTENT
</div>
</div>
I have a onclick() event on .diamonds-container but the .views-row div of the next element [with red or blue background..] go over the container and stop the click event on it.
I tryed to play with the z-index but I didn't have the expected result.
How can I achieve this structure with a correct click event on diamonds-containers ?
I think I can track the .views-row click with javascript and trigger manually a click on the previous diamonds-container but this will be my final option.
How can I achieve this without javascript?
UPDATE:
I have to position my diamonds like this
so I can't use the #matewka code because I will have the overlaping vertically instead of orizzontally..
There is more than one route for this kind of problem.
If you use the rotation transform anyway, why not rotate the .views-row element to get the bounding box out of the way?
For recent browsers and IE11 there are pointer events. See this updated fiddle.
.views-row {
z-index: 1;
pointer-events: none;
}
.diamonds-container {
z-index: 9;
pointer-events: auto;
}
Here is my approach. I'm not sure if nesting two divs inside each other was for rotating purpose or had some other meaning. Anyway, I did it this way:
.views-row {
width: 130px;
height: 130px;
-webkit-transform: rotate(45deg);
}
.views-row-first {
-webkit-transform-origin: 195px center;
}
.views-row-even {
-webkit-transform-origin: center center;
}
.views-row-odd {
-webkit-transform: rotate(-45deg);
-webkit-transform-origin: -65px center;
}
Each .views-row is rotated and the transform origins are all pointed to the center of the middle div. Notice that the transform-origin values are multiplicities of the half of the width (130px / 2).
See the updated FIDDLE for the complete CSS. I also added a :hover property for .diamonds-container so you can see that they're all clickable.
UPDATE
With the picture you added the problem became much more complicated. But I figured it out.
Hint: If you can't wait for the fiddle - you'll find it at the bottom of the answer.
The idea:
Square boxes are nested twice. Each 2 .diamond boxes are wrapped with the .pair-wrapper div. That div is rotated 45deg and it is repeated few times along its container. Each even .pair-wrapper has increased width to position its right-hand neighbour properly.
A bunch of .pair-wrappers are wrapped with the .line-wrapper. You can add as much .line-wrappers and .pair-wrapper as you want (remember - .pair-wrappers will break into the new line if they don't fit).
Finally, each .line-wrapper has fixed height and hidden overflow to restrict its children area from the top and the bottom. Each .pair-wrapper is positioned relatively and has negative top value.
The solution is based mostly on fixed values, both I could figure out a better idea.
The code
Example HTML markup looks like this:
<div class="line-wrapper line-wrapper-odd">
<div class="pair-wrapper pair-wrapper-odd">
<div class="diamond-box"></div>
<div class="diamond-box"></div>
</div>
<div class="pair-wrapper pair-wrapper-even">
<div class="diamond-box"></div>
<div class="diamond-box"></div>
</div>
<div class="pair-wrapper pair-wrapper-odd">
<div class="diamond-box"></div>
<div class="diamond-box"></div>
</div>
</div>
<div class="line-wrapper line-wrapper-even">
<div class="pair-wrapper pair-wrapper-odd">
<div class="diamond-box"></div>
<div class="diamond-box"></div>
</div>
.....
</div>
.....
And the most important parts from CSS (complete CSS in the fiddle):
.line-wrapper {
height: 170px;
overflow: hidden;
}
.line-wrapper-even {
margin-left: -92px;
}
.pair-wrapper {
width: 130px;
position: relative;
top: -26px;
-webkit-transform: rotate(45deg);
}
.pair-wrapper-odd {
-webkit-transform-origin: 65px 65px;
}
.pair-wrapper-even {
-webkit-transform-origin: 92px 131px;
width: 239px;
}
.diamond-box {
width: 130px;
height: 130px;
}
The fiddle
http://jsfiddle.net/N3V6J/3/

floating a div over an (absolutely positioned?) background div (or image)

I couldn't seem to find a reference to this problem anywhere after lengthy searching. This probably means I am missing basic concepts but I am going to go ahead and ask anyway. I am trying to have a float:left <div> overlay a background image. A simplified version of the problem is below (with a div representing the image for quick reproducibility)
<div style='position: absolute; background-color: blue; width: 500px; height: 500px'>
BACKGROUND DIV
</div>
<div style='float: left; background-color: yellow; width: 100px; height: 100px'>
FLOATING IMAGE
</div>
It seems the absolutely positioned div overlays the float. How do I sort this out - without resorting to the background-image property of the parent (this is not an option) ?
Set position:relative; on the floating element and assign a z-index:1; to the background and z-index:2; to the floating image.
<div style='position: absolute; background-color: blue; width: 500px; height: 500px'>
BACKGROUND DIV
</div>
<div style='position:relative; float: left; background-color: yellow; width: 100px; height: 100px; z-index:2;'>
FLOATING IMAGE
</div>
EDIT: here's a jsfiddle for your reference: http://jsfiddle.net/exUm7/1/
Div overlay is not a good idea other than if you are doing game kind of thing. I think is batter if you plan your layout as much as without overlay. It will make you easy.
but if you must need to do this. Here we go
<div style='float:left; background-color:blue; width:500px; height:500px; z-index:1'>
BACKGROUND DIV
</div>
<div style='float:left; margin-left:-500px; background-color:yellow; width:100px; height:100px; z-index:2'>
FLOATING IMAGE
</div>

Div is not moving nearby divs

I have something like this:
<div class="top">top</div>
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
</div>
<div class="bottom">bottom</div>
Relevant code in jsFiddle
As you can see, between top and bottom divs, there is a div container. I want this div container to move bottom dive as much as is needed (and i don't want it to be a fixed value - that means if, lets say left container will get much higher - the bottom div will be pushed down as well.
How can i do that?
This is a simple seeming problem that ends up being kind of tricky. The above suggestion about position:relative vs. position:absolute are a good first step. After that you need to make some room for the set width right div:
.left {
height: 100%;
min-height: 50px;
border:1px dashed red;
padding-right: 50px; <---
}
Then float your right div in the space you made:
.right {
float:right; <---
width: 50px; (This needs to match the padding-right value above.)
text-align: right;
min-height: 50px;
height: 100%;
border:1px dashed blue;
}
Finally, put the right div before the left div in the html:
<div class="top">top</div>
<div class="container">
<div class="right">right</div>
<div class="left">left</div>
</div>
<div class="bottom">bottom</div>
(Tested in Chrome and IE.)
See: Right div fix width, left div extend to max width?
You can check out a fiddle here: http://jsfiddle.net/x3QfG/1/
Will that work for you?
Right now you're using absolute positions for the left/right div's, so you will always need to know the height in order to position the bottom div correctly. What you want to do is float these instead, then clear the floats in the bottom div. That way the left/right can be as high as their contents, and the bottom div will always appear below.
.bottom {
clear: both;
}
.left {
float: left;
width: 50%;
min-height: 50px;
}
.right {
float: right;
width: 50%;
min-height: 150px;
}
I've modified your jsFiddle accordingly, and made the right div higher to show how the bottom always appears below.
Use floats rather than positioning them absolutely. That will make your architecture very much fluid and flexible.
After you apply necessary float values to your .left and .right, use a clearfix hack to contain your floated elements within the container. Now whenever any of the .left or .right divs increase in height, the bottom div will be pushed down.
Make Container Relative and left and right absolute,and for positioning set width rather than using float.

Placing a div sidebar next to a centered div

I've found a lot of variations to this question within SO, but it seems no matter what I try I can't get this (seemingly very simple!) thing working!
What I'm trying to do is to keep the 'centered' div in the center of the viewport and to place the 'sidebar' div directly to its right (i.e. not right-aligned to the viewport) without affecting the centering of the 'centered' div.
Here's some test code on jsfiddle:
http://jsfiddle.net/6wCyr/13/
Everything I've read seems to imply that the float property is exactly what I'm looking for, but the results in the link show that I get weird results wherein the right sidebar is placed below the 'centered' div rather than beside it. That's what's shown in the link.
I've also seen a solution involving using a negative value for the right property, and setting the width of the sidebar exactly, but I couldn't get that one going either.
Hopefully this question is as easy to solve as I think it should be! Just can't seem to find the right set of div inside div and so forth. Hard to debug these alignment issues!
Thanks!
Live Demo
I moved div.sidebar inside div.centered.
I added position: relative to div.centered.
We're using this technique.
You don't have to declare a fixed width on div.sidebar.
CSS:
div.centered {
margin-left: auto;
margin-right: auto;
border: dashed;
width: 100px;
height: 100px;
position: relative
}
div.sidebar {
border: dotted;
position: absolute;
top: 0;
left: 100%
}
HTML:
<div class="holder">
<div class="centered">
CENTERED
<div class="sidebar">
RIGHT SIDEBAR
</div>
</div>
</div>
Try this.
http://jsfiddle.net/DOSBeats/6wCyr/16/
.holder {
margin:0 auto;
width:100px;
}
.centered {
border: dashed;
float:left;
height: 100px;
}
.sidebar {
border: dotted;
float:left;
margin-right:-100px;
width:100px;
}
If you do not set a width to your holder and center it, the sidebar will float to the edge of the window.
Try this:
HTML:
<div id="holder">
<div id="sidebar">Sidebar</div>
<div id="centered">Centered</div>
</div>
CSS:
#holder{
margin:auto;
width:500px;
}
#sidebar{
border:dotted;
float:left;
width:100px;
}
#centered{
border:dashed;
margin-left:110px;
width:380px;
}

Resources