Éléments d'interface utilisateur personnalisés

Ci-dessous, vous trouverez quelques discussions sur les moyens de personnaliser certains éléments HTML. Beaucoup des éléments que vous devez concevoir pour votre application partagent les propriétés décrites ci-dessous. Gardez à l'esprit que ce ne sont là que des exemples.

Au lieu d'utiliser le code expliqué ci-dessous tel qu'il est, s'il vous plaît, concevez vos propres widgets ou contrôles personnalisés. Il m'est difficile de vous donner des points pour ma propre conception et mon propre code.

Boutons

Un bouton est une chose que l'utilisateur peut cliquer ou toucher pour valider une commande, ou naviguer sur une application, ou pour activer une option, ou même pour sélectionner un outil. Il y a plusieurs façons de créer des boutons en HTML.

HTML fournit des balises pour les boutons. Vous pouvez facilement utiliser la balise <button>. Cela fera un bouton qui ressemble à ceci : . Il a des propriétés par défaut, et il aura un aspect différent sur différents navigateurs. J'ai créé les boutons cliquables sous forme de boutons dans l'application d'échantillons que je vous ai données.

Ce type de bouton est naturel, mais parfois il est un peu difficile de styler comme vous le souhaitez. Une alternative est d'utiliser une simple balise (c'est appelée ancre), et de la faire ressembler à un bouton en utilisant css.

Bouton de l'balise

Remarquez comment cela réagit à la souris. Cliquez également dessus pour le plaisir... Trois états, montrés dans un seul widget : stand, hover, clic. Le CSS est le suivant. (Cela utilise un id de zbttn qui serait appliqué sur l'balise d'ancrage.)

#bttn {
  display: inline-block;
  padding: 0.3em;
  background: #339;
  color: white;
  text-decoration: none;
  border-radius: 5px;
  transition: all 0.5s;
}
#bttn:hover {
  background: #393;
  box-shadow: 5px 5px 8px black;
}
#bttn:active {
  transition: none;
  box-shadow: 2px 2px 2px black;
}

Vous pouvez voir que la conception d'un bouton est super facile.

Si nous voulions faire un état désactivé pour ce bouton, nous pourrions le faire comme ça. Le code CSS suit.

Bouton de l'balise

#bttn.disabled {
  display: inline-block;
  padding: 0.3em;
  background: white;
  color: #ccc;
  text-decoration: none;
  border-radius: 5px;
  border: solid 3px #ccc;
  pointer-events: none;
}

Dans le code de l'exemple, j'ai ajouté une classe .disabled à l'élément #bttn'bttn' nous a utilisé auparavant. Vous pouvez utiliser n'importe quelle manière que vous vouliez appliquer cet état. Maintenant, pour le code, je suis sûr que vous pouvez voir à quel point les couleurs sont différentes ici. Nous n'avons pas non plus besoin d'autres règles pour d'autres États parce qu'il s'agit d'un état inactif. Cet état devrait être appliqué sur le bouton par JavaScript dans le cas où le bouton n'est pas utilisé.

Le seul élément qui est différent est le dernier bien: les événements de pointage: aucun;. Ceci éteint tout événement lié à cet élément. Vous ne voyez donc pas l'icône de la souris pointeuse, et quand vous cliquez sur rien d'eux. Avec cela, le bouton est vraiment désactivé.

Champs d'entrée

Ici, nous allons jouer avec un champ d'entrée de texte simple ancien. Il y en a aussi plusieurs dans l'application. Pour commencer, une entrée de texte ressemble à ceci.

<form action="#" autocomplete="off" id="textInput">
  <fieldset>
    <input id="first" type="text" name="first" required>
    <label for="first">First Name</label>
  </fieldset>
</form>
    

Notez que j'ai inclus une balise et une balise Celles-ci ne sont pas absolument nécessaires pour montrer simplement l'apport. Mais si elle devait être utilisée, l'entrée devrait être à l'intérieur d'une forme. Vous le savez déjà. Et nous utiliserons le fieldet pour certaines transitions fantaisistes plus tard. Restez à l'écoute.

Le code ci-dessus, par défaut, ressemble à ceci.

Maintenant nous pouvons personnaliser cette chose. Commençons par de simples changements. L'balise n'est qu'un conteneur de texte. Vous pouvez lui appliquer n'importe quelle propriété qui affecte la typographie: police-famille, taille, couleur, etc. La zone de texte elle-même, l'entrée, est comme un élément de bloc, elle a: bordure, arrière-plan, ombre-boîte, etc. Notez que l'balise se trouve après la saisie. C'est à cause de la façon dont nous l'utiliserons. Vous pourriez le faire autrement.

Donc, faisons bleu l'balise (ma couleur de texte par défaut sur cette page est grise). Et nous allons le placer juste en dessous du champ plutôt que sur sa droite. Aussi, mettons la frontière du champ donc n'est qu'une ligne au fond du champ au lieu d'une boîte. Plus comme un formulaire imprimé. Enfin, éliminons la frontière autour du champ. Vous aurez besoin de placer ce code CSS à l'intérieur d'une balise de style pour l'essayer.

Il est à noter que je n'ai pas modifié la largeur de l'entrée. Il est un peu trop petit pour un champ de texte réel. Dans votre application, vous devriez tenir compte de la taille des champs. Mais cela n'a pas d'importance pour notre discussion.

#textInput fieldset {
  border: none;
}
#textInput label {
  color: #339;
  display: block;
}
#first {
  outline: none;
  border: none;
  border-bottom: solid #339 2px;
}
    

Avec le code ci-dessus appliqué, il ressemble à ça.

Maintenant, essayez de cliquer sur le champ pour taper dedans. Vous voyez comment la couleur, la bordure, etc. changent ? Cela se fait avec une transition entre les États dans les CSS. Le code ressemble à ça. (Je viens de mettre les deux règles pour le champ d'entrée. Ceci remplace les deux règles par le même sélecteur du bloc de code précédent. Ne pas faire double emploi avec les règles.)

#first {
  outline: none;
  border: none;
  border-bottom: solid #339 2px;
  transition: all 0.5s;
}
#first:focus { /*this is the focus state*/
  border-bottom: solid green 2px;
  background: lightgreen;
}

Laissez faire quelque chose de plus fantaisiste. Nous mettrons l'balise «à l'intérieur» du champ, il ressemble donc à un espace réservé. Et quand vous donnez la mise au point au champ, l'balise passe au sommet et vous permet d'écrire ce que vous voulez.

Cela semble compliqué, mais ce n'est pas si mal. Le CSS est un peu plus élaboré. Le voici. Je vais l'expliquer ci-après. Encore une fois, les règles ici qui ont des sélecteurs qui existent déjà ne devraient pas être dupliquées. Ils devraient remplacer ce que vous avez déjà. Vous devez ajouter les nouvelles règles.

#textInput fieldset {
  border: none;
  position: relative;
}
#textInput label {
  position: absolute;
  top: 1em;
  color: #339;
  display: block;
  transform-origin: left;
  transition: all 0.5s ease;
}
#first {
  outline: none;
  border: none;
  border-bottom: solid #339 2px;
  margin-top: 1em;
  transition: all 0.5s;
}
#first:focus, #first:valid {
  border-bottom: solid green 2px;
  background: lightgreen;
}
#first:focus ~ label, #first:valid ~ label {
  top: 0px;
  transform: scale(0.8, 0.8);
  color: green;
}

La première chose étrange que vous remarquerez ici est que nous fixons la position: relative; pour le fieldet. Il s’agit de nous permettre de préciser ensuite la position absolue de l’balise afin que nous puissions animer la position de l’balise.

Ensuite, nous avons positionné: obsolue; pour l'balise, comme je viens de mentionner. Ensuite, nous le positionnons de sorte qu'il apparaît à l'intérieur du champ: le haut est la propriété qui positionne un élément par le haut. Nous avons également défini l'origin de transformation qui détermine de quel côté elle va s'étendre (nous y arriverons). Et bien sûr, nous devons fixer une propriété de transition pour qu'elle anime la transition entre les États.

L'apport «, tout d'abord, c'est la première fois qu'elle était en cours d'élaboration. L'état d'avancement de l'apport reste également le même. Mais vous remarquerez que j'ai ajouté un deuxième sélecteur: premier:valide à la règle. Ceci détermine les propriétés de l'entrée lorsqu'elle a une valeur. Nous ne voulons pas que l'balise revienne dans le champ après que l'utilisateur a entré sa valeur.

La dernière règle est nouvelle. Et c'est probablement un sélecteur que vous n'avez jamais utilisé. Le connecteur de y sélectionne les frères et sœurs: éléments qui ont le même parent. C'est pourquoi nous avons besoin de l'balise d'balise après l'entrée dans le langage HTML, de sorte que nous pouvons la sélectionner en utilisant ce type de sélecteur. Donc, la première:focus et l'balise signifie: obtenir l'élément d'balise (sélecteur de marque) qui est un frère ou un autre#first, quand celui-ci a le:focus (lorsque le point d'insertion du clavier est dans celui-ci). Qu'advient-il de l'balise lorsque l'entrée se concentre ? Il se déplace vers le haut:0px; (plus à l'intérieur du champ, mais au-dessus). Nous l'éteinons également de sorte qu'il semble plus petit. Et nous le rendons vert, comme la couleur du champ sur l'accent.

Interut sur les couleurs

Je veux que vous remarquiez comment les couleurs dans les exemples que je vous donne sont similaires. Remarquez comment les états de stand utilisent tous 339 bleus. Remarquez comment les États actifs utilisent le vert au 393. Et la plupart des gris sont 'cccc. Ce n'est pas une chose chanceuse, ce n'est pas aléatoire. C'est une décision, c'est la conception. Cela fait que les champs de texte et les boutons font partie de la même famille visuelle, ils utilisent le même langage visuel.

J'aurais pu utiliser d'autres caractéristiques pour souligner davantage ce langage visuel: l'épaisseur du trait, la forme de la boîte, le style de la ligne, les tailles relatives, etc. Cela fait partie de votre mandat de concevoir chaque élément de l'interface comme des membres d'un système. J'ai utilisé la couleur pour ça ici.

Parlons donc de couleur. Comment déterminez-vous combien de couleurs votre besoin d'un projet? Quel est le but de la couleur? Je ne parle pas de la couleur à choisir, je parle de l'utilisation des couleurs dans un produit. La couleur que vous utilisez dépend de différentes choses : l'humeur, le public, le marquage, etc. Mais le nombre de couleurs et la façon dont vous utilisez la couleur est déterminée par certains besoins très spécifiques du produit.

Nous utilisons des couleurs pour un seul usage dans la conception: pour distinguer, ou si vous voulez, pour créer du contraste.

Vous avez besoin de couleurs différentes pour classer le contenu. Donc le nombre de couleurs que vous utilisez dans un produit est déterminé par le nombre de catégories de choses que vous avez. C'est tout.

Disons que vous voulez concevoir une lettre. Une lettre sera une feuille de papier et certains caractères imprimés ou écrits dessus. 2 choses : 2 couleurs. Typiquement, ceux-ci seront blancs (pour le papier), et noirs (pour l'encre). Mais, si vous avez de la fantaisie, ils pourraient être du beige clair (pour le papier) et bleu foncé (pour l'encre). Mais il reste cependant deux catégories de choses deux couleurs. Contraste. C'est vrai pour tous les produits que vous concevez.

Il y a d'autres façons de créer du contraste (forme, texture, taille, etc.), de sorte que vous n'avez pas nécessairement besoin d'une couleur pour chaque catégorie de choses. Mais toujours utiliser les couleurs avec l'objet.

Donc, pour déterminer les couleurs que vous utiliserez pour ce projet, trouvez les catégories de choses pour lesquelles vous devrez utiliser les couleurs: différents types de boutons, une hiérarchie des balises, des champs de différentes fonctions, etc. Une fois que vous savez comment vous avez l'intention d'utiliser les couleurs, vous pouvez décider des couleurs que vous utiliserez.

Icônes

Une icône fait généralement référence à une petite illustration. Il est souvent utilisé à la place des mots sur les contrôles. Les icônes typiques que vous rencontrez incluent:

(J'ai utilisé une bibliothèque d'icônes gratuite appelée Friconix pour fournir ces exemples. Si vous voulez, vous pouvez commencer avec une icône d'une bibliothèque, mais vous devez ajouter de l'animation et d'autres propriétés, alors faites attention à ce que vous utilisez. Croyez-moi, c'est mieux si vous le dessinez vous-même. De plus, je ne demande que 2 si...)

Des icônes plus élaborées sont également utilisées pour identifier les applications: les «Ps bleus dans un carré» de Photoshop (l'icône était beaucoup plus détaillée avant, consultez-la), la balle colorée de Chrome, etc. Les émojis sont aussi des icônes. Les icônes sont partout.

Icône SVG animée de base

Il s'agit d'un exemple d'icône dessinée dans SVG. S'il était utilisé dans une application, il serait probablement plus petit, mais je veux dire clairement cette présentation (hint). Cette icône a trois états : stand, hover, et clic. Si vous mettez votre souris dessus, vous aurez une surprise. Et si vous cliquez dessus, vous verrez quelque chose d'autre se produire. Voyons comment cela se fait.

C'est le code SVG pour cette icône. Vous pouvez aussi regarder la source de cette page... Vous n'avez pas à vous soucier des détails, mais remarquez les identifiants des deux groupes (tag )): "smoke et 'house. Nous les utiliserons dans le code plus tard.

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
   viewBox="0 0 200 200" xml:space="preserve">
<g id="smoke">
  <path class="st0" d="M129.5,66.5c0,0-4-9,1-22s3-26.6,0-29.3c-2.2-2,11.2,8.2,13.5,28.1c0.8,6.7,0.2,14.4-2.5,23.2H129.5z"/>
</g>
<g id="house">
  <polygon class="st1" points="146.5,104.7 146.5,66.5 124.5,66.5 124.5,86.8 99.5,66.5 24.5,127.5 49.8,127.5 49.4,180 87,180 
    87,143.5 112,143.5 112,180 148.7,180 149.1,127.5 174.5,127.5"/>
</g>
</svg>

Très bien, regardons les États. Vous avez probablement compris maintenant que les états sont souvent définis dans le CSS, en utilisant des pseudo-classes comme :hover et:active. Pour cette icône, nous allons utiliser JavaScript (JS) ainsi que pour définir les états. En fait, j'ai conçu cette icône en utilisant une bibliothèque d'animation autre que GSAP que nous avons utilisée dans l'affectation précédente. Les transitions sont animées dans CSS, mais le scintillement de fumée utilise Anime.js. (Pour en savoir plus sur ce qui suit.) Je l'ai fait juste pour vous montrer comment utiliser une autre bibliothèque. Quelque chose à laquelle vous devez vous habituer. Bien sûr, vous pouvez utiliser GSAP dans vos icônes. Ou vous ne pouvez pas non plus utiliser de bibliothèque du tout et simplement animer les transitions en utilisant CSS. C'est votre travail.

État autonome

L'état de la position n'est que le dessin tel quel. Mais nous devons cacher la fumée. Donc le CSS ressemble à ça. Remarquez que l'opacité du chemin de fumée est 0 (zéro). La maison et la fumée ont une transition, de sorte que lorsque les propriétés changent, le CSS animera la transition.

Notez également que les sélecteurs appliquent ces propriétés à l'objet à l'intérieur du groupe plutôt qu'au groupe. Dans ce cas ici, nous voulons manipuler le remplissage et d'autres propriétés du chemin et du polygone. Les éléments du groupe n'ont pas de telles propriétés. Nous devons donc manipuler les objets vectoriels, pas les groupes.

#house polygon {
  fill:#FFF;
  stroke:#000;
  stroke-width:5; 
  transition: all 0.2s; 
}
#smoke path {
  fill:#CCC;
  stroke:#000;
  stroke-width:0;
  opacity: 0;
  transition: opacity 0.5s;
}

Click State

Je vais d'abord parler de l'état de clic parce que c'est moins compliqué et plus familier. La seule chose est que le déclencheur de l'événement est géré par JS au lieu de CSS.

Donc ce qui se passe, c'est que nous changeons la valeur de la propriété de remplissage du polygone de maison de blanc à vert. Le code JS ressemble à ça. (Ce code devrait être à l'intérieur d'une balise bas de votre fichier HTML pour fonctionner".)

document.querySelector("#svgIcon").addEventListener("mousedown",function() {
	document.querySelector("#house polygon").style.fill = "#393";
});
document.querySelector("#svgIcon").addEventListener("mouseup",function() {
	document.querySelector("#house polygon").style.fill = "#FFF";
});

Vous remarquez tout de suite que je n'utilise pas l'événement de clic. Pourquoi pas ? Le fait est que je veux mettre la couleur de remplissage au vert uniquement quand la souris est en panne, quand l'utilisateur est en couleur. Et puis, je veux que la couleur soit de retour au blanc quand la souris est soulevée. J'ai donc besoin de gérer l'événement de souris en bas (pour rendre le remplissage vert) puis l'événement de la souris vers le haut (pour le rendre à nouveau blanc). Si vous voulez quelque chose comme un bouton, vous pouvez utiliser l'événement clic. Une fois l'icône cliquée, elle restera telle quelle. (N'oubliez pas le mandat)

Donc la première ligne sélectionne l'élément 'svgicIcon', et y se fixe un événementListener pour l'événement mousedown. Lorsque cet événement est déclenché, nous sélectionnons l'élément polygonal de la maison, et nous régnons sa propriété de remplissage à 393 dollars (vert).

L'autre auditeur est similaire, mais il rend le remplissage blanc sur l'événement mouseup.

État de survol

Maintenant, gérons le cas lorsque la souris se déplace sur l'icône, l'animation de fumée apparaît. Il y a deux choses qui se passent ici : une transition (la fumée apparaît) et une animation (la fumée se déplace). La transition est réalisée en modifiant l'opacité du chemin de fumée. L'animation, comme mentionné ci-dessus, est faite à l'aide de la bibliothèque Anime.js. Donc le déclencheur de l'événement de changement d'état est géré par JS.

Le code ressemble à ça. Remarquez les deux parties distinctes.

//Animation
let smokeAnim = anime.timeline({ autoplay: false, loop: true, duration: 8000, easing: "easeInOutQuint" });
smokeAnim.add({
	targets: "#smoke path",
	d: [
		{ value: 'M142.8,63.5c0,0,4-9-1-22s-3-26.6,0-29.3c2.2-2-11.2,8.2-13.5,28.1c-0.8,6.7-0.2,14.4,2.5,23.2H142.8z'},
		{ value: 'M129.5,70.5c0,0-4-9,1-22s3-26.6,0-29.3c-2.2-2,11.2,8.2,13.5,28.1c0.8,6.7,0.2,14.4-2.5,23.2H129.5z'},
		{ value: 'M142.8,64c0,0,4-9-1-22s-3-26.6,0-29.3c2.2-2-11.2,8.2-13.5,28.1c-0.8,6.7-0.2,14.4,2.5,23.2H142.8z'},
		{ value: 'M129.5,66.5c0,0-4-9,1-22s3-26.6,0-29.3c-2.2-2,11.2,8.2,13.5,28.1c0.8,6.7,0.2,14.4-2.5,23.2H129.5z'},
	]
});

//Transition
document.querySelector("#svgIcon").addEventListener("mouseenter",function() {
	document.querySelector("#smoke path").style.opacity = "1";
	smokeAnim.play();
});
document.querySelector("#svgIcon").addEventListener("mouseleave",function() {
	document.querySelector("#smoke path").style.opacity = "0";
	smokeAnim.pause();
});

La première partie est l'animation. Je n'entrerai pas trop dans les détails sur Anime.js dans ce tutoriel. Il suffit de noter que la référence de la variable à l'animation est appelée fuméeAnim.

Comme je l'ai dit plus haut, vous n'avez pas besoin d'utiliser une bibliothèque pour cette mission. Et si vous voulez, vous pouvez utiliser la bibliothèque GSAP que vous connaissez déjà un peu. Je laisse le code de l'Anime là-bas si vous êtes curieux et que vous aimeriez l'essayer. Imporant : Ne vous aventurez pas dans ce domaine si vous avez des difficultés avec le code. Une caractéristique importante pour devenir concepteur/créateur est de connaître vos limites. J'inclus ici pour les plus avancés et les plus curieux parmi vous. Il est tout à fait acceptable d'ignorer cette partie.

Alors concentrez-vous sur la deuxième partie : la transition. Là encore, nous avons deux événements : le casse-souris et la souris. Ceux-ci sont déclenchés respectivement lorsque la souris entre dans le voisinage de l'élément, et lorsqu'il s'éloigne de lui. Il est possible que vous connaissiez déjà ces deux événements, ils sont assez courants.

Sur la souris entramez l'élément 'svgic'con, nous sélectionnons le chemin de la fumée et régnons son opacité à 1. Cela le rend visible. Puis nous jouons l'animation de smokeAnim. Cette fonction play() vient de la bibliothèque Anime.js.

Sur le côté de souris maintenant, nous renversons cela. Nous avons remis l'opacité du chemin de fumée à 0 (cache-la à nouveau), et nous mettons en pause la fuméeAnim.

Voila !