Progress Button Styles

A set of flat and 3D progress button styles where the button itself serves as a progress indicator. 3D styles are used for showing the progress indication on one side of the button while rotating the button in perspective.

From our sponsor: Looking for an intuitive whiteboard style project management tool? Give Shortcut a try for free.

Today we’d like to share some progress button styles with you. You surely know “Ladda” by Hakim El Hattab, a UI concept that indicates progress directly on the button that invokes a loading action. Some of the buttons have a built-in progress bar and today we’d like to explore that idea with some creative progress button styles. Using perspective will allow us to create some fun 3D effects besides the flat “filling” styles. For a complete solution, please take a better look at Ladda.

Please note that we’ll be using transitions on pseudo-elements which are still not supported in some browsers (e.g. Safari and Mobile Safari).

Also note that we need transform-style: preserve-3d support for the 3D styles, which neither IE10 nor IE11 support.

With the script that we’ve created for showing the button styles, we take a simple button markup

<button class="progress-button" data-style="rotate-angle-bottom" data-perspective data-horizontal>Submit</button>

and transform it into the following structure:

<button class="progress-button" data-style="rotate-angle-bottom" data-perspective data-horizontal>
	<span class="progress-wrap">
		<span class="content">Submit</span>
		<span class="progress">
			<span class="progress-inner"></span>

If we don’t set the data-perspective attribute, then we’ll make this structure:

<button class="progress-button" data-style="fill" data-horizontal>
	<span class="content">Submit</span>
	<span class="progress">
		<span class="progress-inner"></span>

We also indicate if we have a style that needs horizontal or vertical progress bar filling. This will be used in our CSS to specify the regarding styles.
The following styles are the general and common styles for all buttons (note that perspective styles are only needed for the buttons with 3D transforms):

*, *:after, *::before { box-sizing: border-box; }

@font-face {
	font-weight: normal;
	font-style: normal;
	font-family: 'icomoon';
	src:url('../fonts/icomoon/icomoon.eot?#iefix') format('embedded-opentype'),
		url('../fonts/icomoon/icomoon.ttf') format('truetype'),
		url('../fonts/icomoon/icomoon.woff') format('woff'),
		url('../fonts/icomoon/icomoon.svg#icomoon') format('svg');

.progress-button {
	position: relative;
	display: inline-block;
	padding: 0 60px;
	outline: none;
	border: none;
	background: #1d9650;
	color: #fff;
	text-transform: uppercase;
	letter-spacing: 1px;
	font-size: 1em;
	line-height: 4;

.progress-button[disabled].state-loading {
	cursor: default;

.progress-button .content {
	position: relative;
	display: block;

.progress-button .content::before,
.progress-button .content::after  {
	position: absolute;
	right: 20px;
	color: #0e7138;
	font-family: "icomoon";
	opacity: 0;
	transition: opacity 0.3s 0.3s;

.progress-button .content::before {
	content: "e600"; /* Checkmark for success */

.progress-button .content::after {
	content: "e601"; /* Cross for error */

.progress-button.state-success .content::before,
.progress-button.state-error .content::after {
	opacity: 1;

.notransition {
	transition: none !important;

.progress-button .progress {
	background: #148544;

.progress-button .progress-inner {
	position: absolute;
	left: 0;
	background: #0e7138;

.progress-button[data-horizontal] .progress-inner {
	top: 0;
	width: 0;
	height: 100%;
	transition: width 0.3s, opacity 0.3s;

.progress-button[data-vertical] .progress-inner {
	bottom: 0;
	width: 100%;
	height: 0;
	transition: height 0.3s, opacity 0.3s;

/* Necessary styles for buttons with 3D transforms */

.progress-button[data-perspective] {
	position: relative;
	display: inline-block;
	padding: 0;
	background: transparent;
	perspective: 900px;

.progress-button[data-perspective] .content {
	padding: 0 60px;
	background: #1d9650;

.progress-button[data-perspective] .progress-wrap {
	display: block;
	transition: transform 0.2s;
	transform-style: preserve-3d;

.progress-button[data-perspective] .content,
.progress-button[data-perspective] .progress {
	outline: 1px solid rgba(0,0,0,0); /* Smoothen jagged edges in FF */

We are using the pseudo-elements ::before and ::after for the success or error icons which we fade in once loading is finished. The span with the class progress is used as the main wrapper for the progress bar itself which is the span with class progress-inner. Sometimes we use the progress span with a background color, while other times we will just style the child span. We’ll also provide some general styles for the vertical and horizontal case.

Note that for the 3D examples, we’ll use the button as a “shell” that will serve to add the perspective value. The content span will contain the button styles like the background color and the padding, and everything will be wrapped into a span with the class progress-wrap which will be the element that we transform.

An example of an individual button style is the following:

/* Rotate bottom 3d */
/* ====================== */

.progress-button[data-style="rotate-angle-bottom"] .progress {
	position: absolute;
	top: 100%;
	left: 0;
	width: 100%;
	height: 20px;
	box-shadow: 0 -1px 0 #148544; /* fix the blurriness that causes a gap */
	transform: rotateX(-90deg);
	transform-origin: 50% 0%;

.progress-button[data-style="rotate-angle-bottom"].state-loading .progress-wrap {
	transform: rotateX(45deg);

The button will have one of the three states (or none): state-loading, state-success and state-error.

For browsers that don’t support necessary properties, we’ll provide the default fallback of the first style (fill horizontal).

Icons are by IcoMoon and the icon font was created with the IcoMoon app.

We hope that you find these button styles inspiring and useful!

Tagged with:

Mary Lou

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 52

Comments are closed.
  1. Olá, sou novo aqui no site e já estou gostando de mais.
    Tô com uma dúvida: Como é que eu faço redirecionar para outra página após o término do progresso?
    Quero que quando eu clicar no botão, o progresso acabe e eu seja redirecionado.

    Atenciosamente, Vitor.

  2. Hello, I’m new here on the site and I’m enjoying it more.
    ‘m With a doubt: How do I redirect to another page after the progress?
    I want that when I Vclick the button, the progress finish and I will be redirected.
    Regards, Vitor.

  3. Good day, I want to ask how can I use this in form as a submit? I’ve tried to remake it but it didn’t work. Thank you

  4. CHALLENGE,Is there any way to use this these perfect buttons as an upload button where the progress bar does show the condition of the uploading file(how far the uploading goes)

  5. Hi there,

    Has anyone been able to include form validation? It doesn’t seem to work, as it’s a button tag rather than an input submit. Other than that, it works beautifully. 🙂

  6. Has anyone had any luck getting this plugin to work with Contact Form 7?

    When I set it up, the button animates, but the form no longer submits.