Category
Visual Design
Software Engineering

Published
Oct 13, 2017

Read
2 min

Tweet
Share
Comment

Diagonal & Slanted Image Grid Web Design UI

Article Purpose

The purpose of this article is to showcase an approach for rendering a diagonal and slanted image grid UI using HTML and CSS.

Diagonal & Slant CSS

The approach leverages just two aspects of CSS applied to a single container HTML element. The two aspects are:

  • transform property
  • skew() transform-function

In addition, three aspects of CSS are needed for the child <img> elements in order to counter the parent transformation. These three aspects are:

  • undo the skew() on the <img> only
  • object-fit: cover the <img> to ensure center fit
  • transform scale() the <img> to fill the negative space side-effect of the skew()
Diagonal Slanted UI without Scale

Before scale() (photos from unsplash.com)

Diagonal Slanted UI with Scale

After scale() (photos from unsplash.com)

As you will notice, there is unfilled space without the scale() being applied. There may be a better way to fill this space so please share on Twitter @derekknox if you have ideas. The next section has the full HTML and CSS implementation.

The Code

Below is the HTML structure that is rendered in the images above.


<div class='container'>
  <div class="skewed">
    <div class='row'>
      <div class='image-wrap'><img src="img1.jpg"></div>
      <div class='image-wrap'><img src="img2.jpg"></div>
      <div class='image-wrap'><img src="img3.jpg"></div>
    </div>
    <div class='row'>
      <div class='image-wrap'><img src="img4.jpg"></div>
      <div class='image-wrap'><img src="img5.jpg"></div>
      <div class='image-wrap'><img src="img6.jpg"></div>
    </div>
  </div>
</div>

And the corresponding CSS (variables-in-CSS via SCSS):


/* Vars */

$width: 50%; /* Container width */
$skew: -12deg; /* Diagonal and slant value in degrees */
$fit-img-scaler: 1.5; /* Increase as $skew increases to fill empty space */
$border-thickness: 8px; /* Optional border */

/* Styles */

.container {
  width: $width;
  margin: 200px auto;
}

.skewed {
  transform: skew(0, $skew);
}

.row {
  display: flex;
  height: 150px;
  margin-top: $border-thickness * 2;
}

.image-wrap {
  width: 33%;
  height: inherit;
  border: $border-thickness solid #eee;
  overflow: hidden;
}

.image-wrap img {
  /* Ensure width/height are set for object-fit to properly apply */
  width: 100%;
  height: 100%;
  object-fit: cover;
  
  /* Undo skew for reversing effect properly */
  transform: skew(0, -$skew) scale($fit-img-scaler, $fit-img-scaler);
}
It is worth noting that if you are using a preprocessor like SCSS, there is likely a custom function you could write to automate the proper scale() value based on the skew() amount.

Gotcha

There is a gotcha if you apply more than one transform-function in a class (say a rotate() in addition to a skew()). In order to properly undo a transformation, you need to apply the counter transformation in the opposite order originally applied. If you do not, then a counter transformation won't fully work as it might otherwise seem.

Put another way, if in the parent you rotate() and then skew(), in the child you need to skew() and then rotate() the opposite amount of degrees.

Keep this in mind if you ever apply more than one transform-function in a class. Feel free to interact with the live sample CodePen link below.

CodePen