Index: gc_lang/fr/webext/content_scripts/menu.css
==================================================================
--- gc_lang/fr/webext/content_scripts/menu.css
+++ gc_lang/fr/webext/content_scripts/menu.css
@@ -46,10 +46,15 @@
 
 
 /*
     Menu
 */
+div.grammalecte_abs {
+    display: none;
+    position: absolute;
+}
+
 div.grammalecte_menu {
     all: initial;
     display: none;
     position: absolute;
     margin-left: -10px;
@@ -58,10 +63,11 @@
     box-shadow: 0px 0px 2px hsla(210, 10%, 10%, .5);
     background-color: hsl(210, 50%, 30%);
     font-family: "Trebuchet MS", "Fira Sans", "Liberation Sans", sans-serif;
     z-index: 2147483640; /* maximum is 2147483647: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index */
     text-align: left;
+    width: 220px;
 }
 
 @media print {
     .grammalecte_menu { display: none; }
 }

Index: gc_lang/fr/webext/content_scripts/menu.js
==================================================================
--- gc_lang/fr/webext/content_scripts/menu.js
+++ gc_lang/fr/webext/content_scripts/menu.js
@@ -1,15 +1,20 @@
 // JavaScript
 
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global oGrammalecte, xGrammalectePort, showError, window, document */
+
 "use strict";
 
 
 class GrammalecteMenu {
 
     constructor (nMenu, xNode) {
         this.xNode = xNode;
         this.sMenuId = "grammalecte_menu" + nMenu;
+        this.bShadow = document.body.createShadowRoot || document.body.attachShadow;
         this.xButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_main_button", textContent: " "});
         this.xButton.onclick = () => { this.switchMenu(); };
         this.xButton.style.zIndex = (xNode.style.zIndex.search(/^[0-9]+$/) !== -1) ? (parseInt(xNode.style.zIndex) + 1).toString() : xNode.style.zIndex;
         this.xMenu = this._createMenu();
 
@@ -19,12 +24,30 @@
         let xNodeInsertAfter = this.xNode;
         if (document.location.host == "twitter.com" && this.xNode.classList.contains('rich-editor')) {
             xNodeInsertAfter = this.xNode.parentNode;
         }
 
-        this._insertAfter(this.xButton, xNodeInsertAfter, nMarginTop);
-        this._insertAfter(this.xMenu, xNodeInsertAfter, nMarginTop + 8);
+        if (this.bShadow){
+            this.oShadowBtn = oGrammalecte.createNode("div", {className: "grammalecte_abs", style: "width:16px;height:16px;"});
+            this.oShadowBtnNode = this.oShadowBtn.attachShadow({mode: "open"});
+            this.oShadowBtnNode.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/menu.css"})
+            );
+            this.oShadowBtnNode.appendChild(this.xButton);
+            this._insertAfter(this.oShadowBtn, xNodeInsertAfter, nMarginTop);
+
+            this.oShadowMenu = oGrammalecte.createNode("div", {id: this.sMenuId+"_shadow", className: "grammalecte_abs", style: "width:0;height:0;"});
+            this.oShadowMenuNode = this.oShadowMenu.attachShadow({mode: "open"});
+            this.oShadowMenuNode.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: oGrammalecte.sExtensionUrl + "content_scripts/menu.css"})
+            );
+            this.oShadowMenuNode.appendChild(this.xMenu);
+            this._insertAfter(this.oShadowMenu, xNodeInsertAfter, nMarginTop + 8);
+        } else {
+            this._insertAfter(this.xButton, xNodeInsertAfter, nMarginTop);
+            this._insertAfter(this.xMenu, xNodeInsertAfter, nMarginTop + 8);
+        }
         this._createListeners();
     }
 
     _insertAfter (xNewNode, xReferenceNode, nMarginTop) {
         xReferenceNode.parentNode.insertBefore(xNewNode, xReferenceNode.nextSibling);
@@ -31,10 +54,13 @@
         xNewNode.style.marginTop = nMarginTop + "px";
     }
 
     _createListeners () {
         this.xNode.addEventListener('focus', (e) => {
+            if (this.bShadow){
+                this.oShadowBtn.style.display = "block";
+            }
             this.xButton.style.display = "block";
         });
         /*this.xNode.addEventListener('blur', (e) => {
             window.setTimeout(() => {this.xButton.style.display = "none";}, 300);
         });*/
@@ -47,10 +73,13 @@
     _createMenu () {
         try {
             let xMenu = oGrammalecte.createNode("div", {id: this.sMenuId, className: "grammalecte_menu"});
             let xCloseButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_close_button", textContent: "×"} );
             xCloseButton.onclick = () => {
+                if (this.bShadow){
+                    this.oShadowBtn.style.display = "none";
+                }
                 this.xButton.style.display = "none";
                 this.switchMenu();
             }
             xMenu.appendChild(xCloseButton);
             xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"}));
@@ -113,13 +142,21 @@
             showError(e);
         }
     }
 
     deleteNodes () {
-        this.xMenu.parentNode.removeChild(this.xMenu);
-        this.xButton.parentNode.removeChild(this.xButton);
+        if (this.bShadow){
+            this.oShadowMenu.parentNode.removeChild(this.oShadowMenu);
+            this.oShadowBtn.parentNode.removeChild(this.oShadowBtn);
+        } else {
+            this.xMenu.parentNode.removeChild(this.xMenu);
+            this.xButton.parentNode.removeChild(this.xButton);
+        }
     }
 
     switchMenu () {
+        if (this.bShadow){
+            this.oShadowMenu.style.display = (this.oShadowMenu.style.display == "block") ? "none" : "block";
+        }
         this.xMenu.style.display = (this.xMenu.style.display == "block") ? "none" : "block";
     }
 }