├── LICENCE ├── README.md ├── assets ├── css │ └── styles.css ├── img │ ├── fr.svg │ ├── gb.svg │ └── language.png ├── js │ └── prism.js └── scss │ ├── _language.scss │ ├── core │ ├── _base.scss │ ├── _classes.scss │ ├── _normalize.5.0.0.scss │ ├── _prism.scss │ ├── _variables-colors.scss │ └── _variables-fonts.scss │ └── styles.scss ├── favicon.ico └── index.html /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Russ Weakley, Max Design 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A semantic, accessible language switcher 2 | 3 | Demo version: https://russmaxdesign.github.io/language-switcher/ 4 | 5 | This language switcher uses a simple radio button combination to allow users to change language. There is additional hidden information available for screen reader users. The module works with standard keyboard controls, and it also includes hover, focus and checked background colors. 6 | 7 | See [Licence information](LICENCE) for use. 8 | -------------------------------------------------------------------------------- /assets/css/styles.css: -------------------------------------------------------------------------------- 1 | .font24{font-size:1.5em}.font22{font-size:1.375em}.font20{font-size:1.25em}.font18{font-size:1.125em}.font16{font-size:1em}.font14{font-size:.875em}.font12{font-size:.75em}.font10{font-size:.625em}.c-black{color:#000}.c-red{color:#b00}.c-white{color:#fff}.c-primary-color{color:#166DCC}.c-secondary-color{color:#2E496E}.bg-black{background-color:#000}.bg-red{background-color:#b00}.bg-white{background-color:#fff}.bg-primary-color{background-color:#166DCC}.bg-secondary-color{background-color:#2E496E}.gray5{color:#f2f2f2}.gray10{color:#e5e5e5}.gray15{color:#d9d9d9}.gray20{color:#ccc}.gray25{color:#bfbfbf}.gray30{color:#b2b2b2}.gray35{color:#a6a6a6}.gray40{color:#999}.gray45{color:#8c8c8c}.gray50{color:gray}.gray55{color:#737373}.gray60{color:#666}.gray65{color:#595959}.gray70{color:#4d4d4d}.gray75{color:#404040}.gray80{color:#333}.gray85{color:#262626}.gray90{color:#1a1a1a}.bg-gray5{background-color:#f2f2f2}.bg-gray10{background-color:#e5e5e5}.bg-gray15{background-color:#d9d9d9}.bg-gray20{background-color:#ccc}.bg-gray25{background-color:#bfbfbf}.bg-gray30{background-color:#b2b2b2}.bg-gray35{background-color:#a6a6a6}.bg-gray40{background-color:#999}.bg-gray45{background-color:#8c8c8c}.bg-gray50{background-color:gray}.bg-gray55{background-color:#737373}.bg-gray60{background-color:#666}.bg-gray65{background-color:#595959}.bg-gray70{background-color:#4d4d4d}.bg-gray75{background-color:#404040}.bg-gray80{background-color:#333}.bg-gray85{background-color:#262626}.bg-gray90{background-color:#1a1a1a}/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:0.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}code[class*="language-"],pre[class*="language-"]{color:black;background:none;text-shadow:0 1px white;font-family:Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*="language-"]::-moz-selection,pre[class*="language-"] ::-moz-selection,code[class*="language-"]::-moz-selection,code[class*="language-"] ::-moz-selection{text-shadow:none;background:#b3d4fc}pre[class*="language-"]::selection,pre[class*="language-"] ::selection,code[class*="language-"]::selection,code[class*="language-"] ::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*="language-"],pre[class*="language-"]{text-shadow:none}}pre[class*="language-"]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#f5f2f0}:not(pre)>code[class*="language-"]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:slategray}.token.punctuation{color:#999}.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#905}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#690}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#a67f59;background:rgba(255,255,255,0.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.function{color:#DD4A68}.token.regex,.token.important,.token.variable{color:#e90}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.entity{cursor:help}*{box-sizing:border-box}body{margin:0;padding:20px;color:#4d4d4d;background:#fff;font-family:helvetica,arial,sans-serif;font-size:1em;line-height:1.2}h1{margin:0 0 .5em;font-size:1.8em}h2{margin:1em 0 .5em;font-size:1.4em}h3{margin:1.5em 0 .3em;font-size:1em;font-weight:bold}h4{margin:1.5em 0 .3em;font-size:.88888888em}h1,h2,h3,h4{color:#2E496E}p{margin:1em 0;line-height:1.5}img{max-width:100%;vertical-align:middle}a:link{color:#166DCC}a:visited{color:#1461b5}a:focus,a:hover{color:#11549e}a:active{color:#b00}hr{display:block;height:5px;border:0;margin:2em 0;background:#f2f2f2}figure{margin:1.5em 0;padding:0}figcaption{font-size:.875em;color:#737373;display:block;margin:.4em 0}table{width:100%;margin:1em 0 2em;border-collapse:collapse}caption{padding:0 0 .5em;font-weight:bold;text-align:left}th,td{border-bottom:1px solid #ccc;padding:.5em 1em;text-align:left;vertical-align:top}th{border-top:1px solid #ccc;border-bottom:2px solid #ccc;font-weight:bold}ul,ol{padding-left:1.5em}ul li,ol li{margin-bottom:.2em}dt{font-weight:bold}dd{margin:0 0 .5em;padding-left:1.5em}.container{max-width:38em;margin:0 auto}.hidden{position:absolute;overflow:hidden;clip:rect(0, 0, 0, 0);width:1px;height:1px;border:0;margin:-1px;padding:0}.markup-heading{color:#2E496E;font-size:1em;font-weight:bold}.example{border:1px solid #ccc;margin:1em 0;padding:1em}.input{margin-bottom:1em}.input__content{display:block;margin:0 0 .2em}.input__control{display:block;width:100%;height:2.2em;border:1px solid #ccc;border-radius:.2em;padding:0 .5em;color:gray;background-color:#fff;font-size:1em;line-height:2.2em}.button-primary{height:2.2em;border:1px solid #11549e;border-radius:.2em;padding:0 1em;cursor:pointer;color:#fff;background:#166DCC;font-family:inherit;font-size:1em;line-height:2.2em}.button-primary:focus,.button-primary:hover{border:1px solid #0c3c70;color:#fff;background:#11549e}.button-primary:active{border:1px solid #800;color:#fff;background:#b00}.button-secondary{height:2.2em;border:1px solid #ccc;border-radius:.2em;padding:0 1em;cursor:pointer;color:#166DCC;background:#fff;font-family:inherit;font-size:1em;line-height:2.2em}.button-secondary:focus,.button-secondary:hover{color:#11549e;background:#f2f2f2}.button-secondary:active{color:#b00;background:#e5e5e5}.language{width:110px;height:30px;font-size:14px;line-height:1;margin:1em 0}.language__container--left,.language__container--right{position:relative;float:left;width:55px;height:30px;padding:5px}.language__label{position:absolute;top:0;left:0;width:55px;height:30px;border:1px solid #ccc;padding:7px 8px 5px 0;background-color:#fff;background-repeat:no-repeat;background-position:7px 7px;background-size:14px;text-align:right;text-transform:uppercase}.language__container--left .language__label{border-radius:4px 0 0 4px}.language__container--right .language__label{border-left:0;border-radius:0 4px 4px 0}.language__control:hover+.language__label,.language__control:focus+.language__label{background-color:#eee}.language__control:checked+.language__label{background-color:#ddd}.language__control:focus+.language__label,.language__control:checked:focus+.language__label{z-index:2;outline:2px solid #85bffd;box-shadow:0 0 8px #85bffd}.language__container--fr .language__label{background-image:url("../img/fr.svg")}.language__container--en .language__label{background-image:url("../img/gb.svg")} 2 | -------------------------------------------------------------------------------- /assets/img/fr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/img/gb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /assets/img/language.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russmaxdesign/language-switcher/6355636f93a6a205d73ea19a3b79b8a4db69455e/assets/img/language.png -------------------------------------------------------------------------------- /assets/js/prism.js: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+sass+scss */ 2 | var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(v instanceof a)){u.lastIndex=0;var b=u.exec(v),k=1;if(!b&&h&&m!=r.length-1){if(u.lastIndex=y,b=u.exec(e),!b)break;for(var w=b.index+(c?b[1].length:0),_=b.index+b[0].length,A=m,P=y,j=r.length;j>A&&_>P;++A)P+=r[A].length,w>=P&&(++m,y=P);if(r[m]instanceof a||r[A-1].greedy)continue;k=A-m,v=e.slice(y,P),b.index-=y}if(b){c&&(f=b[1].length);var w=b.index+f,b=b[0].slice(f),_=w+b.length,O=v.slice(0,w),x=v.slice(_),S=[m,k];O&&S.push(O);var N=new a(l,g?n.tokenize(b,g):b,d,b,h);S.push(N),x&&S.push(x),Array.prototype.splice.apply(r,S)}}}}}return r},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var i={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}n.hooks.run("wrap",i);var o=Object.keys(i.attributes).map(function(e){return e+'="'+(i.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+(o?" "+o:"")+">"+i.content+""},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,i=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),i&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); 3 | Prism.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup; 4 | Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:{pattern:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\w\W]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); 5 | !function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var a=/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:a,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:a,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,delete e.languages.sass.selector,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism); 6 | Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)*url(?=\()/i,selector:{pattern:/(?=\S)[^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-_\w]+/,variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.scss.property={pattern:/(?:[\w-]|\$[-_\w]+|#\{\$[-_\w]+\})+(?=\s*:)/i,inside:{variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}},Prism.languages.insertBefore("scss","important",{variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-_\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},"boolean":/\b(?:true|false)\b/,"null":/\bnull\b/,operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.util.clone(Prism.languages.scss); 7 | -------------------------------------------------------------------------------- /assets/scss/_language.scss: -------------------------------------------------------------------------------- 1 | // language variables 2 | 3 | $language-width: 55px; 4 | $language-height: 30px; 5 | $language-focus: #85bffd; 6 | $language-border: #ccc; 7 | $language-hover: #eee; 8 | $language-checked: #ddd; 9 | 10 | 11 | // language styles 12 | 13 | .language { 14 | width: $language-width * 2; 15 | height: $language-height; 16 | font-size: 14px; 17 | line-height: 1; 18 | margin: 1em 0; 19 | } 20 | 21 | .language__container--left, 22 | .language__container--right { 23 | position: relative; 24 | float: left; 25 | width: $language-width; 26 | height: $language-height; 27 | padding: 5px; 28 | } 29 | 30 | .language__label { 31 | position: absolute; 32 | top: 0; 33 | left: 0; 34 | width: $language-width; 35 | height: $language-height; 36 | border: 1px solid $language-border; 37 | padding: 7px 8px 5px 0; 38 | background-color: $white; 39 | background-repeat: no-repeat; 40 | background-position: 7px 7px; 41 | background-size: 14px; 42 | text-align: right; 43 | text-transform: uppercase; 44 | } 45 | 46 | .language__container--left .language__label { 47 | border-radius: 4px 0 0 4px; 48 | } 49 | 50 | .language__container--right .language__label { 51 | border-left: 0; 52 | border-radius: 0 4px 4px 0; 53 | } 54 | 55 | .language__control:hover + .language__label, 56 | .language__control:focus + .language__label { 57 | background-color: $language-hover; 58 | } 59 | 60 | .language__control:checked + .language__label { 61 | background-color: $language-checked; 62 | } 63 | 64 | .language__control:focus + .language__label, 65 | .language__control:checked:focus + .language__label { 66 | z-index: 2; 67 | outline: 2px solid $language-focus; 68 | box-shadow: 0 0 8px $language-focus; 69 | } 70 | 71 | 72 | // country flags 73 | 74 | .language__container--fr .language__label { 75 | background-image: url('../img/fr.svg'); 76 | } 77 | 78 | .language__container--en .language__label { 79 | background-image: url('../img/gb.svg'); 80 | } 81 | -------------------------------------------------------------------------------- /assets/scss/core/_base.scss: -------------------------------------------------------------------------------- 1 | // box-sizing 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | 8 | // body 9 | 10 | body { 11 | margin: 0; 12 | padding: 20px; 13 | color: $base-text-color; 14 | background: $base-background-color; 15 | font-family: $base-font-family; 16 | font-size: $base-font-size; 17 | line-height: 1.2; 18 | } 19 | 20 | 21 | // headings 22 | 23 | h1 { 24 | margin: 0 0 .5em; 25 | font-size: 1.8em; 26 | } 27 | 28 | h2 { 29 | margin: 1em 0 .5em; 30 | font-size: 1.4em; 31 | } 32 | 33 | h3 { 34 | margin: 1.5em 0 .3em; 35 | font-size: 1em; 36 | font-weight: bold; 37 | } 38 | 39 | h4 { 40 | margin: 1.5em 0 .3em; 41 | font-size: .88888888em; 42 | } 43 | 44 | h1, 45 | h2, 46 | h3, 47 | h4 { 48 | color: $secondary-color; 49 | } 50 | 51 | 52 | // paragraphs 53 | 54 | p { 55 | margin: 1em 0; 56 | line-height: 1.5; 57 | } 58 | 59 | 60 | // img 61 | 62 | img { 63 | max-width: 100%; 64 | vertical-align: middle; 65 | } 66 | 67 | 68 | // links 69 | 70 | a:link { 71 | color: $link-color; 72 | } 73 | 74 | a:visited { 75 | color: $link-color-visited; 76 | } 77 | 78 | a:focus, 79 | a:hover { 80 | color: $link-color-hover; 81 | } 82 | 83 | a:active { 84 | color: $link-color-active; 85 | } 86 | 87 | 88 | // hr 89 | 90 | hr { 91 | display: block; 92 | height: 5px; 93 | border: 0; 94 | margin: 2em 0; 95 | background: $gray5; 96 | } 97 | 98 | 99 | // figure 100 | 101 | figure { 102 | margin: 1.5em 0; 103 | padding: 0; 104 | } 105 | 106 | figcaption { 107 | font-size: $font14; 108 | color: $gray55; 109 | display: block; 110 | margin: .4em 0; 111 | } 112 | 113 | 114 | // tables 115 | 116 | table { 117 | width: 100%; 118 | margin: 1em 0 2em; 119 | border-collapse: collapse; 120 | } 121 | 122 | caption { 123 | padding: 0 0 .5em; 124 | font-weight: bold; 125 | text-align: left; 126 | } 127 | 128 | th, 129 | td { 130 | border-bottom: 1px solid $base-table-color; 131 | padding: .5em 1em; 132 | text-align: left; 133 | vertical-align: top; 134 | } 135 | 136 | th { 137 | border-top: 1px solid $base-table-color; 138 | border-bottom: 2px solid $base-table-color; 139 | font-weight: bold; 140 | } 141 | 142 | 143 | // lists 144 | 145 | ul, 146 | ol { 147 | padding-left: 1.5em; 148 | li { 149 | margin-bottom: .2em; 150 | } 151 | } 152 | 153 | dt { 154 | font-weight: bold; 155 | } 156 | 157 | dd { 158 | margin: 0 0 .5em; 159 | padding-left: 1.5em; 160 | } 161 | -------------------------------------------------------------------------------- /assets/scss/core/_classes.scss: -------------------------------------------------------------------------------- 1 | // container 2 | 3 | .container { 4 | max-width: 38em; 5 | margin: 0 auto; 6 | } 7 | 8 | 9 | // hidden-text extend - to hide text offscreen 10 | 11 | %hidden, 12 | .hidden { 13 | position: absolute; 14 | overflow: hidden; 15 | clip: rect(0,0,0,0); 16 | width: 1px; 17 | height: 1px; 18 | border: 0; 19 | margin: -1px; 20 | padding: 0; 21 | } 22 | 23 | 24 | // markup headings 25 | 26 | .markup-heading { 27 | color: $secondary-color; 28 | font-size: 1em; 29 | font-weight: bold; 30 | } 31 | 32 | 33 | // example 34 | 35 | .example { 36 | border: 1px solid $base-border-color; 37 | margin: 1em 0; 38 | padding: 1em; 39 | } 40 | 41 | 42 | // input styles 43 | 44 | .input { 45 | margin-bottom: 1em; 46 | } 47 | 48 | .input__content { 49 | display: block; 50 | margin: 0 0 .2em; 51 | } 52 | 53 | .input__control { 54 | display: block; 55 | width: 100%; 56 | height: 2.2em; 57 | border: 1px solid $base-border-color; 58 | border-radius: .2em; 59 | padding: 0 .5em; 60 | color: $gray50; 61 | background-color: $white; 62 | font-size: 1em; 63 | line-height: 2.2em; 64 | } 65 | 66 | 67 | // button-primary 68 | 69 | .button-primary { 70 | height: 2.2em; 71 | border: 1px solid darken($link-color, 10%); 72 | border-radius: .2em; 73 | padding: 0 1em; 74 | cursor: pointer; 75 | color: $white; 76 | background: $link-color; 77 | font-family: inherit; 78 | font-size: 1em; 79 | line-height: 2.2em; 80 | } 81 | 82 | .button-primary:focus, 83 | .button-primary:hover { 84 | border: 1px solid darken($link-color-hover, 10%); 85 | color: $white; 86 | background: $link-color-hover; 87 | } 88 | 89 | .button-primary:active { 90 | border: 1px solid darken($link-color-active, 10%); 91 | color: $white; 92 | background: $link-color-active; 93 | } 94 | 95 | 96 | // button-secondary 97 | 98 | .button-secondary { 99 | height: 2.2em; 100 | border: 1px solid $base-border-color; 101 | border-radius: .2em; 102 | padding: 0 1em; 103 | cursor: pointer; 104 | color: $link-color; 105 | background: $white; 106 | font-family: inherit; 107 | font-size: 1em; 108 | line-height: 2.2em; 109 | } 110 | 111 | .button-secondary:focus, 112 | .button-secondary:hover { 113 | color: $link-color-hover; 114 | background: $gray5; 115 | } 116 | 117 | .button-secondary:active { 118 | color: $link-color-active; 119 | background: $gray10; 120 | } 121 | -------------------------------------------------------------------------------- /assets/scss/core/_normalize.5.0.0.scss: -------------------------------------------------------------------------------- 1 | /*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /** 4 | * 1. Change the default font family in all browsers (opinionated). 5 | * 2. Correct the line height in all browsers. 6 | * 3. Prevent adjustments of font size after orientation changes in 7 | * IE on Windows Phone and in iOS. 8 | */ 9 | 10 | /* Document 11 | ========================================================================== */ 12 | 13 | html { 14 | font-family: sans-serif; /* 1 */ 15 | line-height: 1.15; /* 2 */ 16 | -ms-text-size-adjust: 100%; /* 3 */ 17 | -webkit-text-size-adjust: 100%; /* 3 */ 18 | } 19 | 20 | /* Sections 21 | ========================================================================== */ 22 | 23 | /** 24 | * Remove the margin in all browsers (opinionated). 25 | */ 26 | 27 | body { 28 | margin: 0; 29 | } 30 | 31 | /** 32 | * Add the correct display in IE 9-. 33 | */ 34 | 35 | article, 36 | aside, 37 | footer, 38 | header, 39 | nav, 40 | section { 41 | display: block; 42 | } 43 | 44 | /** 45 | * Correct the font size and margin on `h1` elements within `section` and 46 | * `article` contexts in Chrome, Firefox, and Safari. 47 | */ 48 | 49 | h1 { 50 | font-size: 2em; 51 | margin: 0.67em 0; 52 | } 53 | 54 | /* Grouping content 55 | ========================================================================== */ 56 | 57 | /** 58 | * Add the correct display in IE 9-. 59 | * 1. Add the correct display in IE. 60 | */ 61 | 62 | figcaption, 63 | figure, 64 | main { /* 1 */ 65 | display: block; 66 | } 67 | 68 | /** 69 | * Add the correct margin in IE 8. 70 | */ 71 | 72 | figure { 73 | margin: 1em 40px; 74 | } 75 | 76 | /** 77 | * 1. Add the correct box sizing in Firefox. 78 | * 2. Show the overflow in Edge and IE. 79 | */ 80 | 81 | hr { 82 | box-sizing: content-box; /* 1 */ 83 | height: 0; /* 1 */ 84 | overflow: visible; /* 2 */ 85 | } 86 | 87 | /** 88 | * 1. Correct the inheritance and scaling of font size in all browsers. 89 | * 2. Correct the odd `em` font sizing in all browsers. 90 | */ 91 | 92 | pre { 93 | font-family: monospace, monospace; /* 1 */ 94 | font-size: 1em; /* 2 */ 95 | } 96 | 97 | /* Text-level semantics 98 | ========================================================================== */ 99 | 100 | /** 101 | * 1. Remove the gray background on active links in IE 10. 102 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 103 | */ 104 | 105 | a { 106 | background-color: transparent; /* 1 */ 107 | -webkit-text-decoration-skip: objects; /* 2 */ 108 | } 109 | 110 | /** 111 | * Remove the outline on focused links when they are also active or hovered 112 | * in all browsers (opinionated). 113 | */ 114 | 115 | a:active, 116 | a:hover { 117 | outline-width: 0; 118 | } 119 | 120 | /** 121 | * 1. Remove the bottom border in Firefox 39-. 122 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 123 | */ 124 | 125 | abbr[title] { 126 | border-bottom: none; /* 1 */ 127 | text-decoration: underline; /* 2 */ 128 | text-decoration: underline dotted; /* 2 */ 129 | } 130 | 131 | /** 132 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 133 | */ 134 | 135 | b, 136 | strong { 137 | font-weight: inherit; 138 | } 139 | 140 | /** 141 | * Add the correct font weight in Chrome, Edge, and Safari. 142 | */ 143 | 144 | b, 145 | strong { 146 | font-weight: bolder; 147 | } 148 | 149 | /** 150 | * 1. Correct the inheritance and scaling of font size in all browsers. 151 | * 2. Correct the odd `em` font sizing in all browsers. 152 | */ 153 | 154 | code, 155 | kbd, 156 | samp { 157 | font-family: monospace, monospace; /* 1 */ 158 | font-size: 1em; /* 2 */ 159 | } 160 | 161 | /** 162 | * Add the correct font style in Android 4.3-. 163 | */ 164 | 165 | dfn { 166 | font-style: italic; 167 | } 168 | 169 | /** 170 | * Add the correct background and color in IE 9-. 171 | */ 172 | 173 | mark { 174 | background-color: #ff0; 175 | color: #000; 176 | } 177 | 178 | /** 179 | * Add the correct font size in all browsers. 180 | */ 181 | 182 | small { 183 | font-size: 80%; 184 | } 185 | 186 | /** 187 | * Prevent `sub` and `sup` elements from affecting the line height in 188 | * all browsers. 189 | */ 190 | 191 | sub, 192 | sup { 193 | font-size: 75%; 194 | line-height: 0; 195 | position: relative; 196 | vertical-align: baseline; 197 | } 198 | 199 | sub { 200 | bottom: -0.25em; 201 | } 202 | 203 | sup { 204 | top: -0.5em; 205 | } 206 | 207 | /* Embedded content 208 | ========================================================================== */ 209 | 210 | /** 211 | * Add the correct display in IE 9-. 212 | */ 213 | 214 | audio, 215 | video { 216 | display: inline-block; 217 | } 218 | 219 | /** 220 | * Add the correct display in iOS 4-7. 221 | */ 222 | 223 | audio:not([controls]) { 224 | display: none; 225 | height: 0; 226 | } 227 | 228 | /** 229 | * Remove the border on images inside links in IE 10-. 230 | */ 231 | 232 | img { 233 | border-style: none; 234 | } 235 | 236 | /** 237 | * Hide the overflow in IE. 238 | */ 239 | 240 | svg:not(:root) { 241 | overflow: hidden; 242 | } 243 | 244 | /* Forms 245 | ========================================================================== */ 246 | 247 | /** 248 | * 1. Change the font styles in all browsers (opinionated). 249 | * 2. Remove the margin in Firefox and Safari. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | font-family: sans-serif; /* 1 */ 258 | font-size: 100%; /* 1 */ 259 | line-height: 1.15; /* 1 */ 260 | margin: 0; /* 2 */ 261 | } 262 | 263 | /** 264 | * Show the overflow in IE. 265 | * 1. Show the overflow in Edge. 266 | */ 267 | 268 | button, 269 | input { /* 1 */ 270 | overflow: visible; 271 | } 272 | 273 | /** 274 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 275 | * 1. Remove the inheritance of text transform in Firefox. 276 | */ 277 | 278 | button, 279 | select { /* 1 */ 280 | text-transform: none; 281 | } 282 | 283 | /** 284 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 285 | * controls in Android 4. 286 | * 2. Correct the inability to style clickable types in iOS and Safari. 287 | */ 288 | 289 | button, 290 | html [type="button"], /* 1 */ 291 | [type="reset"], 292 | [type="submit"] { 293 | -webkit-appearance: button; /* 2 */ 294 | } 295 | 296 | /** 297 | * Remove the inner border and padding in Firefox. 298 | */ 299 | 300 | button::-moz-focus-inner, 301 | [type="button"]::-moz-focus-inner, 302 | [type="reset"]::-moz-focus-inner, 303 | [type="submit"]::-moz-focus-inner { 304 | border-style: none; 305 | padding: 0; 306 | } 307 | 308 | /** 309 | * Restore the focus styles unset by the previous rule. 310 | */ 311 | 312 | button:-moz-focusring, 313 | [type="button"]:-moz-focusring, 314 | [type="reset"]:-moz-focusring, 315 | [type="submit"]:-moz-focusring { 316 | outline: 1px dotted ButtonText; 317 | } 318 | 319 | /** 320 | * Change the border, margin, and padding in all browsers (opinionated). 321 | */ 322 | 323 | fieldset { 324 | border: 1px solid #c0c0c0; 325 | margin: 0 2px; 326 | padding: 0.35em 0.625em 0.75em; 327 | } 328 | 329 | /** 330 | * 1. Correct the text wrapping in Edge and IE. 331 | * 2. Correct the color inheritance from `fieldset` elements in IE. 332 | * 3. Remove the padding so developers are not caught out when they zero out 333 | * `fieldset` elements in all browsers. 334 | */ 335 | 336 | legend { 337 | box-sizing: border-box; /* 1 */ 338 | color: inherit; /* 2 */ 339 | display: table; /* 1 */ 340 | max-width: 100%; /* 1 */ 341 | padding: 0; /* 3 */ 342 | white-space: normal; /* 1 */ 343 | } 344 | 345 | /** 346 | * 1. Add the correct display in IE 9-. 347 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. 348 | */ 349 | 350 | progress { 351 | display: inline-block; /* 1 */ 352 | vertical-align: baseline; /* 2 */ 353 | } 354 | 355 | /** 356 | * Remove the default vertical scrollbar in IE. 357 | */ 358 | 359 | textarea { 360 | overflow: auto; 361 | } 362 | 363 | /** 364 | * 1. Add the correct box sizing in IE 10-. 365 | * 2. Remove the padding in IE 10-. 366 | */ 367 | 368 | [type="checkbox"], 369 | [type="radio"] { 370 | box-sizing: border-box; /* 1 */ 371 | padding: 0; /* 2 */ 372 | } 373 | 374 | /** 375 | * Correct the cursor style of increment and decrement buttons in Chrome. 376 | */ 377 | 378 | [type="number"]::-webkit-inner-spin-button, 379 | [type="number"]::-webkit-outer-spin-button { 380 | height: auto; 381 | } 382 | 383 | /** 384 | * 1. Correct the odd appearance in Chrome and Safari. 385 | * 2. Correct the outline style in Safari. 386 | */ 387 | 388 | [type="search"] { 389 | -webkit-appearance: textfield; /* 1 */ 390 | outline-offset: -2px; /* 2 */ 391 | } 392 | 393 | /** 394 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. 395 | */ 396 | 397 | [type="search"]::-webkit-search-cancel-button, 398 | [type="search"]::-webkit-search-decoration { 399 | -webkit-appearance: none; 400 | } 401 | 402 | /** 403 | * 1. Correct the inability to style clickable types in iOS and Safari. 404 | * 2. Change font properties to `inherit` in Safari. 405 | */ 406 | 407 | ::-webkit-file-upload-button { 408 | -webkit-appearance: button; /* 1 */ 409 | font: inherit; /* 2 */ 410 | } 411 | 412 | /* Interactive 413 | ========================================================================== */ 414 | 415 | /* 416 | * Add the correct display in IE 9-. 417 | * 1. Add the correct display in Edge, IE, and Firefox. 418 | */ 419 | 420 | details, /* 1 */ 421 | menu { 422 | display: block; 423 | } 424 | 425 | /* 426 | * Add the correct display in all browsers. 427 | */ 428 | 429 | summary { 430 | display: list-item; 431 | } 432 | 433 | /* Scripting 434 | ========================================================================== */ 435 | 436 | /** 437 | * Add the correct display in IE 9-. 438 | */ 439 | 440 | canvas { 441 | display: inline-block; 442 | } 443 | 444 | /** 445 | * Add the correct display in IE. 446 | */ 447 | 448 | template { 449 | display: none; 450 | } 451 | 452 | /* Hidden 453 | ========================================================================== */ 454 | 455 | /** 456 | * Add the correct display in IE 10-. 457 | */ 458 | 459 | [hidden] { 460 | display: none; 461 | } 462 | -------------------------------------------------------------------------------- /assets/scss/core/_prism.scss: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+sass+scss */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | background: none; 12 | text-shadow: 0 1px white; 13 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | word-wrap: normal; 19 | line-height: 1.5; 20 | 21 | -moz-tab-size: 4; 22 | -o-tab-size: 4; 23 | tab-size: 4; 24 | 25 | -webkit-hyphens: none; 26 | -moz-hyphens: none; 27 | -ms-hyphens: none; 28 | hyphens: none; 29 | } 30 | 31 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 32 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 33 | text-shadow: none; 34 | background: #b3d4fc; 35 | } 36 | 37 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 38 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 39 | text-shadow: none; 40 | background: #b3d4fc; 41 | } 42 | 43 | @media print { 44 | code[class*="language-"], 45 | pre[class*="language-"] { 46 | text-shadow: none; 47 | } 48 | } 49 | 50 | /* Code blocks */ 51 | pre[class*="language-"] { 52 | padding: 1em; 53 | margin: .5em 0; 54 | overflow: auto; 55 | } 56 | 57 | :not(pre) > code[class*="language-"], 58 | pre[class*="language-"] { 59 | background: #f5f2f0; 60 | } 61 | 62 | /* Inline code */ 63 | :not(pre) > code[class*="language-"] { 64 | padding: .1em; 65 | border-radius: .3em; 66 | white-space: normal; 67 | } 68 | 69 | .token.comment, 70 | .token.prolog, 71 | .token.doctype, 72 | .token.cdata { 73 | color: slategray; 74 | } 75 | 76 | .token.punctuation { 77 | color: #999; 78 | } 79 | 80 | .namespace { 81 | opacity: .7; 82 | } 83 | 84 | .token.property, 85 | .token.tag, 86 | .token.boolean, 87 | .token.number, 88 | .token.constant, 89 | .token.symbol, 90 | .token.deleted { 91 | color: #905; 92 | } 93 | 94 | .token.selector, 95 | .token.attr-name, 96 | .token.string, 97 | .token.char, 98 | .token.builtin, 99 | .token.inserted { 100 | color: #690; 101 | } 102 | 103 | .token.operator, 104 | .token.entity, 105 | .token.url, 106 | .language-css .token.string, 107 | .style .token.string { 108 | color: #a67f59; 109 | background: hsla(0, 0%, 100%, .5); 110 | } 111 | 112 | .token.atrule, 113 | .token.attr-value, 114 | .token.keyword { 115 | color: #07a; 116 | } 117 | 118 | .token.function { 119 | color: #DD4A68; 120 | } 121 | 122 | .token.regex, 123 | .token.important, 124 | .token.variable { 125 | color: #e90; 126 | } 127 | 128 | .token.important, 129 | .token.bold { 130 | font-weight: bold; 131 | } 132 | .token.italic { 133 | font-style: italic; 134 | } 135 | 136 | .token.entity { 137 | cursor: help; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /assets/scss/core/_variables-colors.scss: -------------------------------------------------------------------------------- 1 | // base colors 2 | 3 | $black: #000; 4 | $blue: #00f; 5 | $red: #b00; 6 | $white: #fff; 7 | 8 | 9 | // gray variables 10 | 11 | $gray5: #f2f2f2; 12 | $gray10: #e5e5e5; 13 | $gray15: #d9d9d9; 14 | $gray20: #ccc; 15 | $gray25: #bfbfbf; 16 | $gray30: #b2b2b2; 17 | $gray35: #a6a6a6; 18 | $gray40: #999; 19 | $gray45: #8c8c8c; 20 | $gray50: #808080; 21 | $gray55: #737373; 22 | $gray60: #666; 23 | $gray65: #595959; 24 | $gray70: #4d4d4d; 25 | $gray75: #404040; 26 | $gray80: #333; 27 | $gray85: #262626; 28 | $gray90: #1a1a1a; 29 | 30 | 31 | // main colors 32 | 33 | $primary-color: #166DCC; 34 | $secondary-color: #2E496E; 35 | 36 | $base-text-color: $gray70; 37 | $base-background-color: $white; 38 | $base-border-color: $gray20; 39 | $base-table-color: $gray20; 40 | 41 | $link-color: $primary-color; 42 | $link-color-visited: darken($primary-color, 5%); 43 | $link-color-focus: darken($primary-color, 10%); 44 | $link-color-hover: darken($primary-color, 10%); 45 | $link-color-active: $red; 46 | 47 | 48 | 49 | // w3c helpers 50 | 51 | .c-black { color: $black; } 52 | .c-red { color: $red; } 53 | .c-white { color: $white; } 54 | .c-primary-color { color: $primary-color; } 55 | .c-secondary-color { color: $secondary-color; } 56 | .bg-black { background-color: $black; } 57 | .bg-red { background-color: $red; } 58 | .bg-white { background-color: $white; } 59 | .bg-primary-color { background-color: $primary-color; } 60 | .bg-secondary-color { background-color: $secondary-color; } 61 | 62 | 63 | // gray helpers 64 | 65 | .gray5 { color: $gray5 ; } 66 | .gray10 { color: $gray10; } 67 | .gray15 { color: $gray15; } 68 | .gray20 { color: $gray20; } 69 | .gray25 { color: $gray25; } 70 | .gray30 { color: $gray30; } 71 | .gray35 { color: $gray35; } 72 | .gray40 { color: $gray40; } 73 | .gray45 { color: $gray45; } 74 | .gray50 { color: $gray50; } 75 | .gray55 { color: $gray55; } 76 | .gray60 { color: $gray60; } 77 | .gray65 { color: $gray65; } 78 | .gray70 { color: $gray70; } 79 | .gray75 { color: $gray75; } 80 | .gray80 { color: $gray80; } 81 | .gray85 { color: $gray85; } 82 | .gray90 { color: $gray90; } 83 | .bg-gray5 { background-color: $gray5 ; } 84 | .bg-gray10 { background-color: $gray10; } 85 | .bg-gray15 { background-color: $gray15; } 86 | .bg-gray20 { background-color: $gray20; } 87 | .bg-gray25 { background-color: $gray25; } 88 | .bg-gray30 { background-color: $gray30; } 89 | .bg-gray35 { background-color: $gray35; } 90 | .bg-gray40 { background-color: $gray40; } 91 | .bg-gray45 { background-color: $gray45; } 92 | .bg-gray50 { background-color: $gray50; } 93 | .bg-gray55 { background-color: $gray55; } 94 | .bg-gray60 { background-color: $gray60; } 95 | .bg-gray65 { background-color: $gray65; } 96 | .bg-gray70 { background-color: $gray70; } 97 | .bg-gray75 { background-color: $gray75; } 98 | .bg-gray80 { background-color: $gray80; } 99 | .bg-gray85 { background-color: $gray85; } 100 | .bg-gray90 { background-color: $gray90; } 101 | -------------------------------------------------------------------------------- /assets/scss/core/_variables-fonts.scss: -------------------------------------------------------------------------------- 1 | // base font size 2 | 3 | $base-font-size: 1em; 4 | $base-font-family: helvetica, arial, sans-serif; 5 | 6 | 7 | // font variables 8 | 9 | $font24: $base-font-size * 1.5; 10 | $font22: $base-font-size * 1.375; 11 | $font20: $base-font-size * 1.25; 12 | $font18: $base-font-size * 1.125; 13 | $font16: $base-font-size; 14 | $font14: $base-font-size * .875; 15 | $font12: $base-font-size * .75; 16 | $font10: $base-font-size * .625; 17 | 18 | 19 | // font helpers 20 | 21 | .font24 { font-size: $font24; } 22 | .font22 { font-size: $font22; } 23 | .font20 { font-size: $font20; } 24 | .font18 { font-size: $font18; } 25 | .font16 { font-size: $font16; } 26 | .font14 { font-size: $font14; } 27 | .font12 { font-size: $font12; } 28 | .font10 { font-size: $font10; } 29 | -------------------------------------------------------------------------------- /assets/scss/styles.scss: -------------------------------------------------------------------------------- 1 | // variables 2 | 3 | @import "core/variables-fonts"; 4 | @import "core/variables-colors"; 5 | 6 | 7 | // modules 8 | 9 | @import "core/normalize.5.0.0"; 10 | @import "core/prism"; 11 | @import "core/base"; 12 | @import "core/classes"; 13 | 14 | 15 | // site specific 16 | 17 | @import "language"; 18 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/russmaxdesign/language-switcher/6355636f93a6a205d73ea19a3b79b8a4db69455e/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A simple, accessible language switcher module 6 | 7 | 8 | 9 | 10 | 11 |
12 |

A simple, accessible language switcher module

13 |

GitHub page

14 | 15 |

This language switcher module uses a simple radio button combination to 16 | allow users to change language. Note: This does not include any scripting 17 | to change languages.

18 | 24 | 25 |

Examples

26 |

Unstyled

27 |
28 |

Choose a language for this website

29 |
30 | 31 | 34 |
35 |
36 | 37 | 40 |
41 |
42 |

Unchecked by default

43 |
44 | 45 |
46 | 47 | 50 |
51 |
52 | 53 | 56 |
57 |
58 |

Checked by default

59 |
60 | 61 |
62 | 63 | 66 |
67 |
68 | 69 | 72 |
73 |
74 |
75 | 76 |

Code

77 |
78 |
Markup
79 |
<div class="language" role="radiogroup" aria-labelledby="language-switcher1">
 80 |   <p class="hidden" id="language-switcher1">Choose a language for this website</p>
 81 |   <div class="language__container--left language__container--fr">
 82 |     <input class="language__control" type="radio" id="language1-1" name="language-switch1">
 83 |     <label class="language__label" for="language1-1">
 84 |       FR<span class="hidden"> Français</span>
 85 |     </label>
 86 |   </div>
 87 |   <div class="language__container--right language__container--en">
 88 |     <input class="language__control" type="radio" id="language1-2" name="language-switch1">
 89 |     <label class="language__label" for="language1-2">
 90 |       EN<span class="hidden"> English</span>
 91 |     </label>
 92 |   </div>
 93 | </div>
94 |
95 | 96 |
97 |
SCSS
98 |
// language variables
 99 | 
100 | $language-width: 55px;
101 | $language-height: 30px;
102 | $language-focus: #85bffd;
103 | $language-border: #ccc;
104 | $language-hover: #eee;
105 | $language-checked: #ddd;
106 | 
107 | 
108 | // language styles
109 | 
110 | .language {
111 |   width: $language-width * 2;
112 |   height: $language-height;
113 |   font-size: 14px;
114 |   line-height: 1;
115 |   margin: 1em 0;
116 | }
117 | 
118 | .language__container--left,
119 | .language__container--right {
120 |   position: relative;
121 |   float: left;
122 |   width: $language-width;
123 |   height: $language-height;
124 |   padding: 5px;
125 | }
126 | 
127 | .language__label {
128 |   position: absolute;
129 |   top: 0;
130 |   left: 0;
131 |   width: $language-width;
132 |   height: $language-height;
133 |   border: 1px solid $language-border;
134 |   padding: 7px 8px 5px 0;
135 |   background-color: $white;
136 |   background-repeat: no-repeat;
137 |   background-position: 7px 7px;
138 |   background-size: 14px;
139 |   text-align: right;
140 |   text-transform: uppercase;
141 | }
142 | 
143 | .language__container--left .language__label {
144 |   border-radius: 4px 0 0 4px;
145 | }
146 | 
147 | .language__container--right .language__label {
148 |   border-left: 0;
149 |   border-radius: 0 4px 4px 0;
150 | }
151 | 
152 | .language__control:hover + .language__label,
153 | .language__control:focus + .language__label {
154 |   background-color: $language-hover;
155 | }
156 | 
157 | .language__control:checked + .language__label {
158 |   background-color: $language-checked;
159 | }
160 | 
161 | .language__control:focus + .language__label,
162 | .language__control:checked:focus + .language__label {
163 |   z-index: 2;
164 |   outline: 2px solid $language-focus;
165 |   box-shadow: 0 0 8px $language-focus;
166 | }
167 | 
168 | 
169 | // country flags
170 | 
171 | .language__container--fr .language__label {
172 |   background-image: url('../img/fr.svg');
173 | }
174 | 
175 | .language__container--en .language__label {
176 |   background-image: url('../img/gb.svg');
177 | }
178 | 
179 |
180 | 181 |
182 | 183 |

GitHub page

184 |
185 | 186 | 187 | 188 | 189 | --------------------------------------------------------------------------------