Pure CSS modal dialog
<a href="#popup">Open</a>
<dialog id="popup">
<a href="#!">Close</a>
</dialog>
dialog { display: block; }
dialog:not(:target):not([open]) { display: none; }
<a href="#popup">Open</a>
<dialog id="popup">
<a href="#!">Close</a>
</dialog>
dialog { display: block; }
dialog:not(:target):not([open]) { display: none; }
I used to write:
system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"
But in 2023, system-ui
is much more supported, so this covers almost all fonts:
system-ui, -apple-system, BlinkMacSystemFont, sans-serif
Un syntax highlighter minimal (encore plus léger et themable que microlight).
const hightlight = (code) => code
// operators
.replaceAll(/\b(var|function|typeof|new|return|if|for|in|while|break|do|continue|switch|case|try|catch)([^a-z0-9\$_])/g,
'<span class="c-keyword">$1</span>$2')
// types
.replaceAll(/\b(RegExp|Boolean|Number|String|Array|Object|Function|this|true|false|NaN|undefined|null|Infinity)([^a-z0-9\$_])/g,
'<span class="c-type">$1</span>$2')
// comments
.replaceAll(/(\/\*[^]*?\*\/|(\/\/)[^\n\r]+)/gim,'<span class="c-comment">$1</span>')
// strings
.replaceAll(/('.*?')/g,'<span class="c-string">$1</span>')
// function & variables names (with link)
.replaceAll(/([a-z\_\$][a-z0-9_]*)(\s?([\(\)\[\];]|[=+\-\*,<]\s)|\s>)/gi,'<a id="var-$1" href="#var-$1" class="c-variable">$1</a>$2')
// braces
.replaceAll(/(\{|\}|\]|\[|\|)/gi,'<span class="c-punctuation">$1</span>')
// numbers
.replaceAll(/(0x[0-9a-f]*|\b(\d*\.)?([\d]+(e-?[0-9]*)?)\b)/gi,'<span class="c-atom">$1</span>')//|(0x[0-9abcdefx]*)
// tabulations (2 spaces)
//.replace(/\t/g,' ')
document.querySelectorAll('code')
.forEach((code) => {
code.innerHTML=hightlight(code.innerText)
});
code .c-type {font-weight:700}
code .c-variable, .c-type {color: #228}
code .c-keyword {color: #708}
code .c-string {color:#a22}
code .c-punctuation {color:#666}
code .c-atom {color:#281}
code .c-comment, .c-comment * {color: #A70!important}
code *:target{background-color:#ff6}
Mais en quelques minutes d'utilisation, on voit qu'il souffre quelques problèmes. On peut donc l'améliorer rapidement en :
const hightlight = (code) => code
.replaceAll(/(<)/g,'<span>$1</span>') // Mandatory, else innerHTML comments them with <!-- -->
// Strings
.replaceAll(/('.*?'|".*?")/g,'<span class="c-string">$1</span>')
// Operators
.replaceAll(/\b(var|const|let|function|typeof|new|return|if|for|foreach|in|while|break|do|continue|switch|case|try|catch)([^a-z0-9\$_])/g,
'<span class="c-operator">$1</span>$2')
// Types
.replaceAll(/\b(RegExp|Boolean|Number|String|Array|Object|Function|this|true|false|NaN|undefined|null|Infinity)([^a-z0-9\$_])/g,
'<span class="c-type">$1</span>$2')
// Comments
.replaceAll(/(\/\*[^]*?\*\/|(?<!\:)(\/\/)[^\n\r]+|<span><<\/span>\!\-\-[^]*?\-\->)/gim,'<span class="c-comment">$1</span>')
// Variables & Function names
.replaceAll(/([a-z\_\$][a-z0-9_]*)(\s?([\(\)\[\];]|[=+\-\*,<]\s)|\s>)/gi,'<a id="var-$1" href="#var-$1" class="c-variable">$1</a>$2')
// Braces
.replaceAll(/(\{|\}|\]|\[|\|)/gi,'<span class="c-punctuation">$1</span>')
// Numbers
.replaceAll(/(0x[0-9a-f]*|\b(\d*\.)?([\d]+(e-?[0-9]*)?)\b)/gi,'<span class="c-atom">$1</span>')//|(0x[0-9abcdefx]*)
// Tabs (2 spaces)
//.replace(/\t/g,' ')
document.querySelectorAll('pre > code')
.forEach((code) => {
code.innerHTML=hightlight(code.textContent)
});
code .c-type {font-weight:700}
code .c-variable, .c-type {color: #228}
code .c-operator {color: #708}
code .c-string {color:#a22}
code .c-punctuation {color:#666}
code .c-atom {color:#281}
code .c-comment, .c-comment * {color: #A70!important}
code *:target{background-color:#ff6}
/* Tomorrow Night theme */
@media screen and (prefers-color-scheme: dark) {
code .c-type {color:#DB9455;font-style:700}
code .c-operator {color: #B194B4}
code .c-variable {color: #83A1C1}
code .c-string {color:#D7C467}
code .c-atom {color: #B1BE59}
code .c-punctuation {color:inherit}
code .c-comment, .c-comment * {color: #999!important;opacity:.5}
}
Modifications :
const
et let
pour Javascript, foreach
pour PHPtextContent
et non le plus lent et moins fiable innerText
(voir http://www.kellegous.com/j/2013/02/27/innertext-vs-textcontent/ mais pour résumer : innerText
n'était pas standard, il ne s'applique qu'à des HTMLElement
et non des Node
, il ne retourne que le contenu visible, change les espaces et demande des infos de layout qui font qu'il est de 12 à 300 fois moins rapide)<div class="relative">
<div class="toTop">
<a href="#top" title="Retour en haut">
Retour en haut
</a>
</div>
</div>
<footer id="footer">
…
</footer>
.relative {
position:relative;
}
.toTop {
display:none;
position:fixed;
right:20px;
bottom:20px;
z-index:1000;
}
function toTop(element,footer){
var scroll = $(window).scrollTop();
var maxScroll = $(window).height() * 0.4;
if(scroll > maxScroll)
$(element).show();
else
$(element).hide();
if($(element).offset().top + $(element).height() >= $(footer).offset().top - 10)
$(element).css('position', 'absolute');
if($(document).scrollTop() + window.innerHeight < $(footer).offset().top)
$(element).css('position', 'fixed');
}
$(window).scroll(function() {
toTop('.toTop',"#footer");
});
$(window).resize(function() {
toTop('.toTop',"#footer");
});
/* Greatly inspired by Frow https://github.com/Beg-in/frow */
.row,
[class*="row-"] {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-left: -15px; /* Gutters */
margin-right: -15px; /* Gutters */
}
.row > *,
[class*="row-"] > * {
max-width: 100%;
width: 100%;
padding-left: 15px; /* Gutters */
padding-right: 15px; /* Gutters */
}
@media (min-width: 992px) { /* Only on desktop by default */
.row,
[class*="row-"] {
justify-content: start;
}
/* Only on unstyled col in unstyled row
That way, unstyled col in styled rows will adapt */
.row > * {
flex: 1 1 auto;
width: auto;
}
.row-1 > * { width: 100%; }
.row-2 > * { width: 50%; }
.row-3 > * { width: 33.33%; }
.row-4 > * { width: 25%; }
.row-5 > * { width: 20%; }
.row-6 > * { width: 16.66%; }
.row-7 > * { width: 14.28%; }
.row-8 > * { width: 12.5%; }
.row-9 > * { width: 11.11%; }
.row-10 > * { width: 10%; }
.row-11 > * { width: 9.09%; }
.row-12 > * { width: 8.33%; }
.col-1 { width: 8.33%; }
.col-2 { width: 16.66%; }
.col-3 { width: 25%; }
.col-4 { width: 33.33%; }
.col-5 { width: 41.66%; }
.col-6 { width: 50%; }
.col-7 { width: 58.33%; }
.col-8 { width: 66.66%; }
.col-9 { width: 75%; }
.col-10 { width: 83.33%; }
.col-11 { width: 91.66%; }
.col-12 { width: 100%; }
}
So you can add columns without class:
<div class="row">
<div></div>
<div></div>
</div>
Or, you can specify the number of columns with .row-*
:
<div class="row-2">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
(will output 2 columns of 3 items)
Or, you can specify the width of each item with .col-*
:
<div class="row-12">
<div class="col-6"></div>
<div class="col-2"></div>
<div></div> <!-- Automagically fill -->
<div class="col-1"></div>
</div>
By default, will be displayed as a single column on mobile and tablets.
@media screen and (max-width:800px) {
td,
th {
display: block;
}
}
Or, with flexbox:
@media screen and (max-width: 800px) {
tr {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
td,
th {
flex: 1 1 10%;
text-align: center;
}
}
form {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
}
input {
margin:5px;
flex: 1 1 50%;
}
input[type=submit] {
flex: 1 1 20%;
cursor: pointer;
background: #5766AD;
color: white;
font-weight: 600;
}
input[name=url] {
/* Will occupy the entire width */
flex: 1 1 100%;
}
/* Flex Skeletton
For a column main+footer
with a sticky footer */
body,
html {
height: 100%;
min-height: 100%;
padding: 0;
margin: 0;
}
body {
display: flex;
flex-direction: column;
height: 100vh;
overflow-x: hidden;
}
section {
flex: 1 0 auto;
}
footer {
flex: none; // It's here the magic begins
}
Or another:
html, body {
height: 100%;
min-height: 100%;
padding: 0;
margin: 0;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
section {
flex: none;
margin-top: 0;
margin-bottom: auto;
}
footer {
flex: none;
}