How to simulate a layout transform in CSS?

Viewed 93

Below is a code snippet. I wouldn't mind using JS if the solution requires it.

TL;DR

How to translate something so that the layout around it is affected?

The story

I remember that a few years ago I used in WPF the LayoutTransform and RenderTransform properties on UI elements.

The RenderTransform changed the element without applying the change to the layout so other elements are not affected by this specific transform. Just like the CSS transform property.

The LayoutTransform did what RenderTransform did but also changed the client bounding rectangle so, let's say we have a flexbox with direction set as column. Rotating its second element can change the height of the flexbox, as opposed to RenderTransform.

I think it is a very helpful behaviour and in a few years I think it would be great to have some CSS property like: layout-transform, applied eventually before the (render transform) transform.

An example of why I would like to have this very much

I have a hero image with a cropped and differently styled version on top of it both used for an animation. When the user scrolls, the cropped version goes over the upper side of the hero image, by an animation of margin-top with negative margins. The effect is like having a mountain in a landscape, when the user scrolls the mountain goes above part of the sky and below the mountain is the color of the mountain with contents over it.

Below the hero image there is the page content and to move the content just below the cropped image I use position: relative on the content (<main>) and use a CSS animation to move it up by the same amount with the top property with a negative value.

But if I want to add a footer to the page, it will appear too low on the page with a spacing between main and footer. So I will use the same trick with position: relative or translate transform again.

This is OK for a small number of elements (although I am not sure that the page scrolling is not affected). But if I have a dynamic number of elements, this solution is, IMHO, dirty. For example, in React I would have to keep some state for this at the root element and pass some information to descendants in a not-so-Reactish-way.

I read this but it did not help me: CSS transform doesn't change CSS layout.

.grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
}

.cropped {
  position: relative;
  grid-row: 1/2;
  grid-column: 1/2;
  min-height: 10vh;
  max-height: 1rem;
  align-self: end;
  background-color: yellow;
  animation: anim-1 1s ease-in-out 1s 1 normal both;
}

.original {
  grid-row: 1/2;
  grid-column: 1/2;
  min-height: 75vh;
  background-color: green;
}

main {
  animation: anim-2 1s ease-in-out 1s 1 normal both;
  position: relative;
  background: #253a57;
  padding: 3rem;
  color: white;
  text-align: justify;
}

@keyframes anim-1 {
  0% {
    top: 0;
  }
  100% {
    top: -50vh;
  }
}

@keyframes anim-2 {
  0% {
    top: 0;
  }
  100% {
    top: -50vh;
  }
}
<div class="grid">
  <div class="original"></div>
  <div class="cropped"></div>
</div>

<main>
  <h1>Lorem Ipsum</h1>
  <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Mollitia corporis nesciunt officiis ad dolor! Ipsam commodi, sunt cupiditate voluptatum a debitis dicta sint minima qui. Explicabo ducimus quaerat unde cum!</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maxime dolorum suscipit voluptas. Dignissimos repellat eius rerum, debitis repudiandae quis quod corrupti maiores voluptatibus at, laudantium similique quidem numquam dolores modi!</p>
</main>

<footer>
  Lorem Ipsum Dolor Sit Amet
</footer>

0 Answers
Related