Scale arrow made of 2 spans with margin and rotation - html

I have an arrow that I want to scale with screen size, But I don't understand why negative margin doesn't scale properly for different screens is it because of the rotation? http://jsfiddle.net/1yab70ns/:
Edit: I realized it is because of the space from the inline-block and I fixed it wiht float, but why doesn't it also scale with screen?
.pointer span {
width: 1.7vh;
height: 4.5vh;
background: #41291B;
border-radius: 5vh;
display: inline-block;
position: relative;
}
.pointer span:nth-child(1) {
transform: rotate(45deg);
}
.pointer span:nth-child(2) {
transform: rotate(-45deg);
margin-left: -0.3vh;
}
<div class="pointer" id="pointer">
<span></span>
<span></span>
</div>

By using transform: rotate without specifying the point around which rotation will take place, the system defaults to rotating about the mid point of each element. That, coupled with the natural distance between two block elements can cause a problem.
If we make the rotation about the mid point of the top of each element and just enough down so that when they turn they overlap at the top and start them off overlapping each other exactly you get a more aligned result. We don't need to compensate by using margin left, we absolutely know that they are rotating about the same point.
.pointer{
position:absolute;
top: 50%;
left:50%;
}
.pointer span {
margin: 0;
padding: 0;
width: 1.7vh;
height: 4.5vh;
background: #41291B;
border-radius: 5vh;
display: inline-block;
position: absolute;
transform-origin: 0.85vh 0.85vh;
}
.pointer span:nth-child(1) {
transform: rotate(
45deg
);
}
.pointer span:nth-child(2) {
transform: rotate(
-45deg
);
}
<div class="pointer" id="pointer">
<span></span>
<span></span>
</div>

Related

CSS transform: scale makes bottom fixed elements disappear

I'm trying to scale the elements in my body tag so that my website looks the same on differing screen sizes. However, when I apply transform: scale(), the fixed elements associated with bottom disappear. Why is this and how can I fix it?
css
body
{
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
-webkit-transform: scale(1, 1);
}
#invite
{
position: fixed;
bottom: 20px;
right: 31px;
text-align: center;
cursor: pointer;
}
The invite element disappears when I scale with 1.
It will be more helpful if you could include your code and I think you should use media query if you are trying to make your page responsive.
transform:scale(0.5) will create a new binding box for the position:fixed; element, (when that element is a child of the transformed item)
relevant Stackoverflow question
and further explanations in the chromium bug tracker
Example 'buggy' behaviour:
div {
margin: 20px;
padding: 20px;
}
.body {
background: olive;
min-height:600px
}
.main {
background: pink;
}
.bottom {
background: orange;
position: fixed;
bottom: 0;
}
.body:hover {
transform: scale(1)
}
<div class='body'>
<div class="main">
main content</div>
<div class="bottom"> bottom content </div>;
</div>
As for alternatives: responsive design; the general philosophy is to re-arrange elements into a single vertical stack as the viewport gets smaller.

Why positioning absolute element in the center of it's parent relative element while setting top and left to 50% does not work? [duplicate]

When working with hero images or full screen anything, I typically see text or images with the following bit of CSS:
.item {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
What is this code actually doing?
The reason why transform: translate(-50%, -50%) is required is because you want the center of the element to line up with the center of its parent. In simple terms, it can be boiled down to translateX(-50%) translateY(-50%), which means:
move me leftwards by 50% of my width, along the x-axis, and
move me upwards by 50% of my height, along the y-axis
This effectively moves the center of the element to its original top left corner. Remember then when you set left: 50%; top 50% on the element, you are moving its top left corner to the center of its parent (which means it is not visually centered at all). By moving the element back leftwards and upwards by half of its width and height respectively, you are sure that its center now aligns with the parent's center, making it visually horizontally + vertically centered.
As a proof of concept, see the code snippet below: hover over the parent to cause the child element's "ghost" to reposition itself by means of transform: translate(-50%, -50%):
body {
margin: 0;
padding: p;
}
.parent {
background-color: #ccc;
width: 100vw;
height: 100vh;
position: relative;
}
.child {
background-color: rgba(0,0,255,0.5);
width: 50px;
height: 50px;
position: absolute;
top: 50%;
left: 50%;
}
.child::before {
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
content: '';
transition: all .5s ease-in-out;
}
body:hover .child::before {
transform: translate(-50%, -50%);
}
<div class="parent">
<div class="child"></div>
</div>
TL;DR version
Let's say there is a .container and an .item inside.
This code below is positioning .item relatively to .container; meaning .item top left corner is in the center of its container
.item {
top: 50%;
left: 50%;
}
While the below is positioning .item relatively to its own width and height; meaning minus 50% of its width and height.
.item {
transform: translate(-50%, -50%);
}
If the two code snippets below are combined, then the expected center will show up.

What is the best way to avoid font-size scaling when transforming its container?

I am using css transform: scale to animate the entering of a modal. The problem is that the text scale with the <div> that contains it.
How can I avoid?
I want to use scale because it is the suggested way for obtaining smoother animations.
Without your code, it is hard to give you a working answer.
Basically, you cannot exclude a child element from its parent element being scaled. You can accomplish what you want by separating the two elements.
There is more information here.
What you can do is transform both the container and text.
The container is scaled up, while the text is scaled down - so it appears to stay the same.
Here is a very basic example:
button:focus + div {
transform: scale(2);
}
button:focus + div p {
transform: scale(.5);
}
div {
width: 200px;
margin: 0 auto;
text-align: center;
background: black;
color: white;
}
<button>Click to scale box</button>
<div>
<p>Do not scale this text</p>
</div>
#MalloreeEady answer, I just enhanced the answer from the post. Text that are related from the parent container usually get affected by any transformation. To able to avoid that, you may need to create another tag inside or use the pseudo-elements.
h2 {
color: #ffffff;
}
.box {
position: relative;
width: 50%;
height: 50%;
padding: 10px;
text-align: center;
margin: 50px auto;
}
.box::before {
content: '';
position: absolute;
top: 0; left: 0;
display: block;
background: #000;
width: 100%;
height: 100%;
z-index: -1;
}
.box:hover::before {
-webkit-transform: scale(1.3);
-ms-transform: scale(1.3);
transform: scale(1.3);
}
<div class="box">
<h2>TEST TEXT</h2>
</div>

CSS make cube with skew and rotate

I am trying to make cube with 3 square divs and CSS.
The problem appears with the top side: I can't find a way to give it a proper shape.
Of course, it should be an easy way to do it with matrix or other stuff, but if there's a way to solve this problem using only skew and rotate, please provide it.
Thanks in advance.
html:
<div id='box' class='top'></div>
<div id='box' class='left'></div>
<div id='box' class='right'></div>
CSS:
#box {
width: 50px;
height: 50px;
}
.top {
background: #bbf;
margin: 40px 0 0 24px;
transform: rotate(-30deg) skewX(30deg); /* ??! */
}
.left {
background: #fbb;
transform: rotate(30deg) skewX(30deg);
display: inline-block;
margin: -11px 0 0 0;
}
.right {
background: #bfb;
transform: rotate(60deg) skewY(30deg);
display: inline-block;
margin: -11px 0 0 -11px;
}
EDIT: thanks to #rby, I reordered the layers a bit
See at jsfiddle
Here's one way to do it using only skew and rotate as you specified, but with a few additional modifications. First, and most important, arrange the order of your divs so that the div for the top box is first, followed by the two sides. The way you have it now, the top div (class third) is last. Then, the other modifications I did was to use a block display for the top div and add a left margin to it so that it is pushed in towards the side divs and reduce the top margin on the side divs from 50px to 10px. With these changes and your existing rotate, skewX transforms, you get a cube.
Here's the modified code - not to disrupt your code too much I simply created a new id called boxTop for the top box but it'd be best to restructure the rules.
The divs:
<div id='boxTop' class='third'></div>
<div id='box' class='first'></div>
<div id='box' class='second'></div>
The CSS:
#box {
width: 100px;
height: 100px;
margin-top: 10px;
display: inline-block;
}
#boxTop {
width: 100px;
height: 100px;
display: block;
}
.third {
background: #bbf;
margin-left: 50px;
transform: rotate(-30deg) skewX(30deg); /* ??! */
}
Hope this solves your problem.

Trying to understand the relationship between these CSS transforms

I have the following CSS transforms and I am trying to understand the relationship between them so I can figure out how to compensate for one of them.
Here is my code:
.background {
height: 720px;
position: absolute;
width: 1280px;
background-color: rgb(205, 163, 163);
}
.text {
transform: matrix(0, 1, -1, 0, 700, 206.66071428571);
width: 306px;
position: absolute;
height: 120px;
font-size: 120px;
color: rgb(255, 0, 0);
}
.top-left {
transform-origin: top left;
}
.center-center {
transform-origin: center center 0px;
}
<div>
<div class="background"></div>
<div class="top-left text">
<p>TEXT</p>
</div>
<div class="center-center text">
<p>TEXT</p>
</div>
</div>
transforms-origin: center center;
and
transform-origin: top left;
Are the CSS properties in question.
You will see two pieces of text, both with the same properties, except for their transform-origin.
I am trying to understand why the text with the "center center" origin is being placed where it is. I would assume the central point of its "bounding box" would be at the same spot of the top left corner of the bounding box of the other piece of text?
I am looking to figure out the relationship between the two so I can potentially shift the text with the "center center" origin to be in place of the other text.
To make it easier to understand, I have changed your matrix for an aproximate composite transform. You have a translate and a rotate 90 deg. And I have reduced the translate amount so that it fits more easily in the snippet. But the math remains unchanged.
Now notice that the center of transforms (wait for the animation to take place) are not where you might expect, the divs are not in the same place than the ps. I have added a border to the div so that it is easier to see.
About the translation involved, you are rotating around the center of the div. or around the top left corner. The distance between those points is half the width of the div, and half the height:
153px 60px
Now, when you rotate that 90deg, the equivalent translation is the sum and the rest of those values:
213px 93px
Hover on the snippet to see those values applied, and the 2 ps aligned
.background {
height: 99%;
position: absolute;
width: 100%;
background-color: rgb(205, 163, 163);
}
.text {
transform: translate(300px, 100px) rotate(90deg);
width: 306px;
position: absolute;
height: 120px;
font-size: 120px;
color: rgb(255, 0, 0);
border: solid 1px black;
animation: show 4s infinite;
}
.top-left {
transform-origin: top left;
}
.center-center {
transform-origin: center center 0px;
}
#keyframes show {
0% { transform: translate(300px, 100px) rotate(90deg);}
5% { transform: translate(300px, 100px) rotate(90deg);}
100% { transform: translate(300px, 100px) rotate(0deg);}
}
body:hover .text {
animation: none;
}
body:hover .center-center p {
transform: translate(93px, 213px);
}
p {transition: 1s; }
<div>
<div class="background"></div>
<div class="top-left text">
<p>TEXT</p>
</div>
<div class="center-center text">
<p>TEXT</p>
</div>
</div>
To understand that in the general case. Changing the transform origin is equivalent, in a mathematical sense, to do a translate (from one origin to the other), apply the transform, and do the inverse of the translate.
This translate, since you are moving from center center to top left, is half the width, half the height.
when you apply to this value the matrix, the uniform terms are negligible, and you end with x2 = x1 * a00 + y1 * a01 and y2 = x1 * a10 + y1 * a11.
The final movement is that last calculus minus the first translate. Just check that my original answer is the special case for the matrix provided in your question
The transform-origin property allows you to change the position of transformed elements.
2D transformations can change the x- and y-axis of an element. 3D transformations can also change the z-axis of an element.
to better understnad. Here is the live demo from W3schools.com :http://www.w3schools.com/cssref/trycss3_transform-origin_inuse.htm
Example CSS with browser prefixes.
CSS
div {
-ms-transform: rotate(45deg); /* IE 9 */
-ms-transform-origin: 20% 40%; /* IE 9 */
-webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
-webkit-transform-origin: 20% 40%; /* Chrome, Safari, Opera */
transform: rotate(45deg);
transform-origin: 20% 40%;
}