← Article précédent Article suivant →
Publié le 07 septembre 2015
Concept Design

Un bouton se transformant en modal window. Un formulaire d'envoi de message comme contenu, avec des animations CSS3 type Material Design.

Tutoriel HTML5 / CSS3 / jQuery - Message Material Design

Avant de débuter


Cette série de tutoriels intitulée "Concept Design" a pour but de convertir en code les concepts de design que nous pouvons voir sur la toile. En effet, de plus en plus nous voyons des concepts de design voir le jour, s'en suit alors des réalisations originales de designers. J'ai alors eu l'idée de réaliser le développement de ces créations et de vous les partager sous forme de tutoriels.
N'hésitez pas à me partager des liens de concept design qui pourraient faire l'objet d'un nouveau tutoriel dans cette série.

A l'origine de ce design


Qu'est-ce que c'est ?


Aujourd'hui nous allons voir comment un bouton peut grandir en modal window. Ici nous utiliserons unformulaire de contact en guise de contenu, mais vous pouvez imaginer bien des choses ! Ce bouton peut par exemple être un bouton flottant intégré dans votre site, dans le coin de vos pages et fixé, bref, nous pouvons imaginer pleins de choses. Ce qui nous intéresse ce sont les animations et non la fonctionnalité d'envoi de message.

Une histoire de code


Ici nous utiliserons la librairie jQuery de façon à aller plus vite dans le développement, des animations CSS3 et bien évidemment HTML pour la structure.
Je travaille dans un fichier "index.html" pour la structure et un fichier "style.css" pour le style. Je ne mets que le code permettant de faire les animations et un peu plus. Vous pouvez télécharger le code en entier à l'aide du bouton "Code source" ci-dessus afin d'avoir la totalité. Mais essayez de bien comprendre avant de le télécharger. :) Allez hop, on passe au code, c'est parti !

La structure HTML


On structure notre page via HTML de façon à adopter une certaine hiérarchie pour notre réalisation.
<!-- Conteneur principal -->
<div id="container">

    <!-- Bouton déclencheur -->
    <div class="button">

        <!-- Contenu du bouton, ici notre modal window -->
        <div class="button-modal">

            <!-- En-tête de la modal -->
            <div class="button-modal-header">
                <input type="text" placeholder="To" autocomplete="off"
                       class="button-modal-input button-modal-input-to left" />
                <div class="button-modal-header-close right"></div>
                <div class="clear"></div>
            </div>

            <!-- Corps de la modal -->
            <div class="button-modal-body">
                <input type="text" placeholder="Subject" autocomplete="off"
                       class="button-modal-input button-modal-input-subject" />
                <textarea placeholder="Say Something" autocomplete="off"
                          class="button-modal-input"></textarea>
                <div class="button-modal-send button-disabled">Send</div>
            </div>
            
        </div>

    </div>

</div>

JavaScript


Le JavaScript sert ici à ajouter et retirer les classes suite à des actions faites par l'utilisateur afin de donner le relais à notre CSS. Nous allons également l'utiliser pour vérifier que les champs destinataire et sujet soient remplis pour envoyer le message. N'oubliez pas de faire cette vérification aussi côté serveur.
Une fois notre bouton cliqué, nous ajoutons la classe ".button-clicked" à notre conteneur (qui est notre parent) pour que nous puissons impacter sur le style des différents éléments.
N'oubliez pas que nous travaillons à l'intérieur de notre bouton, donc les clics que nous faisons dans la modal sont des clics sur notre bouton déclencheur. C'est pourquoi nous utilisons "e.stopPropagation()" afin d'arrêter toute action relative à notre parent. Je vous laisse faire le test de retirer "e.stopPropagation()" pour que vous compreniez pourquoi. ;)
$(document).ready(function() {

    // Déclaration de nos variables "globales"
    var $container = $("#container");
        $button = $(".button"),
        $buttonSend = $(".button-modal-send"),
        $modalClose = $(".button-modal-header-close"),
        $inputTo = $(".button-modal-input-to"),
        $inputSubject = $(".button-modal-input-subject"),

        inputToValue = "",
        inputSubjectValue = "",

        // Déclaration de nos fonctions

        // Fermer la modal
        closeModal = function() {
            $container.removeAttr("class");

            disable();

            cleanFields();
        },
        // Vérifier que le destinataire et le sujet sont remplis
        checkFull = function() {
            if (inputToValue.length > 0 && inputSubjectValue.length > 0)
                $buttonSend.removeClass("button-disabled");
            else
                disable();
        },
        // Désactiver le bouton envoyer
        disable = function() {
            if (!$buttonSend.hasClass("button-disabled"))
                $buttonSend.addClass("button-disabled");
        },
        // Nettoyer les champs
        cleanFields = function() {
            inputToValue = "";
            inputSubjectValue = "";

            $(".button-modal-input").val("");
        }
        // Enclencher l'animation du message envoyé
        sendMessage = function() {
            $button.addClass("button-success");

            // Attendre la fin de l'animation pour revenir au bouton initial
            $button.one("webkitAnimationEnd mozAnimationEnd oAnimationEnd
                         oanimationend animationend", function() {
                $(this).removeClass("button-success");
            });

            closeModal();
        };

    // Une fois le bouton cliqué
    $button.click(function(e) {
        e.preventDefault();

        $container.addClass("button-clicked");
    });

    // Ecouter les touches sur le champs destinataire
    $inputTo.keyup(function() {
        inputToValue = $(this).val();
        checkFull();
    });

    // Ecouter les touches sur le champs sujet
    $inputSubject.keyup(function() {
        inputSubjectValue = $(this).val();
        checkFull();
    });

    // Lorsque l'on clic sur le bouton envoyer
    $buttonSend.click(function(e) {
        e.preventDefault();
        e.stopPropagation();

        // Vérifier que le bouton envoyer est bien activé
        if (!$(this).hasClass("button-disabled"))
            sendMessage();
    });

    // Quand on clic sur notre "croix" pour fermer
    $modalClose.click(function(e) {
        e.preventDefault();
        e.stopPropagation();

        closeModal();
    });
});

Le style


On passe au CSS pour donner vie à nos animations.
Je vous rappelle que nous nous intéressons ici seulement aux animations et quelques "plus" et non au style des éléments. Vous pouvez télécharger le code source plus haut.

Oh, mais c'est qu'il bouge notre bouton déclencheur


Une fois le bouton cliqué, nous donnons une rotation à notre conteneur parent de -90 degrés pour dessiner une trajectoire sous forme d'arc de cercle. Pour jouer sur la hauteur, ajustez votre "width", oui oui n'oubliez pas qu'on vient de tourner sur -90 degrés.
#container {
    position: absolute;
    text-align: right;
    width: 500px;
    bottom: 50px;
    right: 50px;
    -webkit-transition: transform .5s;
    transition: transform .5s;
}
.button-clicked#container {
    -webkit-transform: rotate(-90deg);
    transform: rotate(-90deg);
}

Hein quoi ?! Notre bouton évolue en modal window !


Toujours une fois le bouton cliqué, nous lui donnons la forme d'un rectangle et il devient "réel" conteneur, ici sous forme de modal window comprenant des champs.
#container.button-clicked .button {
    cursor: default;
    background-image: none;
    -webkit-transform: rotate(90deg);
    transform: rotate(90deg);
    -webkit-animation: toForm 1s both;
    animation: toForm 1s both;
}
@-webkit-keyframes toForm {
    100% {
        width: 500px;
        height: 300px;
        border-radius: 4px;
    }
}
@keyframes toForm {
    100% {
        width: 500px;
        height: 300px;
        border-radius: 4px;
    }
}

Formulaire, apparaît !


Maintenant que notre bouton déclencheur a évolué ( :D ) en modal window, alors nous pouvons nous occuper du contenu de celle-ci.
Par défaut, le contenu du bouton n'est pas affiché, il faut bien le cacher quand il est encore à l'état de bouton. Mais quand il grandit en modal window, alors nous lui donnons le droit d'afficher son contenu.
Pour ce faire, nous écrivons une animation "fadeIn" qui s'enclenchera 0.55 secondes après le clic, de façon à laisser notre bouton mûrir correctement.
.button-modal {
    text-align: left;
    display: none;
}
#container.button-clicked .button-modal {
    display: block;
    -webkit-animation: fadeIn 1s .55s both;
    animation: fadeIn 1s .55s both;

}
@-webkit-keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
@keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

Style du bouton d'envoi


Le bouton d'envoi comprend deux états : activé et désactivé. Via JavaScript, nous modifions son état en fonction de nos champs destinataire et sujet.
.button-modal-send {
    border-radius: 4px;
    display: inline-block;
    cursor: pointer;
    color: #FFF;
    padding: 7px 14px;
    font-weight: bold;
    font-size: 22px;
    text-transform: uppercase;
    background-color: #2AC6BF;
    -webkit-transition: all .3s;
    transition: all .3s;
}
.button-modal-send:active {
    background-color: #99EAE6;
}
.button-modal-send.button-disabled {
    cursor: default;
    color: #A9A9A9;
    background-color: transparent;
}

Animation de succès


Dernière étape du processus, allez allez !
Une fois le bouton d'envoi activé et cliqué, alors la classe ".button-success" est ajoutée à notre bouton déclencheur via JavaScript. Nous utilisons ici une courbe de bezier afin de contrôler notre animation, nous voulons qu'elle soit lente sur la toute fin.
Nous modifions l'icône ainsi que la couleur de fond de notre bouton déclencheur, puis nous le rapassons à son état d'origine. N'oubliez pas notre JavaScript, une fois l'animation de succès terminée, alors nous retirons la classe ".button-success" de notre bouton.
.button-success {
    cursor: default;
    background: url(../images/icon-success.png) no-repeat #2AC6BF center center;
    -webkit-animation: newRotate 3s cubic-bezier(0, 0, 0, 1);
    animation: newRotate 3s cubic-bezier(0, 0, 0, 1);
}
@-webkit-keyframes newRotate {
    80% {
        background: url(../images/icon-success.png) no-repeat #2AC6BF center center;
        -webkit-transform: rotate(360deg);
    }
    100% {
        background: url(../images/icon-pen.png) no-repeat #FFF center center;
    }
}
@keyframes newRotate {
    80% {
        background: url(../images/icon-success.png) no-repeat #2AC6BF center center;
        transform: rotate(360deg);
    }
    100% {
        background: url(../images/icon-pen.png) no-repeat #FFF center center;
    }
}

Partagez


En espèrant que ce tutoriel vous ait plu ! En attendant les prochains, n'hésitez pas à le partager en cliquant sur les boutons ci-dessous.

Contact


Si vous rencontrez des difficultés ou des erreurs en rapport avec ce tutoriel, contactez-moi via mon adresse email ou Twitter.

Faites-moi parvenir des créations de ce type, on verra ce que l'on pourra faire. :)