translate() vs top/left for positioning - css

From what I find, translate() seems to offer smoother animations over plain top/left but my question is related to a CSS layout I saw recently. The author used the following setting to position a block of text inside the main header image:
.hero-text-box {
position: absolute;
width: 1140px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
He didn't explain, and I'm left wondering what advantage translate() has over top/left in percentage values when it comes to pure layouts (i.e., no animation). I'm guessing this really doesn't matter in the case of layouts, and was the result of the author's habits. But even then, this combines both top/left and translate(). What's going on?

The code you posted is used to position an element vertically and horizontally centered. translate is used here because the percentage are relative to the element dimensions. The percentage values for top and left with position: absolute are relative to the dimensions of the first parent element with position set to relative, absolute or fixed.

Related

Position: fixed and transform: translateZ

Sometimes my sidebar with position: fixed scrolls with page. It happens only in Chrome. I think something wrong happening with viewport (I also have lazy loading implemented, maybe it impacts on viewport). I decided to apply transform: translateZ(0) to the sidebar element. Issue seems to be gone but I can not understand how transform impacts on elements with fixed position?
I have read a lot of information about how it works before asking this question but I can't understand how it solves the problem, maybe there's a need to fix elements which cause viewport overflow? Thanks a lot and sorry for my English.
position: fixed will always position the element relative to the initial window viewport, except when one of the element's ancestors has a transform property, in which case that ancestor behaves like the new viewport:
.container {
transform: translateZ(0); // the "new" viewport
.child {
position: fixed;
top: 1rem; // 1rem relatively to .container
}
}
So when you gave the container a transform property, it acted as the relative container to the fixed child and sorted your issue.
Check out Mozilla's CSS/position docs - they explain the subject well.

How does this CSS code to center an element work?

position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
This is CSS code for centering a button in the viewport. Can somebody explain how this works? I found it somewhere online and it seems to work but I don't get the need for margin-right and transform. Naturally the code doesn't work without them but intuitively I feel the first three should be enough to center the element. I'm relatively new to CSS so I'd understand if this is considered a silly question :)
Take a look at this article: https://css-tricks.com/quick-css-trick-how-to-center-an-object-exactly-in-the-center/. Simply using the first three lines of css (position, top, and left) will center the top left corner of the object, which will make the whole object completely off-center. The negative translation moves the object up and to the right by half of its height and width, respectively, which makes the object centered. In fact, I don't think you even need the margin-right code, but I might be wrong.

Why do not defining width on absolute positioned child get unusual behaviour?

Basically, I have 3 absolutely positioned elements within a relative container, one of them with left: 100% (the one coming next) and one with left: -100% (the previous picture). They transition between the available places automatically with the transition property. The final result of this can be seen here.
<div id="slideshow">
<article>
<img>
</article><article>
<img>
</article><article>
<img>
</article>
</div>
<style>
div#slideshow { position: relative; overflow: hidden }
img { width: 100%; height: auto }
article { width: 100%; position: absolute; transition: left 1s }
article.current { left: 0 }
article.prev { left: -100% }
article.next { left: 100% }
</style>
(This is the result without overflow: hidden applied, to see how the slideshow works.)
As you can see, the <img>s are responsive to their parent, <article>. I know that block elements always take the available width, so I didn't think I had to state it, but as you can see, I had to specify width: 100% on the <article>, too. What happens if I don't? Something interesting, I'd say.
The .prev <img> turns twice as big as the others, and the .next <img> renders at size 0x0. What? You clearly see that all the image should have the same dimensions: 100% width, and auto height.
What I wanted to understand is; why does the CSS work like it does? I find this result quite unexpected, so I really wanted some kind of a discussion on why the result returns what it does, so that I could better understand how the underlying components of the CSS values actually work.
Your problem is not in the images themselves, but on the article.
It's the article elements that are ruling the dimensions, and image gets the dimensions from them.
The width of the article is not set. Lacking that, and in the presence of a left statement, a value of right 0px is assumed. So, when left is 0, the width is 100% of the container, when the left is -100% the width is 200%, and when the left is 100%, the width is 0.
How to solve this ?
Add a width: 100% to article. - the direct solution.
Instead of moving the articles with the left property, do it with a transform: translateX(-100%); You won't have the problem derived from changing left, and it is more performant

Creating triangles

I'm creating a wordpress theme and both sides of the content should have diagonally border. I can solve this with pictures but this is the ugly way and the content has not the same length on every page.
In this case i think two triangles on the right and left side is the correct solution. I tried it with this tutorial, but the problem is that I have to use fixed width for the borders and the triangle should have the height of the content, dynamically adjusted.
How can I solve this, that I come up with two triangles (marked red in the sketch).
You can achieve this (albeit somewhat imprecisely) with the CSS skew transform:
Demo: http://jsfiddle.net/cUWm2/2/
<div class="shape">
A variable amount of content.
</div>
.shape {
position: relative;
}
.shape:before {
content:"";
-moz-transform: skewX(10deg);
-webkit-transform: skewX(10deg);
transform: skewX(10deg);
width: 140%;
left: -20%;
height: 100%;
background-color: #555;
position: absolute;
top: 0;
z-index: -1;
}
This achieves the requested shape with minimal markup and decent (IE9+ and all other modern) browser support. However, when scaling height up or down, eventually the triangles cease to be triangles and a fourth edge becomes visible. You have several options:
Find dimensions that work for a practical amount of content and code to that.
Dynamically alter the skew amount using JavaScript.
Blend the background of the edge shapes with the main shape.
Ignore it (depending on the layout, it doesn't necessarily look bad).
All that said (after playing with various CSS options) I'd probably consider an image-centric solution first. You can use the :before and :after pseudo-elements to create containers which resize vertically along with your main content while staying the same width. You can then use a background image to cover the desired area, or put a 100% x 100% image into the container.
I also agree with using SVGs. I find them easier to manipulate since they're scalable and cross compatible between browsers as they're images. Here's an answer I posted to a similar question, which should get you started: Make CSS3 triangle with linear gradient
From there, it will be easy to set the image heights to match the content's. Here's a jQuery example:
$(document).ready(function() {
$(".triangle").height($(".content").height());
});
I would solve this by the use of SVGs (Scaleable Vector Graphics). You create the two triangle-SVGs and then make a 3 column layout where all columns are equally heigh (for example by using display: table-cell). You chose the left triangle as background-image for the left column and the right triangle as bg-image for the right one. The middle one is for your content.
Dont forget to use preserveAspectRatio(https://developer.mozilla.org/de/docs/SVG/Attribute/preserveAspectRatio) in your SVG.

CSS relative + right (or bottom) almost NEVER work

I've been writing CSS for quite some time now.
I've noticed that
<div style="position: relative; right: 20%; bottom: 20%;">some text</div>
never works!
relative positioning would work with left and top specified but not with right/bottom. Why?
A quick fix around this is to use "absolute" instead and specify right/bottom in pixels, but I need a reason.
Also, correct me if I'm wrong. Irrespective of whether the external container is positioned absolutely or relatively, does it not make much sense to position something "relative" to the boundaries of that container or should elements inside a container always be positioned "absolute"?
Thank you.
From Absolute vs. Relative - Explaining CSS Positioning
Relative positioning uses the same four positioning properties as absolute positioning. But instead of basing the position of the element upon the browser view port, it starts from where the element would be if it were still in the normal flow.
Relative positioning does work with bottom/right values, just not the way you were expecting:
http://cssdesk.com/RX24j
Think about the position values on relative elements as margins, that the surrounding elements simply ignore. The "margins" will always move the element relative to it's previous position in the normal document flow, but remove it from the normal flow at the same time.
When out of the normal document flow, the surrounding elements act as if it were in it's original position in the normal flow... but it's not. This is why a relative element can overlap it's parent (like in Rel 1).
Did you try this?
<div style="position: relative; right: -20%; bottom: -20%;">some text</div>
or rather
<div style="position: relative; right: -80%; bottom: -80%;">some text</div>
not recommended :
left : 0% //will set it to left
left : 100% //will set it to right => you need to get the width of the element and subtract it using calc ( 100% - width)
To people visiting this old post...
if the element that you are trying to position inside something else has a width or height that is larger than the outer element. The position will ignore left, right, bottom, left.
give it width/height auto.
that was the problem that I had. Hope it helps you too!
remove position left, right, top, bottom from the parents element
and put it in the child as you want
.parent_class
{
background: #ff0000 ;
position: absolute;
transition: 0.8s ease-out;
left:0; //" remove this from here"
top:0; // " remove this from here"
z-index: -1;
}
.child_class
{
width: 0px;
height: 70px;
right: 0; //"now it will work"
bottom: 0;//"now it will work"
}

Resources