Sunday, April 6, 2014

HTML Positioning: The Curious Case of Centering the Unknown

It would seem like something as simple as centering an object perfectly, both horizontally and vertically, inside a container should be a basic capability of HTML/CSS. However, I've found that the less you know about your surroundings, the more difficult it gets to accomplish that goal. When you're trying to build something that is fluid and adapts to the available browser size, it becomes challenging to pull off such a simple feat. The best solution I've found that works in the most browsers is using a ghost pseudo-element to allow an element to vertically align inside its parent:

.parent-ghost {
  text-align: center;
  border: 3px solid #555;
  height: 300px;
  width: 70%;
}

.parent-ghost:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

.child-ghost {
  display: inline-block;
  vertical-align: middle;
  width: 20%;
  height: 20%;
  background-color: #f00;
}




Of course, this does not work in IE7 or older which means you either need to fallback to using tables or decide if the current market usage is actually worth the effort (As of February 2014, IE7 shows 0.0%).

Now, if you're willing to ignore 7% of the browser market, you can make things really simple by using the Flexbox Layout module. Although pretty recent, all modern browsers do support it. However, your IE users are going to have to use IE11 to take advantage of it:

.parent-flex {
  display: flex;
  height: 300px;
  width: 70%;
  border: 3px solid #555;
}

.child-flex {
  width: 20%;
  height: 20%;
  margin: auto;
  background-color: #f00;
}





That's a very simple example of how using Flexbox makes laying out content easier. If you haven't tinkered with it, take a look at the CSS-Tricks guide for an introduction. However, once you start using it, you may never want to go back to the old way. I've have a basic understanding of what features Flexbox offers. Since its been only recently implemented, it hasn't been a priority for me to start using it for all my layout problems. For now, I'll appreciate that the time will come when it will be in common use but will rely on the old bag-of-tricks to layout pages for a bit longer.

Now, my favorite trick to centering objects is to use a CSS3 Transform to translate the object back 50% of its height and width (for simplicity, I've left out the vendor prefix variations):

.parent-translate {
  overflow: hidden;
  height: 300px;
  width: 70%;
  border: 3px solid #555;
  position: relative;
}

.child-translate {
  position: absolute;
  width: 20%;
  height: 20%;
  background-color: #f00;

  top: 50%;
  left: 50%;

  transform: translateX(-50%) translateY(-50%);
  /* Split because IE10 won't honor the percentage in translate(-50%, -50%) */
}





This method is not supported in IE8, so according to the market stats, you'll lose 2.7% of your audience (well, they'll simply see a box with its top/left corner centered in the parent). However, the reason I tend to use this method is because I generally attach a transition on the element to animate it into position. Since its already absolutely positioned, I can animate the top property to slide it into view:

.slide {
  top: -50%;

  transition: top 1s;
}

.slide.in {
  top: 50%;
}


Attach a little JS to trigger the action:

   $( '#slide-in' ).click( function() { $( '.slide' ).addClass( 'in' ); } );
   $( '#slide-out' ).click( function() { $( '.slide' ).removeClass( 'in' ); } );




Now the transition won't work in IE9 so we've lost another 2% of our users. Again, its not a complete failure - the box still toggles into view - it just doesn't slide up or down.

Lately, I've come to the conclusion that the current features available in HTML5/CSS3 greatly ease the effort required to create great content and user experiences. I have a hard time justifying not leveraging these technologies because a small segment of the Internet is stuck in the past. I realize this is not usually the individual user's fault (corporate policy, etc). In the end, you have to pick what is suitable for your audience. I just prefer to attempt to nudge everyone forward or at least be ready for the eventual switch. Its nice to see that the browser is evolving to a better place that enables developers to spend less time positioning content and more time building it.