CSS use transform-origin to position a rotated element - css

I can't work out how to rotate an element so that it sits underneath another one. The image below should illustrate the intended result.
Here is what I have tried so far:
.div1 {
height: 120px;
width: 120px;
float: left;
margin: 20px;
border: solid 1px #000;
overflow: hidden;
}
.div1 button {
width: 48px;
height: 48px;
border: 0;
margin: 0;
padding: 0;
}
.div2 {
background-color: #999;
height: 48px;
line-height: 48px;
box-sizing: border-box;
}
.originFromLeft .div2 {
transform: rotate(90deg);
transform-origin: 24px 24px;
padding-left: 12px;
text-align: left;
}
.div1.originFromRight {
overflow: visible;
}
.originFromRight .div2 {
padding-right: 12px;
text-align: right;
transform: rotate(-90deg);
transform-origin: right top;
}
<div class="div1">
<button>></button>
<div class="div2">HELLO</div>
</div>
<div class="div1 originFromLeft">
<button>></button>
<div class="div2">HELLO</div>
</div>
<div class="div1 originFromRight">
<button>></button>
<div class="div2">HELLO</div>
</div>
The second example basically does what I want but the text is orientated the wrong way.
The closest I can get is example 3 but I need to pull this back to the left. I've tried translate but I can't get it to work, I've tried a negative right margin of 100% which almost works but basically doesn't.

One method to achieve the expected output would be to do the following:
Put the button within div2 and position it at the right edge.
Absolutely position the div2 at the bottom of the parent container.
Rotate the div2 in counter clockwise direction (-90deg) with the transform origin at left bottom.
After rotation, the div2 would entirely go outside of the container and hence we need to add an extra translateY(100%) to the transform stack.
The text is aligned to the right and an extra padding-right (greater than the width of the button) is added to keep the text away from the button.
The button would also get rotated by -90 degree because it is a child of div2 and to counter that (that is to make the button text get displayed properly), we need to apply counter rotation.
Now, in this approach the only drawback is that if the text length increases beyond what can be fit in a single line then it would wrap around to the next line (have a look at the second sample in snippet).
.div1 {
position: relative;
height: 120px;
width: 120px;
float: left;
margin: 20px;
border: solid 1px #000;
overflow: hidden;
}
button {
position: absolute;
display: inline-block;
bottom: 0;
right: 0;
width: 48px;
height: 48px;
border: 0;
margin: 0;
padding: 0;
transform: rotate(90deg);
}
.div2 {
position: absolute;
box-sizing: border-box;
bottom: 0px;
height: 48px;
width: 100%;
padding-right: 60px;
line-height: 48px;
background-color: #999;
text-align: right;
transform: rotate(-90deg) translateY(100%);
transform-origin: left bottom;
}
<div class="div1">
<div class="div2">HELLO
<button>></button>
</div>
</div>
<div class="div1">
<div class="div2">HELLO WORLD!!!!!
<button>></button>
</div>
</div>

I have taken your second example and rotated the element the other way round.
And then fixed the position with an extra translateX
.div1 {
height: 120px;
width: 120px;
float: left;
margin: 20px;
border: solid 1px #000;
overflow: hidden;
}
.div1 button {
width: 48px;
height: 48px;
border: 0;
margin: 0;
padding: 0;
}
.div2 {
background-color: #999;
height: 48px;
line-height: 48px;
box-sizing: border-box;
}
.originFromLeft .div2 {
transform: rotate(-90deg) translateX(-100%);
transform-origin: top left;
padding-left: 12px;
text-align: right;
}
<div class="div1 originFromLeft">
<button>></button>
<div class="div2">HELLO</div>
</div>

Related

How to align a text to center horizontally and also to the bottom of page?

I want to align a text to center of the page horizontally and also at the bottom of the page, with a background to text. The text here is variable. I want to break the text into more lines, if it crosses width more than 30% of screen size.
I am either able to align div to center or stick to bottom of the page, but couldn't do both. When I give position to absolute or fixed, The center alignment is missing and I have to give left: 30% to move it right.
This is the HTML
<div class="div-1">
<div class="div-2">
Hey this is an amazing way to do this
</div>
</div>
This is the CSS:
.div-1 {
height: 100vh;
}
.div-2 {
bottom: 10px;
background-color: black;
position: absolute;
color: white;
font-size: 20px;
max-width: 30%;
}
Can someone suggest the perfect way to do this ? Thanks.
For starters, change className to class. Then add
position: fixed;
left: 50%;
bottom: 20px;
transform: translate(-50%, -50%);
margin: 0 auto;
to .div-2
.div-1 {
height: 100vh;
}
.div-2 {
background-color: black;
color: white;
font-size: 20px;
max-width: 30%;
position: fixed;
left: 50%;
bottom: 20px;
transform: translate(-50%, -50%);
margin: 0 auto;
}
<div class="div-1">
<div class="div-2">
Hey this is an amazing way to do this
</div>
</div>
You should use the least amount of tag as possible.
In order to center horizontal, use text-align: center and make sure that the width of the container is 100%.
To reduce the width of the text; use padding for the container.
<footer>
Hey this is an amazing way to do this
</footer>
footer {
position: fixed; bottom: 0; left: 0;
text-align: center; width: 100%; box-sizing: border-box;
padding: 15px 35%; background: blue; color: white;
text-transform: uppercase; font-weight: bold;
}
It should be something like this. You can use className as you are using it in React.
.div-1 {
height: 100vh;
}
.div-2 {
bottom: 0;
background-color: red;
position: absolute;
color: white;
font-size: 20px;
max-width: 30%;
height: 400px;
width: 300px;
margin: 0 auto;
text-align: center;
vertical-align: middle;
line-height: 400px;
}
<div class="div-1">
<div class="div-2">
Hey this is an amazing way to do this
</div>
</div>

Align to left side of contaner a element rotated -90deg

div {
width: 300px;
height: 300px;
border:1px solid black;
}
h1 {
width: 300px;
transform: rotate(-90deg)
}
<div>
<h1>Hola</h1>
</div>
If you try this snippet, you will see that the h1 is rotated and placed in the center of the div (makes sense, they have same width)
But how to align it to the left? (flexible container's width)
You can position the h1 element absolutely with respect to the parent div and then use transform-origin property to specify the axis about which the rotation should happen.
In the below snippet, the element is positioned at the bottom of the parent and because the origin is set at left-bottom, the left-bottom of the element (h1) stays at its position during rotation.
Now because of the rotation, the element would go outside of the parent after rotation. To bring it back into position add translateY(100%) to the transform stack. A text-align: right is added to set the content at left-top. The text-align makes it look a bit more hackish than it actually is but otherwise it is difficult to position at left-top.
div {
position: relative;
width: 300px;
height: 300px;
border: 1px solid black;
}
h1 {
position: absolute;
display: inline-block;
bottom: 0px;
width: 300px;
text-align: right;
transform: rotate(-90deg) translateY(100%);
border: 1px solid;
transform-origin: left bottom;
}
div, h1 {
margin: 0px;
padding: 0px;
}
<div>
<h1>Hola</h1>
</div>
Note to future visitors: Unlike using static values for positioning, this solution using translateY() would be able to adapt itself automatically even if the length of the content increases or spans multiple lines like in the below snippet. Again, the only drawback would be that the text would be right aligned.
div {
position: relative;
display: inline-block;
width: 250px;
height: 250px;
border: 1px solid black;
}
h1 {
position: absolute;
display: inline-block;
bottom: 0px;
width: 250px;
text-align: right;
transform: rotate(-90deg) translateY(100%);
border: 1px solid;
transform-origin: left bottom;
}
div,
h1 {
margin: 0px;
padding: 0px;
}
<div>
<h1>Halooo</h1>
</div>
<div>
<h1>Some lengthy content which wraps around</h1>
</div>
check this out it will give a direction to your required solution..
div {
width: 300px;
height: 300px;
border: 1px solid black;
}
h1 {
width: 70px;
margin-left: -20px;
float: left;
transform: rotate(-90deg)
}
<div>
<h1>Hola</h1>
</div>
Updated
Or you can do in this way also
div {
width: 300px;
height: 300px;
border: 1px solid black;
}
h1 {
position: absolute;
left: -10px;
top: 2px;
transform: rotate(-90deg)
}
<div>
<h1>Hola</h1>
</div>

Divs side-by-side, centred, and overflowing edge of screen

I am trying to design a landing page to link to 2 web apps. I am trying to make the design as visually attractive as possible. I think it would look good if the Divs containing the links were side-by-side at the centre of the screen, with their edges overflowing the left and right of the screen. I can then put a border-radius on them and some nice blocky colour:
Goal:
I have tried numerous options, including inline-block and overflow:hidden:
HTML
<div id="centre-pane">
<div class="app-btn">
<img src="icon.png">link text
</div>
<div class="app-btn">
<img src="icon2.png">link text
</div>
</div>
CSS
.app-btn
{
width:1000px;
height:320px;
display:inline-block;
border:10px solid black;
border-radius: 50px;
}
#centre-pane {
width:2000px;
margin:0 auto;
text-align:center;
overflow-x: hidden;
}
Is this possible? I have found several ways of getting them side-by-side (eg here) but nothing that also lets them overflow the screen.
Just using position absolute would do the trick.
I've added a wrapper but it may not be required.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html,
.wrapper {
height: 100%;
}
.wrapper {
position: relative;
}
.btn {
width: 45%;
height: 30%;
background: lightblue;
border: 2px solid blue;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.left {
left: 0;
border-radius: 0 25% 25% 0;
border-left: none;
}
.right {
right: 0;
border-radius: 25% 0 0 25%;
border-right: none;
}
<div class="wrapper">
<div class="btn left"></div>
<div class="btn right"></div>
</div>
You can achieve this with absolute positioning and negative margins (for the right item). You'll have to fix the size of the body though in order to achieve the effect. I've also added individual classes to the first and second item respectively (.app-btn-1 and .app-btn-2):
body {
width: 2000px;
overflow-x: hidden;
}
.app-btn {
width:1000px;
height:320px;
position: absolute;
border:10px solid black;
border-radius: 50px;
overflow-x: hidden;
}
.app-btn-1 {
left: -500px;
text-align: right;
}
.app-btn-2 {
left: 100%;
margin-left: -500px;
}
DEMO
NOTE: For my demo to look right in jsfiddle, I've quartered the sizes so you can see the effect in the small window
Here is the code you need:
.menu {
display: inline-block;
height: 200px;
width: 40%;
margin-top: calc(50% - 100px);
border: 2px solid red;
background-color: brown;
color: black;
text-decoration: none;
transition: all 0.5s;
}
#left {
float: left;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
margin-left: -10px;
}
#right {
float: right;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
margin-right: -10px;
}
.menu:hover {
background-color: gray;
border-color: brown;
color: red;
}
<div class="menu" id="left">Left</div>
<div class="menu" id="right">Right</div>
I made a
JS Fiddle for you.

Clip child to parent element with border-radius

How do I force clip a child to a parent element that has rounded corners.
<div class="item" >
<div class="top">
<h1>Tile</h1>
<h2>Click me</h2>
</div>
<div class="behind">
<h3>Details</h3>
</div>
</div>
When animating the child, its ignores the border-radius of the parent element. Is there a way to fix the two corners on the top?
.item{
text-align: center;
cursor: pointer;
overflow: hidden;
height: 280px;
width: 280px;
float: left;
border-radius: 5px;
background: white;
margin: 10px;
position: absolute;
}
.top{
z-index: 1;
position: absolute;
height: 280px;
width: 280px;
background: #ed844b;
transition: 0.3s;
border-radius: 5px;
}
.behind{
z-index: 0;
position: absolute;
width: 100%;
top: 136px;
height: 138px;
padding: 10px 16px;
background: #DDDDDD;
box-sizing: border-box;
border-radius: 5px;
}
.slide-up{
transform: translate3d(0, -136px, 0);
border-radius: 0px;
}
Here is a little demo:
http://codepen.io/Koopa/pen/xbaMez
Thanks
Koopa
When you add a css 3d transform to the child, you kinda move it to the separate GPU layer. You can move parent element to GPU layer instead adding null-transform hack transform: translateZ(0) to .item. Or you can replace translate with translateY (In this case child is clipped only when not being animated).

How to make an element inherit of parent element value

I am trying to figure out the correct way to make a div class inherit the parent div height so that when I do for example, padding-top: 100% , it puts the element at 100% of the parent div.
Here's my code:
CSS
#globalContainer{
margin: 0px auto;
width: 100%;
height: 100%;
}
#header-out{
width: 100%;
background-color: black;
}
#header{
width: 940px; /* Set to % when possible */
height: 240px; /* Set to % when possible */
margin: 0px auto;
background-color: white;
}
#header .title{
position: relative;
float: left;
padding-top: 100%;
}
HTML:
<body>
<div id="globalContainer">
<div id="header-out">
<div id="header">
<div class="title">Test</div>
</div>
</div>
</div>
</body>
At the moment, my Test appears at the very bottom of the page inside of the bottom of my header...
Thanks !
EDIT: I am now trying to add a logo next to my title, I used this code:
#header .title{
position: relative;
float: left;
top: 50%;
left: 2.5%;
width: 250px;
height: 100px;
border-style: solid;
border-width: 1px;
}
#header .logo{
position: relative;
float: left;
top: 50%;
width: 250px;
height: 100px;
border-style: solid;
border-width: 1px;
}
Problem is, it overlaps my title, starting where my title would end if I did not use the left: 2.5%
I tried to remove the float: left, it doesn't change anything...
Anyone can help on this ?

Resources