Default theme: Improve compatibility with older browsers

Namely (it could hardly be different...) Internet Explorer - even IE11 still causes trouble. The default theme now supports IE9+, even older browsers will present broken markup. The sliding animation works with IE10+ (however, it is still usable, there's just no nice animation).

Furthermore this commit heavily improves the sliding process by allowing to abort the animation. I've updated Pico's screenshot in the , too.
This commit is contained in:
Daniel Rudolf 2016-08-02 21:49:46 +02:00
parent 6a13915f15
commit 432710c400
No known key found for this signature in database
GPG key ID: A061F02CD8DE4538
6 changed files with 138 additions and 136 deletions

View file

@ -11,7 +11,7 @@ Pico is a stupidly simple, blazing fast, flat file CMS. See http://picocms.org/
Screenshot Screenshot
------- -------
![Pico Screenshot](https://cloud.githubusercontent.com/assets/640217/11488596/70b39396-978d-11e5-885e-01341ad9dd75.gif) ![Pico Screenshot](https://cloud.githubusercontent.com/assets/920356/17342119/f5a85ee8-58f7-11e6-856e-cd72f76cec61.png)
Install Install
------- -------

View file

@ -62,6 +62,7 @@
</div> </div>
</footer> </footer>
<script src="{{ theme_url }}/js/modernizr-3.3.1-custom.min.js" type="text/javascript"></script>
<script src="{{ theme_url }}/js/utils.js" type="text/javascript"></script> <script src="{{ theme_url }}/js/utils.js" type="text/javascript"></script>
<script src="{{ theme_url }}/js/pico.js" type="text/javascript"></script> <script src="{{ theme_url }}/js/pico.js" type="text/javascript"></script>

View file

@ -0,0 +1,3 @@
/*! modernizr 3.3.1 (Custom Build) | MIT *
* https://modernizr.com/download/?-classlist-csstransitions-dataset-requestanimationframe !*/
!function(e,n,t){function r(e,n){return typeof e===n}function i(){var e,n,t,i,o,s,a;for(var f in y)if(y.hasOwnProperty(f)){if(e=[],n=y[f],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;t<n.options.aliases.length;t++)e.push(n.options.aliases[t].toLowerCase());for(i=r(n.fn,"function")?n.fn():n.fn,o=0;o<e.length;o++)s=e[o],a=s.split("."),1===a.length?Modernizr[a[0]]=i:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=i),C.push((i?"":"no-")+a.join("-"))}}function o(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):x?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function s(e,n){return!!~(""+e).indexOf(n)}function a(e){return e.replace(/([a-z])-([a-z])/g,function(e,n,t){return n+t.toUpperCase()}).replace(/^-/,"")}function f(e,n){return function(){return e.apply(n,arguments)}}function u(e,n,t){var i;for(var o in e)if(e[o]in n)return t===!1?e[o]:(i=n[e[o]],r(i,"function")?f(i,t||n):i);return!1}function l(e){return e.replace(/([A-Z])/g,function(e,n){return"-"+n.toLowerCase()}).replace(/^ms-/,"-ms-")}function d(){var e=n.body;return e||(e=o(x?"svg":"body"),e.fake=!0),e}function p(e,t,r,i){var s,a,f,u,l="modernizr",p=o("div"),c=d();if(parseInt(r,10))for(;r--;)f=o("div"),f.id=i?i[r]:l+(r+1),p.appendChild(f);return s=o("style"),s.type="text/css",s.id="s"+l,(c.fake?c:p).appendChild(s),c.appendChild(p),s.styleSheet?s.styleSheet.cssText=e:s.appendChild(n.createTextNode(e)),p.id=l,c.fake&&(c.style.background="",c.style.overflow="hidden",u=w.style.overflow,w.style.overflow="hidden",w.appendChild(c)),a=t(p,e),c.fake?(c.parentNode.removeChild(c),w.style.overflow=u,w.offsetHeight):p.parentNode.removeChild(p),!!a}function c(n,r){var i=n.length;if("CSS"in e&&"supports"in e.CSS){for(;i--;)if(e.CSS.supports(l(n[i]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var o=[];i--;)o.push("("+l(n[i])+":"+r+")");return o=o.join(" or "),p("@supports ("+o+") { #modernizr { position: absolute; } }",function(e){return"absolute"==getComputedStyle(e,null).position})}return t}function m(e,n,i,f){function u(){d&&(delete E.style,delete E.modElem)}if(f=r(f,"undefined")?!1:f,!r(i,"undefined")){var l=c(e,i);if(!r(l,"undefined"))return l}for(var d,p,m,v,h,y=["modernizr","tspan","samp"];!E.style&&y.length;)d=!0,E.modElem=o(y.shift()),E.style=E.modElem.style;for(m=e.length,p=0;m>p;p++)if(v=e[p],h=E.style[v],s(v,"-")&&(v=a(v)),E.style[v]!==t){if(f||r(i,"undefined"))return u(),"pfx"==n?v:!0;try{E.style[v]=i}catch(g){}if(E.style[v]!=h)return u(),"pfx"==n?v:!0}return u(),!1}function v(e,n,t,i,o){var s=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+S.join(s+" ")+s).split(" ");return r(n,"string")||r(n,"undefined")?m(a,n,i,o):(a=(e+" "+T.join(s+" ")+s).split(" "),u(a,n,t))}function h(e,n,r){return v(e,t,t,n,r)}var y=[],g={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){y.push({name:e,fn:n,options:t})},addAsyncTest:function(e){y.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=g,Modernizr=new Modernizr;var C=[],w=n.documentElement;Modernizr.addTest("classlist","classList"in w);var x="svg"===w.nodeName.toLowerCase();Modernizr.addTest("dataset",function(){var e=o("div");return e.setAttribute("data-a-b","c"),!(!e.dataset||"c"!==e.dataset.aB)});var _="Moz O ms Webkit",S=g._config.usePrefixes?_.split(" "):[];g._cssomPrefixes=S;var T=g._config.usePrefixes?_.toLowerCase().split(" "):[];g._domPrefixes=T;var b={elem:o("modernizr")};Modernizr._q.push(function(){delete b.elem});var E={style:b.elem.style};Modernizr._q.unshift(function(){delete E.style}),g.testAllProps=v,g.testAllProps=h,Modernizr.addTest("csstransitions",h("transition","all",!0));var z=function(n){var r,i=prefixes.length,o=e.CSSRule;if("undefined"==typeof o)return t;if(!n)return!1;if(n=n.replace(/^@/,""),r=n.replace(/-/g,"_").toUpperCase()+"_RULE",r in o)return"@"+n;for(var s=0;i>s;s++){var a=prefixes[s],f=a.toUpperCase()+"_"+r;if(f in o)return"@-"+a.toLowerCase()+"-"+n}return!1};g.atRule=z;var P=g.prefixed=function(e,n,t){return 0===e.indexOf("@")?z(e):(-1!=e.indexOf("-")&&(e=a(e)),n?v(e,n,t):v(e,"pfx"))};Modernizr.addTest("requestanimationframe",!!P("requestAnimationFrame",e),{aliases:["raf"]}),i(),delete g.addTest,delete g.addAsyncTest;for(var A=0;A<Modernizr._q.length;A++)Modernizr._q[A]();e.Modernizr=Modernizr}(window,document);

View file

@ -11,14 +11,13 @@
function main() { function main() {
// capability CSS classes // capability CSS classes
document.documentElement.classList.remove('no-js'); document.documentElement.className = 'js';
document.documentElement.classList.add('js');
// wrap tables // wrap tables
utils.forEach(document.querySelectorAll('main table'), function (_, table) { utils.forEach(document.querySelectorAll('main table'), function (_, table) {
if (!table.parentElement.classList.contains('table-responsive')) { if (!/\btable-responsive\b/.test(table.parentElement.className)) {
var tableWrapper = document.createElement('div'); var tableWrapper = document.createElement('div');
tableWrapper.classList.add('table-responsive'); tableWrapper.className = 'table-responsive';
table.parentElement.insertBefore(tableWrapper, table); table.parentElement.insertBefore(tableWrapper, table);
tableWrapper.appendChild(table); tableWrapper.appendChild(table);
@ -49,14 +48,14 @@ function main() {
}, },
onResizeEvent = function () { onResizeEvent = function () {
if (utils.isElementVisible(menuToggle)) { if (utils.isElementVisible(menuToggle)) {
menu.classList.add('hidden'); menu.className = 'hidden';
menuToggle.addEventListener('click', toggleMenuEvent); menuToggle.addEventListener('click', toggleMenuEvent);
menuToggle.addEventListener('keydown', toggleMenuEvent); menuToggle.addEventListener('keydown', toggleMenuEvent);
} else { } else {
menuToggle.removeEventListener('keydown', toggleMenuEvent); menu.className = '';
menu.removeAttribute('data-slide-id');
menuToggle.removeEventListener('click', toggleMenuEvent); menuToggle.removeEventListener('click', toggleMenuEvent);
menu.classList.remove('hidden', 'slide', 'up'); menuToggle.removeEventListener('keydown', toggleMenuEvent);
delete menu.dataset.slideId;
} }
}; };

View file

@ -16,7 +16,8 @@ utils = {};
* *
* @param object object the object to iterate through * @param object object the object to iterate through
* @param function callback function to call on every item; the key is passed * @param function callback function to call on every item; the key is passed
* as first, the value as second parameter * as first, the value as second parameter; the callback may return FALSE
* to stop the iteration
* @return void * @return void
*/ */
utils.forEach = function (object, callback) { utils.forEach = function (object, callback) {
@ -31,7 +32,16 @@ utils.forEach = function (object, callback) {
}; };
/** /**
* Slides a element up (i.e. hide a element by changing its height to 0) * Checks whether the client's browser is able to slide elements or not
*
* @return boolean TRUE when the browser supports sliding, FALSE otherwise
*/
utils.canSlide = function () {
return (Modernizr.classlist && Modernizr.requestanimationframe && Modernizr.csstransitions);
};
/**
* Slides a element up (i.e. hide a element by changing its height to 0px)
* *
* @param HTMLElement element the element to slide up * @param HTMLElement element the element to slide up
* @param function finishCallback function to call when the animation has * @param function finishCallback function to call when the animation has
@ -40,12 +50,40 @@ utils.forEach = function (object, callback) {
* @return void * @return void
*/ */
utils.slideUp = function (element, finishCallback, startCallback) { utils.slideUp = function (element, finishCallback, startCallback) {
utils.slideOut(element, { if (!utils.canSlide()) {
cssRule: 'height', if (startCallback) startCallback();
cssRuleRef: 'clientHeight', element.className += (element.className !== '') ? ' hidden' : 'hidden';
cssClass: 'up', if (finishCallback) window.requestAnimationFrame(finishCallback);
startCallback: startCallback, return;
finishCallback: finishCallback }
element.style.height = element.clientHeight + 'px';
var slideId = parseInt(element.getAttribute('data-slide-id')) || 0;
element.setAttribute('data-slide-id', ++slideId);
window.requestAnimationFrame(function () {
element.classList.add('slide');
window.requestAnimationFrame(function () {
element.style.height = '0px';
if (startCallback) {
startCallback();
}
window.setTimeout(function () {
if (parseInt(element.getAttribute('data-slide-id')) !== slideId) return;
element.classList.add('hidden');
element.classList.remove('slide');
element.style.height = null;
if (finishCallback) {
window.requestAnimationFrame(finishCallback);
}
}, 500);
});
}); });
}; };
@ -59,48 +97,43 @@ utils.slideUp = function (element, finishCallback, startCallback) {
* @return void * @return void
*/ */
utils.slideDown = function (element, finishCallback, startCallback) { utils.slideDown = function (element, finishCallback, startCallback) {
utils.slideIn(element, { if (!utils.canSlide()) {
cssRule: 'height', if (startCallback) startCallback();
cssRuleRef: 'clientHeight', element.className = element.className.replace(/\bhidden\b */g, '');
cssClass: 'up', if (finishCallback) window.requestAnimationFrame(finishCallback);
startCallback: startCallback, return;
finishCallback: finishCallback }
});
};
/** var cssRuleOriginalValue = element.clientHeight + 'px',
* Slides a element out (i.e. hide the element) slideId = parseInt(element.getAttribute('data-slide-id')) || 0;
*
* @param HTMLElement element the element to slide out
* @param object options the settings of the sliding process
* @return void
*/
utils.slideOut = function (element, options) {
element.style[options.cssRule] = element[options.cssRuleRef] + 'px';
var slideId = parseInt(element.dataset.slideId) || 0; element.setAttribute('data-slide-id', ++slideId);
element.dataset.slideId = ++slideId;
element.style.height = null;
element.classList.remove('hidden');
element.classList.remove('slide');
var cssRuleValue = element.clientHeight + 'px';
element.style.height = cssRuleOriginalValue;
window.requestAnimationFrame(function () { window.requestAnimationFrame(function () {
element.classList.add('slide'); element.classList.add('slide');
window.requestAnimationFrame(function () { window.requestAnimationFrame(function () {
element.classList.add(options.cssClass); element.style.height = cssRuleValue;
if (options.startCallback) { if (startCallback) {
options.startCallback(); startCallback();
} }
window.setTimeout(function () { window.setTimeout(function () {
if (parseInt(element.dataset.slideId) !== slideId) return; if (parseInt(element.getAttribute('data-slide-id')) !== slideId) return;
element.classList.add('hidden');
element.classList.remove('slide'); element.classList.remove('slide');
element.classList.remove(options.cssClass); element.style.height = null;
element.style[options.cssRule] = null;
if (options.finishCallback) { if (finishCallback) {
window.requestAnimationFrame(options.finishCallback); window.requestAnimationFrame(finishCallback);
} }
}, 500); }, 500);
}); });
@ -108,52 +141,9 @@ utils.slideOut = function (element, options) {
}; };
/** /**
* Slides a element in (i.e. make the element visible) * Checks whether a element is visible or not
* *
* @param HTMLElement element the element to slide in * @param HTMLElement element the element to check
* @param object options the settings of the sliding process
* @return void
*/
utils.slideIn = function (element, options) {
var cssRuleOriginalValue = element[options.cssRuleRef] + 'px',
slideId = parseInt(element.dataset.slideId) || 0;
element.dataset.slideId = ++slideId;
element.style[options.cssRule] = null;
element.classList.remove('hidden', 'slide', options.cssClass);
var cssRuleValue = element[options.cssRuleRef] + 'px';
element.classList.add('slide');
window.requestAnimationFrame(function () {
element.style[options.cssRule] = cssRuleOriginalValue;
window.requestAnimationFrame(function () {
element.style[options.cssRule] = cssRuleValue;
if (options.startCallback) {
options.startCallback();
}
window.setTimeout(function () {
if (parseInt(element.dataset.slideId) !== slideId) return;
element.classList.remove('slide');
element.style[options.cssRule] = null;
if (options.finishCallback) {
window.requestAnimationFrame(options.finishCallback);
}
}, 500);
});
});
};
/**
* Check whether a element is visible or not
*
* @param HTMLElement element the element to test
* @return boolean TRUE when the element is visible, FALSE otherwise * @return boolean TRUE when the element is visible, FALSE otherwise
*/ */
utils.isElementVisible = function (element) { utils.isElementVisible = function (element) {

View file

@ -7,6 +7,7 @@
* *
* Pico is a stupidly simple, blazing fast, flat file CMS. * Pico is a stupidly simple, blazing fast, flat file CMS.
* *
* @author Gilbert Pellegrom
* @author Daniel Rudolf * @author Daniel Rudolf
* @link http://picocms.org * @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License * @license http://opensource.org/licenses/MIT The MIT License
@ -20,15 +21,8 @@
padding: 0; padding: 0;
} }
body { article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
font-family: 'Droid Sans', 'Helvetica', 'Arial', sans-serif; display:block
font-size: 16px;
line-height: 1.6;
color: #444;
}
p, hr, table, .table-responsive, ol, ul, dl, pre, blockquote {
margin-bottom: 1em;
} }
.hidden { display: none !important; } .hidden { display: none !important; }
@ -48,19 +42,17 @@ p, hr, table, .table-responsive, ol, ul, dl, pre, blockquote {
-webkit-transition: height .5s ease-in !important; -webkit-transition: height .5s ease-in !important;
transition: height .5s ease-in !important; transition: height .5s ease-in !important;
} }
.slide.up { height: 0 !important; }
/*** BASIC LAYOUT ***/ /*** BASIC LAYOUT ***/
html { height: 100%; } html, body { height: 100%; }
body {
display: flex; body { display: flex; flex-direction: column; }
flex-direction: column; main { flex: 1 0 auto; }
height: 100%; header, footer { flex: 0 0 auto; }
}
main { main {
flex: 1 0 auto; padding: 5em 0 4em;
margin: 5em 0 4em;
} }
.container { .container {
@ -83,13 +75,14 @@ header { background: #2EAE9B; }
header h1 { header h1 {
float: left; float: left;
font-size: 2rem; font-size: 2rem;
margin: 0 1em 1.5em 0; margin: 0;
padding: 1.5em 1em 1.5em 0;
} }
header h1 a, header h1 a:hover { color: #fff; } header h1 a, header h1 a:hover { color: #fff; }
header nav { header nav {
text-align: right; text-align: right;
margin: 3em 0; padding: 3em 0;
} }
header nav ul { header nav ul {
list-style: none; list-style: none;
@ -106,17 +99,7 @@ header nav ul li {
header nav a, #page-menu-toggle { color: #afe1da; } header nav a, #page-menu-toggle { color: #afe1da; }
header nav .active a, header nav a:hover, #page-menu-toggle:hover { color: #fff; } header nav .active a, header nav a:hover, #page-menu-toggle:hover { color: #fff; }
#page-menu-toggle { #page-menu-toggle { display: none; }
display: none;
float: right;
width: 2em;
margin: 0 0 0.5em 1em;
font-size: 1.5rem;
line-height: 2em;
text-align: center;
cursor: pointer;
}
#page-menu-toggle > * { vertical-align: middle; }
/*** BASIC LAYOUT: FOOTER ***/ /*** BASIC LAYOUT: FOOTER ***/
@ -129,35 +112,36 @@ footer a { color: #ddd; }
footer a:hover { color: #fff; } footer a:hover { color: #fff; }
footer p { footer p {
margin: 3em 0; margin: 0;
padding: 3em 0;
} }
footer .social { footer .social {
float: right; float: right;
margin: 0 0 0.5em 1em; padding: 1.5em 0 0.5em 1em;
font-size: 2rem; font-size: 2rem;
} }
/*** BASIC LAYOUT: EXTRA SMALL DEVICES ***/ /*** BASIC LAYOUT: EXTRA SMALL DEVICES ***/
@media (max-width: 767px) { @media (max-width: 767px) {
main { margin: 2em 0 1em; } main { padding: 2em 0 1em; }
header h1 { header h1 {
float: none; float: none;
margin: 0.5em 0; padding: 0.5em 0;
} }
header nav { header nav {
clear: right; clear: right;
margin: 0; padding: 0;
} }
header nav ul { header nav ul {
padding-bottom: 1em; padding-bottom: 1em;
} }
header nav ul li { header nav ul li {
display: block; display: block;
margin: 0; margin-left: 0;
text-align: center; text-align: center;
} }
header nav ul li a { header nav ul li a {
@ -165,13 +149,44 @@ footer .social {
padding: 0.5em 0; padding: 0.5em 0;
} }
.js #page-menu-toggle { display: block; } .js #page-menu-toggle {
display: block;
float: right;
width: 2em;
margin: 0.6667em 0 0.6667em 1.3333em;
font-size: 1.5rem;
line-height: 2em;
text-align: center;
cursor: pointer;
}
.js #page-menu-toggle > * { vertical-align: middle; }
footer p { margin: 1em 0; } footer p { padding: 1em 0; }
footer .social { padding: 0.5em 0 0.5em 1em; }
} }
/*** TEXT ***/ /*** TEXT ***/
body {
font-family: 'Droid Sans', 'Helvetica', 'Arial', sans-serif;
font-size: 16px;
line-height: 1.6;
font-variant-ligatures: common-ligatures;
text-rendering: optimizeLegibility;
font-kerning: normal;
color: #444;
}
p, td, th, li, dd {
text-align: justify;
overflow-wrap: break-word;
word-wrap: break-word;
}
p, hr, table, .table-responsive, ol, ul, dl, pre, blockquote {
margin-bottom: 1em;
}
a { a {
color: #2EAE9B; color: #2EAE9B;
text-decoration: none; text-decoration: none;
@ -194,12 +209,6 @@ h6 { font-size: 1rem; font-weight: normal; font-style: italic; }
img { max-width: 100%; } img { max-width: 100%; }
p, td, th, li, dd {
text-align: justify;
overflow-wrap: break-word;
word-wrap: break-word;
}
hr { hr {
border: 0.15em solid #f5f5f5; border: 0.15em solid #f5f5f5;
border-radius: 0.3em; border-radius: 0.3em;