{"id":4161,"date":"2014-10-06T08:45:20","date_gmt":"2014-10-06T06:45:20","guid":{"rendered":"https:\/\/www.creativejuiz.fr\/blog\/?p=4161"},"modified":"2023-10-03T15:54:01","modified_gmt":"2023-10-03T13:54:01","slug":"input-file-personnalise-css-js","status":"publish","type":"post","link":"https:\/\/www.creativejuiz.fr\/blog\/tutoriels\/input-file-personnalise-css-js","title":{"rendered":"Un input:file personnalis\u00e9 en CSS et JS"},"content":{"rendered":"<p>Il y a quelques temps de cela, lorsque je faisais des recherches sur les <a>boutons radios et checkboxes personnalisables en CSS<\/a>, j&rsquo;avais en t\u00eate de faire la m\u00eame chose avec le champ \u00ab\u00a0fichier\u00a0\u00bb (<code>input-file<\/code>). J&rsquo;avais donc fait un <a href=\"http:\/\/creativejuiz.fr\/blog\/doc\/custom-input-file-full-css3-flat-ui.html\">essai en CSS pur<\/a>. Puis j&rsquo;avais laiss\u00e9 l&rsquo;id\u00e9e de c\u00f4t\u00e9.<!--more--><\/p>\n<p>Finalement je suis revenu dessus hier pour compl\u00e9ter l&rsquo;id\u00e9e de base par une information visuelle textuelle. En effet si vous essayez cette version de l&rsquo;<a href=\"http:\/\/creativejuiz.fr\/blog\/doc\/custom-input-file-full-css3-flat-ui.html\">input-file personnalis\u00e9 en CSS<\/a>, vous verrez que rien ne vous indique qu&rsquo;une image est s\u00e9lectionn\u00e9e par vos soins. Ce qui est plut\u00f4t g\u00eanant pour un utilisateur.<\/p>\n<p>J&rsquo;ai alors cherch\u00e9 \u00e0 le faire en JS (vanilla, pas de jQuery), et ce n&rsquo;est pas si complexe que cela.<\/p>\n<p class=\"center\"><a class=\"demonstration\" href=\"http:\/\/creativejuiz.fr\/blog\/doc\/custom-input-file-full-css3-flat-ui-js.html\">D\u00e9monstration<\/a><\/p>\n<h2>Le code HTML<\/h2>\n<p>Pour rendre la chose la plus \u00ab\u00a0naturelle\u00a0\u00bb possible, nous allons nous contenter d&rsquo;un \u00e9l\u00e9ment <code>label<\/code> et d&rsquo;un <code>input:file<\/code>.<br \/>\nLe label sera utilis\u00e9 comme \u00e9l\u00e9ment \u00ab\u00a0sensible\u00a0\u00bb, comme un bouton, pour activer le champ de s\u00e9lection d&rsquo;un fichier.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-markup code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-markup code-embed-code\">&lt;div class=&quot;input-file-container&quot;&gt;<br\/>\t&lt;input class=&quot;input-file&quot; id=&quot;my-file&quot; type=&quot;file&quot;&gt;<br\/>\t&lt;label for=&quot;my-file&quot; class=&quot;input-file-trigger&quot;&gt;<br\/>\t\tSelect a file...<br\/>\t&lt;\/label&gt;<br\/>&lt;\/div&gt;<br\/>&lt;p class=&quot;file-return&quot; aria-live=&quot;polite&quot; aria-atomic=&quot;true&quot;&gt;&lt;\/p&gt;<\/code><\/pre> <div class=\"code-embed-infos\"> <\/div> <\/div>\n<p>Je renseigne ici volontairement plusieurs classes pour manipuler les \u00e9l\u00e9ments en CSS et JS sans d\u00e9pendre des \u00e9l\u00e9ments HTML. Le paragraphe en fin de code permettra d&rsquo;accueillir un peu d&rsquo;informations sur le fichier.<\/p>\n<h2>Quelques styles<\/h2>\n<p>Le conteneur va \u00eatre positionn\u00e9 en <code>relative<\/code> afin de pouvoir placer l&rsquo;input en position absolue.<br \/>\nOn va donc se retrouver avec le label du champ servant de \u00ab\u00a0d\u00e9clencheur\u00a0\u00bb (sensible au clic et touches du clavier) et le champ de recherche de fichiers par dessus mais transparent, servant lui aussi de d\u00e9clencheur.<br \/>\nNous allons faire en sorte de travailler la marge interne (padding) de ce champ afin de le superposer au label, rendant ainsi sensibles le label et le champ invisible sur une surface \u00e0 peu pr\u00e8s identique.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-css code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-css code-embed-code\">\/* styles de base si JS est activ\u00e9 *\/<br\/>.js .input-file-container {<br\/>\tposition: relative;<br\/>\twidth: 225px;<br\/>}<br\/><br\/>.js .input-file-trigger {<br\/>\tdisplay: block;<br\/>\tpadding: 14px 45px;<br\/>\tbackground: #39D2B4;<br\/>\tcolor: #fff;<br\/>\tfont-size: 1em;<br\/>\ttransition: all .4s;<br\/>\tcursor: pointer;<br\/>}<br\/><br\/>.js .input-file {<br\/>\tposition: absolute;<br\/>\ttop: 0;<br\/>\tleft: 0;<br\/>\twidth: 225px;<br\/>\tpadding: 14px 0;<br\/>\topacity: 0;<br\/>\tcursor: pointer;<br\/>}<br\/><br\/>\/* quelques styles d&#039;interactions *\/<br\/>.js .input-file:hover + .input-file-trigger,<br\/>.js .input-file:focus + .input-file-trigger,<br\/>.js .input-file-trigger:hover {<br\/>\tbackground: #34495E;<br\/>\tcolor: #39D2B4;<br\/>}<br\/><br\/>\/* styles du retour visuel *\/<br\/>.file-return {<br\/>\tmargin: 0;<br\/>}<br\/><br\/>.file-return:not(:empty) {<br\/>\tmargin: 1em 0;<br\/>}<br\/><br\/>.js .file-return {<br\/>\tfont-style: italic;<br\/>\tfont-size: .9em;<br\/>\tfont-weight: bold;<br\/>}<br\/><br\/>\/* on compl\u00e8te l&#039;information d&#039;un contenu textuel uniquement lorsque le paragraphe n&#039;est pas vide *\/<br\/>.js .file-return:not(:empty):before {<br\/>\tcontent: &quot;Selected file: &quot;;<br\/>\tfont-style: normal;<br\/>\tfont-weight: normal;<br\/>}<\/code><\/pre> <div class=\"code-embed-infos\"> <\/div> <\/div>\n<p>Pour le reste des choix graphiques (couleurs, typographie, etc) je vous laisse faire, c&rsquo;est secondaire pour ce que je vous propose.<\/p>\n<h2>Retour visuel textuel gr\u00e2ce \u00e0 JavaScript<\/h2>\n<p>Ce code est propos\u00e9 en JS vanilla (c&rsquo;est \u00e0 dire sans Framework JS), il est possible de l&rsquo;adapter \u00e0 votre framework pr\u00e9f\u00e9r\u00e9 si vous en utilisez un dans votre projet.<\/p>\n<div class=\"code-embed-wrapper\"> <pre class=\"language-javascript code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-javascript code-embed-code\">\/\/ ajout de la classe JS \u00e0 HTML<br\/>document.querySelector(&quot;html&quot;).classList.add(&#039;js&#039;);<br\/><br\/>\/\/ initialisation des variables<br\/>const fileInput = document.querySelector( &quot;.input-file&quot; );<br\/>const button = document.querySelector( &quot;.input-file-trigger&quot; );<br\/>const the_return = document.querySelector(&quot;.file-return&quot;);<br\/><br\/>\/\/ action lorsque la &quot;barre d&#039;espace&quot; ou &quot;Entr\u00e9e&quot; est press\u00e9e<br\/>button.addEventListener( &quot;keydown&quot;, function( event ) {<br\/>\tif ( event.keyCode == 13 || event.keyCode == 32 ) {<br\/>\t\tfileInput.focus();<br\/>\t}<br\/>});<br\/><br\/>\/\/ action lorsque le label est cliqu\u00e9<br\/>button.addEventListener( &quot;click&quot;, function( event ) {<br\/>\tfileInput.focus();<br\/>\treturn false;<br\/>});<br\/><br\/>\/\/ affiche un retour visuel d\u00e8s que input:file change<br\/>fileInput.addEventListener( &quot;change&quot;, function( event ) {<br\/>\tthe_return.innerHTML = this.value;<br\/>});<\/code><\/pre> <div class=\"code-embed-infos\"> <\/div> <\/div>\n<p>Les actions sont relativement simples ici, j&rsquo;esp\u00e8re que les commentaires vous suffiront \ud83d\ude42<\/p>\n<p>Le r\u00e9sultat et la pr\u00e9sentation ici sont tr\u00e8s sommaires, il vous appartiendra ensuite de ruser pour ajouter des petits effets visuels : une ic\u00f4ne de fichier joint sur le bouton par exemple, ou une personnalisation du retour textuel suivant la langue, etc.<\/p>\n<p class=\"center\"><a class=\"demonstration\" href=\"http:\/\/creativejuiz.fr\/blog\/doc\/custom-input-file-full-css3-flat-ui-js.html\">D\u00e9monstration<\/a> <a class=\"demonstration\" href=\"http:\/\/codepen.io\/CreativeJuiz\/pen\/HbwcG\">Fork on CodePen.io<\/a><\/p>\n<h2>Quelques articles pour aller plus loin<\/h2>\n<p>Si vous ne le saviez pas, vous pouvez \u00e9galement styler certains \u00e9l\u00e9ments de formulaire comme les boutons radio, les checkbox, ou m\u00eame l&rsquo;\u00e9l\u00e9ment progress en HTML5.<\/p>\n<ul>\n<li><a href=\"https:\/\/www.creativejuiz.fr\/blog\/tutoriels\/personnaliser-aspect-boutons-radio-checkbox-css\">Styler des checkboxes et boutons radio en CSS<\/a><\/li>\n<li><a href=\"https:\/\/www.creativejuiz.fr\/blog\/veille-technologique\/html5-element-progress-avancement-tache\">Styler l&rsquo;\u00e9l\u00e9ment progress en CSS<\/a><\/li>\n<\/ul>\n<p>Bonne lecture !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Il y a quelques temps de cela, lorsque je faisais des recherches sur les boutons radios et checkboxes personnalisables en CSS, j&rsquo;avais en t\u00eate de faire la m\u00eame chose avec le champ \u00ab\u00a0fichier\u00a0\u00bb (input-file). J&rsquo;avais donc fait un essai en CSS pur. Puis j&rsquo;avais laiss\u00e9 l&rsquo;id\u00e9e de c\u00f4t\u00e9.<\/p>\n","protected":false},"author":4,"featured_media":7523,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bluesky_dont_syndicate":"","_bluesky_syndication_accounts":"","_bluesky_syndication_text":"","footnotes":""},"categories":[9,12],"tags":[432,490,125,384],"coauthors":[597],"class_list":["post-4161","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutoriels","category-veille-technologique","tag-formulaire","tag-input","tag-javascript","tag-personnaliser"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/4161","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/comments?post=4161"}],"version-history":[{"count":3,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/4161\/revisions"}],"predecessor-version":[{"id":8525,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/4161\/revisions\/8525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media\/7523"}],"wp:attachment":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media?parent=4161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/categories?post=4161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/tags?post=4161"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/coauthors?post=4161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}