Your friends at Viget present Inspire, a Design & Interaction Blog

Skewed Hit Boxes with CSS Transforms

One of the neatest things about CSS Transforms is that they change the hit area of an element to whatever transformed value we set. So, if we rotate an element, the hit area for that element doesn’t stay a box in the defined X and Y plane; it changes to the transformed shape.

CSS Transformed Hit Box

See the Pen rhAje by Tommy Marshall (@tommymarshall) on CodePen.

With that in mind, when I was handed a design comp with a skewed design element and links with angled edges within it, I realized for great justice it was achievable by skewing an element and applying overflow: hidden to the container.

The markup for this demo is really simple:

<div class="container">
    <div class="inner">
        <ul>
            <li>
                <a href="#">Something Awesome</a>
            </li>
            <li>
                <a href="#">Something Awesome</a>
            </li>
            <li>
                <a href="#">Something Awesome</a>
            </li>
        </ul>
    </div>
</div>

Based on that markup, we first transform the .container element and skew it 18 degrees on the X-axis, then undo that skew on the .inner container so our links display properly instead of at an angle (Using SASS).

.container {
  background: #555;
  margin-left: 100px;
  padding: 100px 0;
  position: relative;
  width: 400px;

  /* the important stuff */
  overflow: hidden;
  @include transform(skewX(-18deg));
  
  .inner {
    /* revert the transform */
    @include transform(skewX(18deg));
  }
​}

If you looked at the above example in a Codepen you’ll notice the edges of the skewed element are a bit choppy. You can use the translateZ trick to fix that rendering issue, but that blurs the child elements of the container as well. Instead, I found adding a simple box-shadow to the container works totally fine.

.container {
  box-shadow: 0 0 1px #000
  ...
}

Next, to fix the alignment of the nested links, I add a bit of left positioning to each <li> using the :nth-child selector. 

ul {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  
  li {
    position: relative;
      
    @for $i from 1 through 3 {
      &:nth-child(#{$i}) {
        left: 18px + ($i * -18);
      }
    }

    a {
      background: #5579c2;
      color: #fff;
      display: block;
      padding: 1em 5em;
      text-decoration: none;
      text-transform: uppercase;
      
      &:hover {
        background: darken(#5579c2, 20%);
      }
    }
  }
}

The bonus of using CSS Transforms and :nth-child is that in browsers without support the fallback looks exactly as you'd expect: an unskewed element without the extra left spacing for each of the links.

You'll notice even with the width: 100% on our links, it doesn't span the full width of the .container. To get around this you can just apply a bit extra to the <ul>, since our .container element is set to overflow: hidden.

ul {
  width: 120%;
}

Final Result

See the Pen Jxcbu by Tommy Marshall (@tommymarshall) on CodePen.

When you hover over the links you’ll see that the hit areas are exactly as we’d expect them to be (not going beyond the bounds of the container) and thanks to CSS Transforms and overflow: hidden.

Found this helpful or have another application of skewing elements change an elements hit area? Let me know below!


On-ramping to a Product Team

Onboarding to a product team can be tough. The existing team is too busy for hand holding, and multi-featured applications can leave you overwhelmed by a “where do I start?” feeling. You not only need to learn how everything works, but you need to understand the rationale behind key design and development decisions that will inform your work going forward. It can be a daunting task.

I know this journey well. Four years ago, I started my UX career at Harvest, a company which makes a time-tracking application known by the same name. Onboarding to a product with a robust feature set and a considerable user base was a formidable task, especially for a UX newbie. However, this experience was an entirely positive one, and it set me up for success when I started at Viget in July 2013. Thanks to my existing product experience, I was able to smoothly transition onto the Vitae team, which was preparing to launch the information and career hub for higher-ed professionals, and quickly become a contributing team member.

Through my experience with both Vitae and Harvest, I’ve learned that having a focused on-ramping process can make all the difference. Whether you’re working at a product company or an agency that builds products, the key to gaining a basic understanding of any app comes down to answering a few standard questions and having an agenda for your exploration.


Dissecting a Design: Viget SpotsYou

We recently built SpotsYou, a tool those of us at Viget can use to get rewarded for hitting the gym. Go read Kevin’s breakdown of what it is and why it exists. Okay, back? Cool. Even though Viget SpotsYou was created as an internal app, we were really excited about it and wanted to make it as cool, attractive, and fun to use as possible. I wanted to share a bit about how the design came together.


Frosted Glass Effect with Blur Filters and Masks

Combining a blur effect and a mask to achieve a frosted glass effect is fairly straightforward in Photoshop.

Frosted glass edge effect used on SAIS

However, achieving this frosted glass effect on the front-end using using a single image file is a slightly different story. To produce this effect, we could use a CSS blur filter + CSS mask, but browser support at this time is poor. Using canvas could also work, but that would involve some JavaScript. Yet another option is good old SVG! It supports masks and filters, browser support is fairly good, plus it’s native HTML. That’s the solution I ended up turning to on a recent project.


Make a Flippin’ 3D Countdown with CSS & JavaScript

In January, we worked with Dick’s Sporting Goods to launch Gear in Action, an interactive lookbook featuring new products for the 2014 Baseball season. During the video presentation, users have the opportunity to click on products in the video, view more details (example), and see purchasing options.

Since this opportunity only occurs during the slow-motion part of the video, we wanted to make sure users understood that the video would be moving on if they didn't choose a product quickly enough. So, we added a countdown timer to the top right of the screen, which finishes when the slow-motion segment ends.

Codepen Example

I was pretty happy with the final effect, which uses only a little CSS and some JS class juggling.