viewport overflow

Vanilla JS : identifier l’élément plus large que le viewport

Aujourd’hui, je régle un petit souci d’affichage sur un une boutique WooCommerce propulsée par Astra.

Le problème est le suivant: lorsqu’on visite le site depuis un mobile, il est possible de faire bouger le contenu de la page vers la gauche, ce qui dévoile une hideuse colonne grise/verte sur le côté droit. Pourtant, aucun élément ne semble dépasser la largeur du contenu.

L’identification de l’élément causant ce défaut d’affichage n’est pas vraiment une chose aisée, car visuellement, on ne distingue rien qui dépasse.

Vanilla JS à la rescousse

Voici un petit script en Vanilla JS qui permet de trouver l’élément qui dépasse la largeur du viewport de votre page:

/**
 * Identify elements that exceed the viewport width
 * by Matt Biscay
 * https://www.skyminds.net/?p=614036
 */
document.addEventListener("DOMContentLoaded", function() {
  const elements = document.querySelectorAll('body *');
  elements.forEach(element => {
    if (element.offsetWidth > document.documentElement.clientWidth) {
      console.log('Element causing overflow: ', element);
    }
  });
});

CSS: couvrez cet overflow que je ne saurais voir

Une fois votre ou vos éléments identifiés, il ne vous reste plus qu’à cacher son overflow-x :

#element {
  overflow-x: hidden;
}

Rafraîchissez la page. Hop, problème résolu.

Speech Bubble Vector

CSS : des notes de bas de page sous forme de popup

Lorsque nous écrivons de longs articles, nous avons souvent besoin d’ajouter des notes de bas de pages – footnotes en anglais – pour donner une référence ou apporter un complément d’informations.

Il existe un moyen d’ajouter une note de bas de page en CSS, avec un effet popup.

Survolez le numéro qui s’affiche ici à pour voir la démo: ¹Voici un example de note de bas de page qui apparaît dans une popup, grâce à CSS :)

Une popup CSS pour vos notes de bas de page

Code HTML

Commençons par le code HTML. Nous avons besoin principalement d’un lien HTML et d’une balise span qui contiendra le contenu de notre footnote :

   <p>Voici un premier paragraphe avec une note de bas de page. <a class="footnote">&sup1<span>Coucou, je suis la note de bas de page numéro 1</span></a>
   </p>

   <p>Voici un deuxième paragraphe avec une note de bas de page. <a class="footnote">&sup1<span>Coucou, je suis la note de bas de page numéro 2 :)</span></a>
   </p>

Code CSS

Et voici notre code CSS pour créer la popup et afficher le contenu de nos notes de bas de page à l’intérieur, au survol de la souris:

a.footnote {
   text-decoration:none;
   background-color: #FEF6BB;
   padding-left: 2px;
   padding-right: 2px;
   margin-right: 2px;
   transition: all 2s ease;
} 

a.footnote span {
   z-index: -1;
   opacity: 0;
   position: fixed;
   left: 15px; 
   bottom: 20px;
   margin-left: 0px;
   margin-right: 18px;
   padding:14px 20px;
   border-radius:4px; box-shadow: 5px 5px 8px #CCC;
   border:1px solid #DCA;
   background-color: #FEF6BB;
   transition: all 2s ease;
}

a.footnote:hover span {
   z-index: 9;
   opacity: 1;
   transition: all 2s ease;
}

Dès que la souris n’est plus au-dessus du numéro de la note de bas de page, cette dernière disparaît avec un effet de fondu.

Résultat

Voilà ce que le code nous donne:

Voici un premier paragraphe avec une note de bas de page. ¹Coucou, je suis la note de bas de page numéro 1

Voici un deuxième paragraphe avec une note de bas de page. ²Hello World, je suis la note de bas de page numéro 2 :)

Matt

Et voilà, c’est très simple, en CSS pur mais c’est efficace et ne prend pas de ressources externes (pas de JS) – cela peut toujours servir!

CSS: superposer du texte lisible sur une image de fond photo

CSS: superposer du texte lisible sur une image de fond

Il est souvent utile de pouvoir placer du texte sur une image de fond, de manière à ce que l’on puisse lire le texte facilement et distinguer l’image. C’est ce que j’utilise sur le blog pour les images d’illustration des articles.

Nous allons donc superposer du texte lisible sur une image de fond en utilisant uniquement du code HTML et CSS, ce qui nous donne ceci:

Voici une planche à voile

Une image de planche à voile se trouve derrière ce texte.

Vous souhaitez accomplir la même chose? Voici comment faire.

Lire la suite

jQuery : sélectionner un élément dont l'ID ou la classe commence ou finit par une chaîne photo 1

jQuery : comment ajouter !important à une propriété CSS

jQuery possède une limitation qui peut s’avérer très gênante : on ne peut ajouter !important à une propriété CSS en utilisant un script jQuery.

Par exemple, ceci ne fonctionnera pas:

jQuery('.foo').css('border', '4px #000 solid !important');

alors que cette déclaration sera bien appliquée:

jQuery('.foo').css('border', '4px #000 solid');

Pour contourner cette limitation, je vous propose plusieurs solutions.

Première solution : utiliser la fonction addClass()

C’est probablement la solution la plus simple : il suffit d’ajouter une classe votre élément avec addClass(), puis de définir le code CSS relatif à cette classe.

Exemple:

jQuery('.foo').addClass('border-black');

et on ajoute le code CSS suivant:

.border-black{
    border: 4px #000 solid !important;
}

Deuxième solution : utiliser la fonction attr()

Une autre solution est d’utiliser la fonction attr(), avec une concaténation pour garder le style CSS inline s’il est déjà présent:

jQuery('.foo').attr('style', function(i,s) { return (s || '') + 'border:4px #000 solid !important;' });

Troisième solution : utiliser la propriété cssText

Toujours en utilisant la concaténation pour garder les styles inline existants, nous utilisons la propriété cssText de la fonction css() :

jQuery('.foo').css('cssText', jQuery('.foo').css('cssText')+'border: 4px #000 solid !important');

Quatrième solution : utiliser style.setProperty()

Ce n’est pas parce que l’on utilise jQuery que nous devons oublier le vanilla JavaScript.

En l’occurrence, JS offre nativement la fonction style.setProperty() qui nous permet d’appliquer notre style aisément:

jQuery('.foo').each(function(){
   this.style.setProperty( 'border', '4px #000 solid', 'important' );
});

Have fun!

CSS : supprimer subtilement le placeholder d'un champ input ou textarea photo

CSS : supprimer subtilement le placeholder d’un champ input ou textarea

Je viens de finir un projet sur Codeable qui utilisait WordPress et Gravity Forms et lors de la réalisation d’un formulaire de réservation complexe, je me suis heurté à Chrome qui ne supprime pas toujours (suivant les versions utilisées) le texte du placeholder d’un champ de type input ou textarea lorsque le curseur est placé à l’intérieur (action focus).

Normalement, la valeur du placeholder disparaît et permet à l’utilisateur de compléter sa saisie mais sous certaines versions de Chrome, cela ne passe pas bien.

J’ai considéré l’utilisation de JavaScript, évidemment, avant de me rendre compte que l’on pouvait résoudre le problème avec quelques règles CSS natives. Toutes les déclarations sont à ajouter – ne cherchez pas à les compiler, cela ne fonctionnera pas !

On joue donc avec l’opacité et un léger effet de transition pour le côté subtil et smooth :

/* Placeholders */
::-webkit-input-placeholder { opacity: 1; transition: opacity .5s; }  /* Chrome 56, Safari 9 */
:-moz-placeholder { opacity: 1; transition: opacity .5s; } /* FF 4-18 */
::-moz-placeholder { opacity: 1; transition: opacity .5s; } /* FF 19-51 */
:-ms-input-placeholder { opacity: 1; -ms-transition: opacity .5s; transition: opacity .5s; } /* IE 10+ */
::placeholder { opacity: 1; transition: opacity .5s; } /* Modern Browsers */

/* Focus */
*:focus::-webkit-input-placeholder { opacity: 0; } /* Chrome 56, Safari 9 */
*:focus:-moz-placeholder { opacity: 0; } /* FF 4-18 */
*:focus::-moz-placeholder { opacity: 0; } /* FF 19-50 */
*:focus:-ms-input-placeholder { opacity: 0; } /* IE 10+ */
*:focus::placeholder { opacity: 0; } /* Modern Browsers */

Ps : Chrome souffre également d’un bug qui concerne la fonction autofill qui aide les utilisateurs à pré-remplir les formulaires.

Pensez donc à supprimer les valeurs enregistrées pendant vos tests (Chrome > Paramètres > Paramètres avancés > Confidentialité et sécurité > Effacer les données de navigation > Paramètres avancés > cocher Données de saisie automatique).

Enjoy !

Nouveau logo pour SkyMinds (version 2018) photo

Nouveau logo pour SkyMinds (version 2018)

Aujourd’hui, le logo de SkyMinds fait peau neuve ! Plus discret, plus moderne aussi. J’en ai profité pour mettre en place toute une liste de modifications cosmétiques que j’ai trop longtemps repoussées.

Nouveau logo pour SkyMinds (version 2018) photo
Nouveau logo !

Mise à jour des templates du thème enfant

L’avantage d’un thème enfant sous WordPress, c’est que l’on ne perd pas ses modifications lorsque le thème parent se met à jour. Le thème enfant, c’est tout simplement la base, l’étape qui vient juste après l’installation d’un nouveau thème.

Or, au fil des mois ans, il se trouve que le thème parent évolue et que les fichiers du thème enfant (modifiés) ne sont plus exactement à jour. J’en ai donc profité pour reprendre les nouveaux fichiers et y apporter mes modifications.

Concaténation des appels des fichiers de police

En analysant les fichiers du thème, je me suis rendu compte qu’on pouvait gagner pas mal de temps de chargement grâce à une épuration du nombre de polices utilisées sur le site. Au lieu d’en avoir deux (Open Sans et Droid Sans), il n’y en aura plus qu’une : Open Sans. Elle est légère, classique et facile à lire.

Le problème, c’est que Divi charge pas mal de versions de cette police par défaut : 300, 400, 700… en normal, italic et gras et avec des subsets exotiques comme le cyrillique, le grec ou le vietnamien. Clairement, on doit pouvoir mieux faire !

Divi : suppression des subsets Google Fonts

On commence par virer les subsets exotiques. Rendez-vous dans Divi > Theme options > General > désactivez Google Fonts subsets. Vous venez d’économisez 400KB.

Divi : suppression de toutes les Google Fonts et chargement de l’unique nécessaire

C’est pénible d’avoir tous les grammages d’une police chargés pour rien. Voici ce que j’utilise pour tout virer dans un premier temps, puis ajouter uniquement ce dont j’ai réellement besoin:

/*
|-----------------------------------------------------------------------
| Plugin Name: Sky Remove DIVI Google Fonts and add what we need
| Plugin URI:  https://www.skyminds.net/?p=29578
| Author:  Matt Biscay
| Author URI:  https://www.skyminds.net/
|-----------------------------------------------------------------------
*/

// remove all Divi fonts, we'll just load what we need
// @return: array
function et_builder_get_google_fonts() { return array(); }
function et_get_google_fonts() { return array(); }

// add fonts : logo (Comfortaa:700) and site (Open+Sans:400,700). No subsets.
add_action( 'wp_enqueue_scripts', 'sky_logo_add_google_fonts' );
function sky_logo_add_google_fonts() {
	wp_enqueue_style( 'sky-logo-google-fonts', 'https://fonts.googleapis.com/css?family=Comfortaa:700|Open+Sans:400,700', false ); 
}

Kaboom! On vient de se retirer une sacrée épine du pied. Il faudra juste relire la feuille de style pour être sûr que l’on utilise bien soit du font-weight 400 (regular), soit du 700 (bold). Pensez également à vérifier votre critical CSS.

Amélioration de la section Auteur

A la fin de chaque article se trouve la section de l’auteur, qui comprend une courte description ainsi que des liens vers ses profils sociaux. J’ai profité de la police du thème pour remplacer les noms des réseaux par des icônes. C’est purement cosmétique mais je trouve cela plus joli.

Cela m’a permis de me rendre compte que le site n’utilise absolument pas Font Awesome – ce que je trouve totalement fou. J’aime tellement cette police que j’ai acheté la version professionnelle pour mes développements… et ne l’utilise pas moi-même !

J’ai troqué le bleu clair pour un beige. A voir sur la durée.

Nouveau logo

Et enfin, last but not least, j’ai troqué mon logo image contre un logo font. Cela faisait pas mal de temps qu’il me trottait dans la tête l’idée de le changer. J’ai d’abord commencé, comme d’habitude, par tenter de créer des logos images avant de changer mon fusil d’épaule et considérer la possibilité d’utiliser une Google Font pour le générer à la volée.

Après quelques recherches, j’ai finalement opté pour la police Comfortaa en 700. C’est plutôt moderne par rapport au logo précédent qui avait la particularité d’être un dégradé de plusieurs couleurs (rose, violet, bleu, vert), avec des ligatures à certaines lettres.

Celui-ci sera donc beaucoup plus clean et professionnel. Je pense d’ailleurs le réutiliser sur d’autres supports de personal branding.

Lire la suite

CSS : remplir le contenu d'une div de manière fluide photo

CSS : remplir le contenu d’une div de manière fluide

J’ai récemment été confonté à un problème lors de la réécriture du code CSS d’un formulaire Gravity Form : on voulait que le contenu remplisse la div, sans sauter de ligne lorsqu’il n’y en avait pas besoin.

Je pensais naïvement qu’un simple float:none et une largeur à 100% suffiraient :

.gfield_label {
   float: none !important;
   width: 100% !important;
}

Mais cela a fini par chambouler tous les champs de formulaires : labels et champs n’étaient plus sur la même ligne.

La solution est toute simple mais cela m’a pris un temps fou à la trouver – il suffit d’ajouter un clear:both au bloc parent qui contient l’élément que l’on veut fluidifier, comme ceci :

/* Make it flow */
li#field_11_10 { clear: both !important; }

En espérant que cela puisse vous faire gagner du temps !

Javascript : afficher le contenu d'un bloc HTML après un délai variable photo

JavaScript : afficher du contenu dans un bloc DIV après un délai défini

Voici comment afficher du contenu (texte, HTML, JS, CSS ou tout autre contenu) dans un bloc DIV, après un délai que vous aurez préalablement défini, le tout en JavaScript.

C’est écrit en JavaScript pur (vanilla JavaScript), c’est-à-dire sans librairies supplémentaires, et donc compatible avec tous les navigateurs. On utilise innerHTML pour faire apparaître la div après le délai imparti.

Exemple de contenu affiché après un délai

Le texte suivant apparaît 7 secondes après le chargement de la page :

Le code : afficher le contenu d’une DIV après un délai

Voici le style CSS à placer dans l’entête de la page (HEAD) :

.centered {
    margin:0 auto;
    text-align:center;
}

Et voici le contenu HTML à placer dans le corps de la page (BODY):

<div id="example_div" class="centered"> </div>

Ainsi que le code JavaScript qui s’occupe du délai:

/*
|-----------------------------------------------------------------------
| Delayed DIV text in vanilla JavaScript by Matt 
| URL : https://www.skyminds.net
|-----------------------------------------------------------------------
|
| Returns predefined text in a DIV after a delay.
|
*/
(function(){
   var element_id = 'example_div' ; /* name of div ID w/ delayed text */
   var delayed_text = "Ceci est un texte d'illustration pour tester l'affichage d'un bloc DIV après un délai défini."; 
   var time = 7; /* time in seconds until display */

setTimeout(function(){
document.getElementById(element_id).innerHTML = delayed_text;},time*1000);
})();

Fonctionnement du script

Voici comment fonctionne le script : on recherche le bloc DIV qui possède l’identifiant #exemple_div et on lui injecte le contenu de la variable delayed_text après le délai en secondes défini dans la variable time.

Ne pas oublier d’échapper les slash par des antislash dans les balises de fermeture (liens, paragraphes etc) dans la variable delayed_text.

Simple et efficace.

HTML5 : corriger l'erreur

HTML5 : corriger l’erreur “The frameborder attribute on the iframe element is obsolete. Use CSS instead.”

Le problème : l’attribut HTML frameborder

HTML5-logo

Si vous obtenez l’erreur :
“The frameborder attribute on the iframe element is obsolete. Use CSS instead.”

sur le validateur HTML5 du W3C, c’est que le code de votre page HTML5 contient un élément <iframe> avec un attribut frameborder comme dans l’exemple suivant :

<iframe frameborder="0" />

Solution CSS: la propriété border

Comme l’attribut frameborder n’est plus présent dans HTML5, il faut utiliser la propriété CSS border en CSS à la place de l’attribut HTML frameborder:

<iframe style="border: 0;" />

Solution HTML : l’attribut seamless

Avec HTML5, il est possible de résoudre le problème en ajoutant l’attribut seamless à l’iframe:

<iframe seamless />

L’apparence du texte et des éléments de présentation de la page doivent être gérés par CSS et non par le code HTML, c’est plus propre et surtout plus simple à gérer.

HTML5 : corriger l'erreur

HTML5 : corriger l’erreur “The scrolling attribute on the iframe element is obsolete. Use CSS instead.”

Le problème : l’attribut HTML scrolling

HTML5-logo

Si, au détour d’une validation du code HTML5 de votre page, vous obtenez l’erreur suivante:

“The scrolling attribute on the iframe element is obsolete. Use CSS instead”

… c’est que le code de votre page HTML5 contient un élément <iframe> avec un attribut scrolling comme dans le code suivant :

<iframe scrolling="no" />

La solution CSS : la propriété overflow

Comme l’attribut scrolling ne fait plus partie des spécifications HTML5, il faut utiliser CSS à la place et utiliser la propriété overflow:

<iframe style="overflow: hidden;" />

L’apparence du texte et des éléments de présentation de la page doivent être gérés par CSS et non par le code HTML.

jQuery : sélectionner un élément dont l'ID ou la classe commence ou finit par une chaîne photo 1

jQuery : script toggle pour afficher et cacher de multiples blocs HTML

jquery

J’ai écrit il y a quelques temps un script jQuery utilisant la fonction toggle pour afficher/cacher un seul bloc HTML mais pas mal de gens m’ont demandé comment faire pour afficher plusieurs blocs HTML.

Voici comment s’y prendre, en utilisant les fonctions jQuery .slideup(), .slidedown() et .closest().

Démo


Article A

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam

Article B

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam

Article C
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam

Le script

1. Ajoutez jQuery dans l’entête de votre page (head), comme ceci :

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>

Lire la suite

WordPress : valider le code des meta oEmbeds de YouTube, DailyMotion, Vimeo et SlideShare photo

WordPress : valider le code des meta oEmbeds de YouTube, DailyMotion, Vimeo et SlideShare

Allez, je continue ma petite série sur la gestion de l’intégration oEmbed sous WordPress.

WordPress gère nativement plusieurs services : copiez-collez l’adresse d’une vidéo YouTube dans un article et hop, vous obtenez une vidéo entièrement intégrée, avec un code plutôt propre mais pas entièrement valide.

oembed-all-service

Je vous propose donc de valider le code généré par WordPress lorsqu’il vient de sites tiers comme YouTube, DailyMotion, Vimeo ou SlideShare.

Valider le code oEmbed de YouTube

Il suffit de lancer les quatre requêtes SQL suivantes :

UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, 'frameborder="0" allowfullscreen', 'style="border: none"');
UPDATE wp_commentmeta SET meta_value = REPLACE (meta_value, 'frameborder="0" allowfullscreen', 'style="border: none"');
UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, "wmode=transparent' frameborder='0'", "wmode=transparent' style='border: none'");
UPDATE wp_commentmeta SET meta_value = REPLACE (meta_value, "wmode=transparent' frameborder='0'", "wmode=transparent' style='border: none'");

Valider le code oEmbed de Dailymotion

Pour le code de Dailymotion, ces deux requêtes suffisent :

UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, 'frameborder="0">', 'style="border: none">');
UPDATE wp_commentmeta SET meta_value = REPLACE (meta_value, 'frameborder="0">', 'style="border: none">');

Valider le code oEmbed de Vimeo

Quatre requêtes pour Vimeo :

UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, 'frameborder="0" title=', 'title=');
UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, ' webkitallowfullscreen mozallowfullscreen allowfullscreen', '');
UPDATE wp_commentmeta SET meta_value = REPLACE (meta_value, 'frameborder="0" title=', 'title=');
UPDATE wp_commentmeta SET meta_value = REPLACE (meta_value, ' webkitallowfullscreen mozallowfullscreen allowfullscreen', '');

Valider le code oEmbed de SlideShare

Et deux requêtes pour SlideShare :

UPDATE wp_postmeta SET meta_value = REPLACE (meta_value, 'frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen>', 'style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px;overflow:auto;border:none">');
UPDATE wp_commentmeta SET meta_value = REPLACE (meta_value, 'frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen>', 'style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px;overflow:auto;border:none">');

Et voilà, le code est plus propre, plus valide et utilise CSS plutôt que des balises propriétaires.