Buttons with Icons

The most common case for this kind of pattern is when you need to build buttons for social network sharing.

Defining our needs

As usual, I like to define some goals so that the CSS solution does make sense to you. What I need is:

  • Vertical aligned buttons
  • Buttons with vertical aligned icon and text
  • If I don't have enough space, the overflowing buttons go to a new line.
  • Buttons cover the entire space available by distributing the available space.
  • Keep the HTML code as simple and accessible as possible, as usual :p

The last part is optional.

Let's code this

Our HTML basics

<ul class="social-buttons">
	<li>
		<a href="https://twitter.com/">
			<i class="icon-twitter" role="presentation"></i>
			Twitter
		</a>
	</li>
	<li>
		<a href="https://www.facebook.com/">
			<i class="icon-facebook" role="presentation"></i>
			Facebook
		</a>
	</li>
	<li>
		<a href="https://instagram.com">
			<i class="icon-instagram" role="presentation"></i>
			Instagram
		</a>
	</li>
	<li>
		<a href="http://weibo.com/">
			<i class="icon-weibo" role="presentation"></i>
			Weibo
		</a>
	</li>
	<li>
		<a href="https://www.linkedin.com/">
			<i class="icon-linkedin" role="presentation"></i>
			Linkedin
		</a>
	</li>
</ul>

I used role="presentation" to avoid assistive technology reading the decorative icon. Read more about that thanks to the excellent article by Scott O'Hara "Know your ARIA: 'hidden' VS 'none'".

CSS to flex the things

Ok now we are using Flexbox to make the magic happen.

/**
 * The container and the item are both
 * into flex layout. To align items
 * to each other.
 */
.social-buttons,
.social-buttons li {
	display: flex;
	padding: 0;
	margin: 0;
}

/**
 * Force to occupy the space available
 * and allow item being on several lines
 */
.social-buttons {
	width: 100%;
	list-style: none;
	flex-wrap: wrap;
}

/**
 * Items tend to occupy 25% of
 * the available width but are
 * allow to grow.
 */
.social-buttons li {
	flex-basis: 25%;
	flex-shrink: 0;
	flex-grow: 1;
}

/**
 * The anchor is also in Flex
 * to align icon and text and
 * center their content.
 */
.social-buttons a {
	display: flex;
	justify-content: center;
	align-items: center;
	width: 100%;
	padding: .5em 1em;
	font-weight: 500;
	text-decoration: none;
	color: #FFF;
}

/**
 * Some decorations for the 
 * next lines.
 */
.social-buttons i {
	margin-right: .5em;
}

.social-buttons [href*="twitter.com"] {
	background: #1da1f2;
}

.social-buttons [href*="facebook.com"] {
	background: #3b5998;
}

.social-buttons [href*="instagram.com"] {
	background: #c13584;
}

.social-buttons [href*="weibo.com"] {
	background: #e6162d;
}

.social-buttons [href*="linkedin.com"] {
	background: #0077b5;
}

The magic parts are here the wrap option and the fact that .social-buttons li are allow to grow even if their width is set thanks to flex-basis: 25% which is not a strong constraint

Here is an alternative code with margin:

.social-buttons li {
	margin: 2px;
}

Have fun!