Add tags
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
324
index.html
324
index.html
@ -14,32 +14,44 @@
|
|||||||
<nav class="sidebar" aria-label="Table of Contents">
|
<nav class="sidebar" aria-label="Table of Contents">
|
||||||
<button class="hamburger hamburger--spin sidebar__menu" type="button" aria-label="Menu" aria-expanded="false">
|
<button class="hamburger hamburger--spin sidebar__menu" type="button" aria-label="Menu" aria-expanded="false">
|
||||||
<span class="hamburger-box">
|
<span class="hamburger-box">
|
||||||
<span class="hamburger-inner"></span>
|
<span class="hamburger-inner"></span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="sidebar__links">
|
<div class="sidebar__links">
|
||||||
<a class="sidebar__link" href="#box-sizing-reset">Box-sizing reset</a>
|
<section data-type="layout" class="sidebar__section">
|
||||||
<a class="sidebar__link" href="#clearfix">Clearfix</a>
|
<h4 class="sidebar__section-heading">layout</h4>
|
||||||
<a class="sidebar__link" href="#constant-width-to-height-ratio">Constant width to height ratio</a>
|
<a class="sidebar__link" href="#box-sizing-reset"><span>Box-sizing reset</span></a>
|
||||||
<a class="sidebar__link" href="#custom-scrollbar">Custom scrollbar</a>
|
<a class="sidebar__link" href="#clearfix"><span>Clearfix</span></a>
|
||||||
<a class="sidebar__link" href="#custom-text-selection">Custom text selection</a>
|
<a class="sidebar__link" href="#constant-width-to-height-ratio"><span>Constant width to height ratio</span></a>
|
||||||
<a class="sidebar__link" href="#disable-selection">Disable selection</a>
|
<a class="sidebar__link" href="#evenly-distributed-children"><span>Evenly distributed children</span></a>
|
||||||
<a class="sidebar__link" href="#donut-spinner">Donut spinner</a>
|
<a class="sidebar__link" href="#horizontal-and-vertical-centering"><span>Horizontal and vertical centering</span></a>
|
||||||
<a class="sidebar__link" href="#easing-variables">Easing variables</a>
|
<a class="sidebar__link" href="#truncate-text"><span>Truncate text</span></a>
|
||||||
<a class="sidebar__link" href="#etched-text">Etched text</a>
|
</section>
|
||||||
<a class="sidebar__link" href="#evenly-distributed-children">Evenly distributed children</a>
|
<section data-type="visual" class="sidebar__section">
|
||||||
<a class="sidebar__link" href="#gradient-text">Gradient text</a>
|
<h4 class="sidebar__section-heading">visual</h4>
|
||||||
<a class="sidebar__link" href="#hairline-border">Hairline border</a>
|
<a class="sidebar__link" href="#custom-scrollbar"><span>Custom scrollbar</span></a>
|
||||||
<a class="sidebar__link" href="#horizontal-and-vertical-centering">Horizontal and vertical centering</a>
|
<a class="sidebar__link" href="#custom-text-selection"><span>Custom text selection</span></a>
|
||||||
<a class="sidebar__link" href="#hover-underline-animation">Hover underline animation</a>
|
<a class="sidebar__link" href="#etched-text"><span>Etched text</span></a>
|
||||||
<a class="sidebar__link" href="#mouse-cursor-gradient-tracking">Mouse cursor gradient tracking</a>
|
<a class="sidebar__link" href="#gradient-text"><span>Gradient text</span></a>
|
||||||
<a class="sidebar__link" href="#overflow-scroll-gradient">Overflow scroll gradient</a>
|
<a class="sidebar__link" href="#hairline-border"><span>Hairline border</span></a>
|
||||||
<a class="sidebar__link" href="#popout-menu">Popout menu</a>
|
<a class="sidebar__link" href="#overflow-scroll-gradient"><span>Overflow scroll gradient</span></a>
|
||||||
<a class="sidebar__link" href="#pretty-text-underline">Pretty text underline</a>
|
<a class="sidebar__link" href="#pretty-text-underline"><span>Pretty text underline</span></a>
|
||||||
<a class="sidebar__link" href="#shape-separator">Shape separator</a>
|
<a class="sidebar__link" href="#shape-separator"><span>Shape separator</span></a>
|
||||||
<a class="sidebar__link" href="#system-font-stack">System font stack</a>
|
<a class="sidebar__link" href="#system-font-stack"><span>System font stack</span></a>
|
||||||
<a class="sidebar__link" href="#triangle">Triangle</a>
|
<a class="sidebar__link" href="#triangle"><span>Triangle</span></a>
|
||||||
<a class="sidebar__link" href="#truncate-text">Truncate text</a>
|
</section>
|
||||||
|
<section data-type="animation" class="sidebar__section">
|
||||||
|
<h4 class="sidebar__section-heading">animation</h4>
|
||||||
|
<a class="sidebar__link" href="#donut-spinner"><span>Donut spinner</span></a>
|
||||||
|
<a class="sidebar__link" href="#easing-variables"><span>Easing variables</span></a>
|
||||||
|
<a class="sidebar__link" href="#hover-underline-animation"><span>Hover underline animation</span></a>
|
||||||
|
</section>
|
||||||
|
<section data-type="interactivity" class="sidebar__section">
|
||||||
|
<h4 class="sidebar__section-heading">interactivity</h4>
|
||||||
|
<a class="sidebar__link" href="#disable-selection"><span>Disable selection</span></a>
|
||||||
|
<a class="sidebar__link" href="#mouse-cursor-gradient-tracking"><span>Mouse cursor gradient tracking</span></a>
|
||||||
|
<a class="sidebar__link" href="#popout-menu"><span>Popout menu</span></a>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
@ -55,8 +67,20 @@
|
|||||||
</header>
|
</header>
|
||||||
<main class="main" id="main">
|
<main class="main" id="main">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<nav class="tags" aria-label="Filter by tags">
|
||||||
|
<button class="tags__tag is-large is-active" data-type="all">
|
||||||
|
<i data-feather="check"></i>all</button>
|
||||||
|
<button class="tags__tag is-large " data-type="layout">
|
||||||
|
<i data-feather="layout"></i>layout</button>
|
||||||
|
<button class="tags__tag is-large " data-type="visual">
|
||||||
|
<i data-feather="eye"></i>visual</button>
|
||||||
|
<button class="tags__tag is-large " data-type="animation">
|
||||||
|
<i data-feather="loader"></i>animation</button>
|
||||||
|
<button class="tags__tag is-large " data-type="interactivity">
|
||||||
|
<i data-feather="edit-2"></i>interactivity</button>
|
||||||
|
</nav>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="box-sizing-reset">Box-sizing reset</h3>
|
<h3 id="box-sizing-reset"><span>Box-sizing reset</span><span class="tags__tag snippet__tag" data-type="layout"><i data-feather="layout"></i>layout</span></h3>
|
||||||
<p>Resets the box-model so that <code>width</code>s and <code>height</code>s are not affected by their <code>border</code>s or <code>padding</code>.</p>
|
<p>Resets the box-model so that <code>width</code>s and <code>height</code>s are not affected by their <code>border</code>s or <code>padding</code>.</p>
|
||||||
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">html {
|
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">html {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -67,7 +91,7 @@
|
|||||||
box-sizing: inherit;
|
box-sizing: inherit;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__box-sizing-reset">Demo</div>
|
<div class="snippet-demo__box-sizing-reset">Demo</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,12 +106,12 @@
|
|||||||
border: 5px solid;
|
border: 5px solid;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>box-sizing: border-box</code> makes the addition of <code>padding</code> or <code>border</code>s not affect an element's <code>width</code> or <code>height</code>.</li>
|
<li><code>box-sizing: border-box</code> makes the addition of <code>padding</code> or <code>border</code>s not affect an element's <code>width</code> or <code>height</code>.</li>
|
||||||
<li><code>box-sizing: inherit</code> makes an element respect its parent's <code>box-sizing</code> rule.</li>
|
<li><code>box-sizing: inherit</code> makes an element respect its parent's <code>box-sizing</code> rule.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
98.2%
|
98.2%
|
||||||
@ -99,11 +123,13 @@
|
|||||||
<a href="https://caniuse.com/#feat=css3-boxsizing" target="_blank">https://caniuse.com/#feat=css3-boxsizing</a>
|
<a href="https://caniuse.com/#feat=css3-boxsizing" target="_blank">https://caniuse.com/#feat=css3-boxsizing</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="clearfix">Clearfix</h3>
|
<h3 id="clearfix"><span>Clearfix</span><span class="tags__tag snippet__tag" data-type="layout"><i data-feather="layout"></i>layout</span></h3>
|
||||||
<p>Ensures that an element self-clears its children.</p>
|
<p>Ensures that an element self-clears its children.</p>
|
||||||
<h6 data-type="Note: This is only useful if you are still using float to build layouts. Please consider using a modern approach with flexbox layout or grid layout.">Note: This is only useful if you are still using float to build layouts. Please consider using a modern approach with flexbox layout or grid layout.</h6>
|
<h6>Note: This is only useful if you are still using float to build layouts. Please consider using a modern approach with flexbox layout or grid layout.</h6>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="clearfix">
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="clearfix">
|
||||||
<div class="floated">float a</div>
|
<div class="floated">float a</div>
|
||||||
<div class="floated">float b</div>
|
<div class="floated">float b</div>
|
||||||
@ -111,7 +137,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">.clearfix::after {
|
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">.clearfix::after {
|
||||||
content: "";
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
@ -119,7 +145,7 @@
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__clearfix">
|
<div class="snippet-demo__clearfix">
|
||||||
<div class="snippet-demo__floated">float a</div>
|
<div class="snippet-demo__floated">float a</div>
|
||||||
@ -137,22 +163,24 @@
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>.clearfix::after</code> defines a pseudo-element.</li>
|
<li><code>.clearfix::after</code> defines a pseudo-element.</li>
|
||||||
<li><code>content: ''</code> allows the pseudo-element to affect layout.</li>
|
<li><code>content: ''</code> allows the pseudo-element to affect layout.</li>
|
||||||
<li><code>clear: both</code> indicates that the left, right or both sides of the element cannot be adjacent to earlier floated elements within the same block formatting context.</li>
|
<li><code>clear: both</code> indicates that the left, right or both sides of the element cannot be adjacent to earlier floated elements within the same block formatting context.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
99+%
|
99+%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="constant-width-to-height-ratio">Constant width to height ratio</h3>
|
<h3 id="constant-width-to-height-ratio"><span>Constant width to height ratio</span><span class="tags__tag snippet__tag" data-type="layout"><i data-feather="layout"></i>layout</span></h3>
|
||||||
<p>Given an element of variable width, it will ensure its height remains proportionate in a responsive fashion (i.e., its width to height ratio remains constant).</p>
|
<p>Given an element of variable width, it will ensure its height remains proportionate in a responsive fashion (i.e., its width to height ratio remains constant).</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="constant-width-to-height-ratio"></div>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="constant-width-to-height-ratio"></div>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -162,7 +190,7 @@
|
|||||||
padding-top: 50%;
|
padding-top: 50%;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<p>Resize your browser window to see the proportion of the element remain the same.</p>
|
<p>Resize your browser window to see the proportion of the element remain the same.</p>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__constant-width-to-height-ratio"></div>
|
<div class="snippet-demo__constant-width-to-height-ratio"></div>
|
||||||
@ -174,19 +202,21 @@
|
|||||||
padding-top: 50%;
|
padding-top: 50%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p><code>padding-top</code> and <code>padding-bottom</code> can be used as an alternative to <code>height</code> such that the percentage value causes an element's height to become a percentage of its parent's width, i.e. <code>50%</code> means
|
<p><code>padding-top</code> and <code>padding-bottom</code> can be used as an alternative to <code>height</code> such that the percentage value causes an element's height to become a percentage of its parent's width, i.e. <code>50%</code> means
|
||||||
the height will be 50% of the parent element's width, which means it acts the same as <code>width</code>. This allows its proportion to remain constant.</p>
|
the height will be 50% of the parent element's width, which means it acts the same as <code>width</code>. This allows its proportion to remain constant.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
99+%
|
99+%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p><span class="snippet__support-note">⚠️ <code>padding-top</code> pushes any content within the element to the bottom.</span></p>
|
<p><span class="snippet__support-note">⚠️ <code>padding-top</code> pushes any content within the element to the bottom.</span></p>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="custom-scrollbar">Custom scrollbar</h3>
|
<h3 id="custom-scrollbar"><span>Custom scrollbar</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Customizes the scrollbar style for the document and elements with scrollable overflow, on WebKit platforms.</p>
|
<p>Customizes the scrollbar style for the document and elements with scrollable overflow, on WebKit platforms.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="custom-scrollbar">
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="custom-scrollbar">
|
||||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure id exercitationem nulla qui repellat laborum vitae, molestias tempora velit natus. Quas, assumenda nisi. Quisquam enim qui iure, consequatur velit sit?</p>
|
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure id exercitationem nulla qui repellat laborum vitae, molestias tempora velit natus. Quas, assumenda nisi. Quisquam enim qui iure, consequatur velit sit?</p>
|
||||||
@ -197,18 +227,18 @@
|
|||||||
width: 8px;
|
width: 8px;
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
|
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
/* Scrollable element */
|
/* Scrollable element */
|
||||||
.some-element::webkit-scrollbar {
|
.some-element::webkit-scrollbar {
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__custom-scrollbar">
|
<div class="snippet-demo__custom-scrollbar">
|
||||||
<p>
|
<p>
|
||||||
@ -236,7 +266,7 @@
|
|||||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
|
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>::-webkit-scrollbar</code> targets the whole scrollbar element.</li>
|
<li><code>::-webkit-scrollbar</code> targets the whole scrollbar element.</li>
|
||||||
<li><code>::-webkit-scrollbar-track</code> targets only the scrollbar track.</li>
|
<li><code>::-webkit-scrollbar-track</code> targets only the scrollbar track.</li>
|
||||||
@ -245,7 +275,7 @@
|
|||||||
<p>There are many other pseudo-elements that you can use to style scrollbars. For more info, visit the
|
<p>There are many other pseudo-elements that you can use to style scrollbars. For more info, visit the
|
||||||
<a href="https://webkit.org/blog/363/styling-scrollbars/" target="_blank">WebKit Blog</a>
|
<a href="https://webkit.org/blog/363/styling-scrollbars/" target="_blank">WebKit Blog</a>
|
||||||
</p>
|
</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
87.3%
|
87.3%
|
||||||
@ -257,9 +287,11 @@
|
|||||||
<a href="https://caniuse.com/#feat=css-scrollbar" target="_blank">https://caniuse.com/#feat=css-scrollbar</a>
|
<a href="https://caniuse.com/#feat=css-scrollbar" target="_blank">https://caniuse.com/#feat=css-scrollbar</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="custom-text-selection">Custom text selection</h3>
|
<h3 id="custom-text-selection"><span>Custom text selection</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Changes the styling of text selection.</p>
|
<p>Changes the styling of text selection.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="custom-text-selection">Select some of this text.</p>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="custom-text-selection">Select some of this text.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -272,7 +304,7 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__custom-text-selection">Select some of this text.</p>
|
<p class="snippet-demo__custom-text-selection">Select some of this text.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -286,9 +318,9 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p><code>::selection</code> defines a pseudo selector on an element to style text within it when selected. Note that if you don't combine any other selector your style will be applied at document root level, to any selectable element.</p>
|
<p><code>::selection</code> defines a pseudo selector on an element to style text within it when selected. Note that if you don't combine any other selector your style will be applied at document root level, to any selectable element.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
84.6%
|
84.6%
|
||||||
@ -301,9 +333,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=css-selection" target="_blank">https://caniuse.com/#feat=css-selection</a>
|
<a href="https://caniuse.com/#feat=css-selection" target="_blank">https://caniuse.com/#feat=css-selection</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="disable-selection">Disable selection</h3>
|
<h3 id="disable-selection"><span>Disable selection</span><span class="tags__tag snippet__tag" data-type="interactivity"><i data-feather="edit-2"></i>interactivity</span></h3>
|
||||||
<p>Makes the content unselectable.</p>
|
<p>Makes the content unselectable.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p>You can select me.</p>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p>You can select me.</p>
|
||||||
<p class="unselectable">You can't select me!</p>
|
<p class="unselectable">You can't select me!</p>
|
||||||
@ -312,7 +346,7 @@ in any specification.</span></p>
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p>You can select me.</p>
|
<p>You can select me.</p>
|
||||||
<p class="snippet-demo__disable-selection">You can't select me!</p>
|
<p class="snippet-demo__disable-selection">You can't select me!</p>
|
||||||
@ -322,9 +356,9 @@ in any specification.</span></p>
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p><code>user-select: none</code> specifies that the text cannot be selected.</p>
|
<p><code>user-select: none</code> specifies that the text cannot be selected.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
86.3%
|
86.3%
|
||||||
@ -336,15 +370,21 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=user-select-none" target="_blank">https://caniuse.com/#feat=user-select-none</a>
|
<a href="https://caniuse.com/#feat=user-select-none" target="_blank">https://caniuse.com/#feat=user-select-none</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: interactivity -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="donut-spinner">Donut spinner</h3>
|
<h3 id="donut-spinner"><span>Donut spinner</span><span class="tags__tag snippet__tag" data-type="animation"><i data-feather="loader"></i>animation</span></h3>
|
||||||
<p>Creates a donut spinner that can be used to indicate the loading of content.</p>
|
<p>Creates a donut spinner that can be used to indicate the loading of content.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="donut"></div>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="donut"></div>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">@keyframes donut-spin {
|
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">@keyframes donut-spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% {
|
||||||
100% { transform: rotate(360deg); }
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.donut {
|
.donut {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -356,7 +396,7 @@ in any specification.</span></p>
|
|||||||
animation: donut-spin 1.2s linear infinite;
|
animation: donut-spin 1.2s linear infinite;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__donut-spinner"></div>
|
<div class="snippet-demo__donut-spinner"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -379,9 +419,9 @@ in any specification.</span></p>
|
|||||||
animation: snippet-demo__donut-spin 1.2s linear infinite;
|
animation: snippet-demo__donut-spin 1.2s linear infinite;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p>Use a semi-transparent <code>border</code> for the whole element, except one side that will serve as the loading indicator for the donut. Use <code>animation</code> to rotate the element.</p>
|
<p>Use a semi-transparent <code>border</code> for the whole element, except one side that will serve as the loading indicator for the donut. Use <code>animation</code> to rotate the element.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
94.8%
|
94.8%
|
||||||
@ -396,9 +436,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=transforms2d" target="_blank">https://caniuse.com/#feat=transforms2d</a>
|
<a href="https://caniuse.com/#feat=transforms2d" target="_blank">https://caniuse.com/#feat=transforms2d</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: animation -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="easing-variables">Easing variables</h3>
|
<h3 id="easing-variables"><span>Easing variables</span><span class="tags__tag snippet__tag" data-type="animation"><i data-feather="loader"></i>animation</span></h3>
|
||||||
<p>Variables that can be reused for <code>transition-timing-function</code> properties, more powerful than the built-in <code>ease</code>, <code>ease-in</code>, <code>ease-out</code> and <code>ease-in-out</code>.</p>
|
<p>Variables that can be reused for <code>transition-timing-function</code> properties, more powerful than the built-in <code>ease</code>, <code>ease-in</code>, <code>ease-out</code> and <code>ease-in-out</code>.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="easing-variables"></div>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="easing-variables"></div>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -432,7 +474,7 @@ in any specification.</span></p>
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__easing-variables">Hover</div>
|
<div class="snippet-demo__easing-variables">Hover</div>
|
||||||
</div>
|
</div>
|
||||||
@ -473,10 +515,10 @@ in any specification.</span></p>
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p>The variables are defined globally within the <code>:root</code> CSS pseudo-class which matches the root element of a tree representing the document. In HTML, <code>:root</code> represents the <code><html></code> element and is identical
|
<p>The variables are defined globally within the <code>:root</code> CSS pseudo-class which matches the root element of a tree representing the document. In HTML, <code>:root</code> represents the <code><html></code> element and is identical
|
||||||
to the selector <code>html</code>, except that its specificity is higher.</p>
|
to the selector <code>html</code>, except that its specificity is higher.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
87.2%
|
87.2%
|
||||||
@ -488,9 +530,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=css-variables" target="_blank">https://caniuse.com/#feat=css-variables</a>
|
<a href="https://caniuse.com/#feat=css-variables" target="_blank">https://caniuse.com/#feat=css-variables</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: animation -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="etched-text">Etched text</h3>
|
<h3 id="etched-text"><span>Etched text</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Creates an effect where text appears to be "etched" or engraved into the background.</p>
|
<p>Creates an effect where text appears to be "etched" or engraved into the background.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="etched-text">I appear etched into the background.</p>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="etched-text">I appear etched into the background.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -501,7 +545,7 @@ in any specification.</span></p>
|
|||||||
color: #b8bec5;
|
color: #b8bec5;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__etched-text">I appear etched into the background.</p>
|
<p class="snippet-demo__etched-text">I appear etched into the background.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -513,11 +557,11 @@ in any specification.</span></p>
|
|||||||
text-shadow: 0 2px 0 white;
|
text-shadow: 0 2px 0 white;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p><code>text-shadow: 0 2px white</code> creates a white shadow offset <code>0px</code> horizontally and <code>2px</code> vertically from the origin position.</p>
|
<p><code>text-shadow: 0 2px white</code> creates a white shadow offset <code>0px</code> horizontally and <code>2px</code> vertically from the origin position.</p>
|
||||||
<p>The background must be darker than the shadow for the effect to work.</p>
|
<p>The background must be darker than the shadow for the effect to work.</p>
|
||||||
<p>The text color should be slightly faded to make it look like it's engraved/carved out of the background.</p>
|
<p>The text color should be slightly faded to make it look like it's engraved/carved out of the background.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
97.9%
|
97.9%
|
||||||
@ -529,9 +573,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=css-textshadow" target="_blank">https://caniuse.com/#feat=css-textshadow</a>
|
<a href="https://caniuse.com/#feat=css-textshadow" target="_blank">https://caniuse.com/#feat=css-textshadow</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="evenly-distributed-children">Evenly distributed children</h3>
|
<h3 id="evenly-distributed-children"><span>Evenly distributed children</span><span class="tags__tag snippet__tag" data-type="layout"><i data-feather="layout"></i>layout</span></h3>
|
||||||
<p>Evenly distributes child elements within a parent element.</p>
|
<p>Evenly distributes child elements within a parent element.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="evenly-distributed-children">
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="evenly-distributed-children">
|
||||||
<p>Item1</p>
|
<p>Item1</p>
|
||||||
@ -544,7 +590,7 @@ in any specification.</span></p>
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__evenly-distributed-children">
|
<div class="snippet-demo__evenly-distributed-children">
|
||||||
<p>Item1</p>
|
<p>Item1</p>
|
||||||
@ -559,13 +605,13 @@ in any specification.</span></p>
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>display: flex</code> enables flexbox.</li>
|
<li><code>display: flex</code> enables flexbox.</li>
|
||||||
<li><code>justify-content: space-between</code> evenly distributes child elements horizontally. The first item is positioned at the left edge, while the last item is positioned at the right edge.</li>
|
<li><code>justify-content: space-between</code> evenly distributes child elements horizontally. The first item is positioned at the left edge, while the last item is positioned at the right edge.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p>Alternatively, use <code>justify-content: space-around</code> to distribute the children with space around them, rather than between them.</p>
|
<p>Alternatively, use <code>justify-content: space-around</code> to distribute the children with space around them, rather than between them.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
97.8%
|
97.8%
|
||||||
@ -577,9 +623,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=flexbox" target="_blank">https://caniuse.com/#feat=flexbox</a>
|
<a href="https://caniuse.com/#feat=flexbox" target="_blank">https://caniuse.com/#feat=flexbox</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="gradient-text">Gradient text</h3>
|
<h3 id="gradient-text"><span>Gradient text</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Gives text a gradient color.</p>
|
<p>Gives text a gradient color.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="gradient-text">Gradient text</p>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="gradient-text">Gradient text</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -589,7 +637,7 @@ in any specification.</span></p>
|
|||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__gradient-text">
|
<p class="snippet-demo__gradient-text">
|
||||||
Gradient text
|
Gradient text
|
||||||
@ -605,13 +653,13 @@ in any specification.</span></p>
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>background: -webkit-linear-gradient(...)</code> gives the text element a gradient background.</li>
|
<li><code>background: -webkit-linear-gradient(...)</code> gives the text element a gradient background.</li>
|
||||||
<li><code>webkit-text-fill-color: transparent</code> fills the text with a transparent color.</li>
|
<li><code>webkit-text-fill-color: transparent</code> fills the text with a transparent color.</li>
|
||||||
<li><code>webkit-background-clip: text</code> clips the background with the text, filling the text with the gradient background as the color.</li>
|
<li><code>webkit-background-clip: text</code> clips the background with the text, filling the text with the gradient background as the color.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
90.7%
|
90.7%
|
||||||
@ -623,9 +671,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=text-stroke" target="_blank">https://caniuse.com/#feat=text-stroke</a>
|
<a href="https://caniuse.com/#feat=text-stroke" target="_blank">https://caniuse.com/#feat=text-stroke</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="hairline-border">Hairline border</h3>
|
<h3 id="hairline-border"><span>Hairline border</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Gives an element a border equal to 1 native device pixel in width, which can look very sharp and crisp.</p>
|
<p>Gives an element a border equal to 1 native device pixel in width, which can look very sharp and crisp.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="hairline-border">text</div>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="hairline-border">text</div>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -648,7 +698,7 @@ in any specification.</span></p>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__hairline-border">Text with a hairline border around it.</p>
|
<p class="snippet-demo__hairline-border">Text with a hairline border around it.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -672,12 +722,12 @@ in any specification.</span></p>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>box-shadow</code>, when only using spread, adds a pseudo-border which can use subpixels*.</li>
|
<li><code>box-shadow</code>, when only using spread, adds a pseudo-border which can use subpixels*.</li>
|
||||||
<li>Use <code>@media (min-resolution: ...)</code> to check the device pixel ratio (<code>1dppx</code> equals 96 DPI), setting the spread of the <code>box-shadow</code> equal to <code>1 / dppx</code>.</li>
|
<li>Use <code>@media (min-resolution: ...)</code> to check the device pixel ratio (<code>1dppx</code> equals 96 DPI), setting the spread of the <code>box-shadow</code> equal to <code>1 / dppx</code>.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser Support">Browser Support</h4>
|
<h4>Browser Support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
95.0%
|
95.0%
|
||||||
@ -694,9 +744,11 @@ in any specification.</span></p>
|
|||||||
</ul>
|
</ul>
|
||||||
<hr>
|
<hr>
|
||||||
<p>*Chrome does not support subpixel values on <code>border</code>. Safari does not support subpixel values on <code>box-shadow</code>. Firefox supports subpixel values on both.</p>
|
<p>*Chrome does not support subpixel values on <code>border</code>. Safari does not support subpixel values on <code>box-shadow</code>. Firefox supports subpixel values on both.</p>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="horizontal-and-vertical-centering">Horizontal and vertical centering</h3>
|
<h3 id="horizontal-and-vertical-centering"><span>Horizontal and vertical centering</span><span class="tags__tag snippet__tag" data-type="layout"><i data-feather="layout"></i>layout</span></h3>
|
||||||
<p>Horizontally and vertically centers a child element within a parent element.</p>
|
<p>Horizontally and vertically centers a child element within a parent element.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="horizontal-and-vertical-centering">
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="horizontal-and-vertical-centering">
|
||||||
<div class="child"></div>
|
<div class="child"></div>
|
||||||
@ -708,7 +760,7 @@ in any specification.</span></p>
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__horizontal-and-vertical-centering">
|
<div class="snippet-demo__horizontal-and-vertical-centering">
|
||||||
<p class="snippet-demo__horizontal-and-vertical-centering__child">Centered content.</p>
|
<p class="snippet-demo__horizontal-and-vertical-centering__child">Centered content.</p>
|
||||||
@ -722,13 +774,13 @@ in any specification.</span></p>
|
|||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>display: flex</code> enables flexbox.</li>
|
<li><code>display: flex</code> enables flexbox.</li>
|
||||||
<li><code>justify-content: center</code> centers the child horizontally.</li>
|
<li><code>justify-content: center</code> centers the child horizontally.</li>
|
||||||
<li><code>align-items: center</code> centers the child vertically.</li>
|
<li><code>align-items: center</code> centers the child vertically.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
97.8%
|
97.8%
|
||||||
@ -740,9 +792,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=flexbox" target="_blank">https://caniuse.com/#feat=flexbox</a>
|
<a href="https://caniuse.com/#feat=flexbox" target="_blank">https://caniuse.com/#feat=flexbox</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="hover-underline-animation">Hover underline animation</h3>
|
<h3 id="hover-underline-animation"><span>Hover underline animation</span><span class="tags__tag snippet__tag" data-type="animation"><i data-feather="loader"></i>animation</span></h3>
|
||||||
<p>Creates an animated underline effect when the text is hovered over.</p>
|
<p>Creates an animated underline effect when the text is hovered over.</p>
|
||||||
<p>
|
<p>
|
||||||
<small><strong>Credit:</strong>
|
<small><strong>Credit:</strong>
|
||||||
@ -773,7 +827,7 @@ in any specification.</span></p>
|
|||||||
transform-origin: bottom left;
|
transform-origin: bottom left;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__hover-underline-animation">Hover this text to see the effect!</p>
|
<p class="snippet-demo__hover-underline-animation">Hover this text to see the effect!</p>
|
||||||
</div>
|
</div>
|
||||||
@ -800,7 +854,7 @@ in any specification.</span></p>
|
|||||||
transform-origin: bottom left;
|
transform-origin: bottom left;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>display: inline-block</code> makes the block <code>p</code> an <code>inline-block</code> to prevent the underline from spanning the entire parent width rather than just the content (text).</li>
|
<li><code>display: inline-block</code> makes the block <code>p</code> an <code>inline-block</code> to prevent the underline from spanning the entire parent width rather than just the content (text).</li>
|
||||||
<li><code>position: relative</code> on the element establishes a Cartesian positioning context for pseudo-elements.</li>
|
<li><code>position: relative</code> on the element establishes a Cartesian positioning context for pseudo-elements.</li>
|
||||||
@ -814,7 +868,7 @@ in any specification.</span></p>
|
|||||||
<li><code>:hover::after</code> then uses <code>scaleX(1)</code> to transition the width to 100%, then changes the <code>transform-origin</code> to <code>bottom left</code> so that the anchor point is reversed, allowing it transition out in the
|
<li><code>:hover::after</code> then uses <code>scaleX(1)</code> to transition the width to 100%, then changes the <code>transform-origin</code> to <code>bottom left</code> so that the anchor point is reversed, allowing it transition out in the
|
||||||
other direction when hovered off.</li>
|
other direction when hovered off.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
94.9%
|
94.9%
|
||||||
@ -829,9 +883,11 @@ in any specification.</span></p>
|
|||||||
<a href="https://caniuse.com/#feat=css-transitions" target="_blank">https://caniuse.com/#feat=css-transitions</a>
|
<a href="https://caniuse.com/#feat=css-transitions" target="_blank">https://caniuse.com/#feat=css-transitions</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: animation -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="mouse-cursor-gradient-tracking">Mouse cursor gradient tracking</h3>
|
<h3 id="mouse-cursor-gradient-tracking"><span>Mouse cursor gradient tracking</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span><span class="tags__tag snippet__tag" data-type="interactivity"><i data-feather="edit-2"></i>interactivity</span></h3>
|
||||||
<p>A hover effect where the gradient follows the mouse cursor.</p>
|
<p>A hover effect where the gradient follows the mouse cursor.</p>
|
||||||
<p>
|
<p>
|
||||||
<small class="snippet__credit"><strong>Credit:</strong>
|
<small class="snippet__credit"><strong>Credit:</strong>
|
||||||
@ -866,21 +922,21 @@ in any specification.</span></p>
|
|||||||
height: var(--size);
|
height: var(--size);
|
||||||
background: radial-gradient(circle closest-side, pink, transparent);
|
background: radial-gradient(circle closest-side, pink, transparent);
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
transition: width .2s ease, height .2s ease;
|
transition: width 0.2s ease, height 0.2s ease;
|
||||||
}
|
}
|
||||||
.mouse-cursor-gradient-tracking:hover::before {
|
.mouse-cursor-gradient-tracking:hover::before {
|
||||||
--size: 200px;
|
--size: 200px;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="JavaScript">JavaScript</h4><pre><code class="lang-js">var btn = document.querySelector('.mouse-cursor-gradient-tracking')
|
<h4 data-type="JavaScript">JavaScript</h4><pre><code class="lang-js">var btn = document.querySelector('.mouse-cursor-gradient-tracking')
|
||||||
btn.onmousemove = function (e) {
|
btn.onmousemove = function(e) {
|
||||||
var x = e.pageX - btn.offsetLeft
|
var x = e.pageX - btn.offsetLeft
|
||||||
var y = e.pageY - btn.offsetTop
|
var y = e.pageY - btn.offsetTop
|
||||||
btn.style.setProperty('--x', x + 'px')
|
btn.style.setProperty('--x', x + 'px')
|
||||||
btn.style.setProperty('--y', y + 'px')
|
btn.style.setProperty('--y', y + 'px')
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<button class="snippet-demo__mouse-cursor-gradient-tracking">
|
<button class="snippet-demo__mouse-cursor-gradient-tracking">
|
||||||
<span>Hover me</span>
|
<span>Hover me</span>
|
||||||
@ -928,14 +984,14 @@ btn.onmousemove = function (e) {
|
|||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
</script>
|
</script>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p><em>TODO</em></p>
|
<p><em>TODO</em></p>
|
||||||
<p><strong>Note!</strong></p>
|
<p><strong>Note!</strong></p>
|
||||||
<p>If the element's parent has a positioning context (<code>position: relative</code>), you will need to subtract its offsets as well.</p>
|
<p>If the element's parent has a positioning context (<code>position: relative</code>), you will need to subtract its offsets as well.</p>
|
||||||
<pre><code class="lang-js">var x = e.pageX - btn.offsetLeft - btn.offsetParent.offsetLeft
|
<pre><code class="lang-js">var x = e.pageX - btn.offsetLeft - btn.offsetParent.offsetLeft
|
||||||
var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
87.2%
|
87.2%
|
||||||
@ -950,9 +1006,11 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<a href="https://caniuse.com/#feat=css-variables" target="_blank">https://caniuse.com/#feat=css-variables</a>
|
<a href="https://caniuse.com/#feat=css-variables" target="_blank">https://caniuse.com/#feat=css-variables</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual, interactivity -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="overflow-scroll-gradient">Overflow scroll gradient</h3>
|
<h3 id="overflow-scroll-gradient"><span>Overflow scroll gradient</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Adds a fading gradient to an overflowing element to better indicate there is more content to be scrolled.</p>
|
<p>Adds a fading gradient to an overflowing element to better indicate there is more content to be scrolled.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="overflow-scroll-gradient">
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="overflow-scroll-gradient">
|
||||||
<div class="overflow-scroll-gradient__scroller">
|
<div class="overflow-scroll-gradient__scroller">
|
||||||
@ -969,7 +1027,10 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
background: linear-gradient(rgba(255, 255, 255, 0.001), white); /* transparent keyword is broken in Safari */
|
background: linear-gradient(
|
||||||
|
rgba(255, 255, 255, 0.001),
|
||||||
|
white
|
||||||
|
); /* transparent keyword is broken in Safari */
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.overflow-scroll-gradient__scroller {
|
.overflow-scroll-gradient__scroller {
|
||||||
@ -982,7 +1043,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__overflow-scroll-gradient">
|
<div class="snippet-demo__overflow-scroll-gradient">
|
||||||
<div class="snippet-demo__overflow-scroll-gradient__scroller">
|
<div class="snippet-demo__overflow-scroll-gradient__scroller">
|
||||||
@ -1016,7 +1077,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<script>
|
<script>
|
||||||
document.querySelector('.snippet-demo__overflow-scroll-gradient__scroller').innerHTML = 'content '.repeat(200)
|
document.querySelector('.snippet-demo__overflow-scroll-gradient__scroller').innerHTML = 'content '.repeat(200)
|
||||||
</script>
|
</script>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>position: relative</code> on the parent establishes a Cartesian positioning context for pseudo-elements.</li>
|
<li><code>position: relative</code> on the parent establishes a Cartesian positioning context for pseudo-elements.</li>
|
||||||
<li><code>::after</code> defines a pseudo element.</li>
|
<li><code>::after</code> defines a pseudo element.</li>
|
||||||
@ -1027,7 +1088,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<li><code>bottom: 0</code> positions the pseudo-element at the bottom of the parent.</li>
|
<li><code>bottom: 0</code> positions the pseudo-element at the bottom of the parent.</li>
|
||||||
<li><code>pointer-events: none</code> specifies that the pseudo-element cannot be a target of mouse events, allowing text behind it to still be selectable/interactive.</li>
|
<li><code>pointer-events: none</code> specifies that the pseudo-element cannot be a target of mouse events, allowing text behind it to still be selectable/interactive.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
94.8%
|
94.8%
|
||||||
@ -1039,9 +1100,11 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<a href="https://caniuse.com/#feat=css-gradients" target="_blank">https://caniuse.com/#feat=css-gradients</a>
|
<a href="https://caniuse.com/#feat=css-gradients" target="_blank">https://caniuse.com/#feat=css-gradients</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="popout-menu">Popout menu</h3>
|
<h3 id="popout-menu"><span>Popout menu</span><span class="tags__tag snippet__tag" data-type="interactivity"><i data-feather="edit-2"></i>interactivity</span></h3>
|
||||||
<p>Reveals an interactive popout menu on hover.</p>
|
<p>Reveals an interactive popout menu on hover.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="reference">
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="reference">
|
||||||
<div class="popout-menu">
|
<div class="popout-menu">
|
||||||
@ -1061,7 +1124,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__reference">
|
<div class="snippet-demo__reference">
|
||||||
<div class="snippet-demo__popout-menu">
|
<div class="snippet-demo__popout-menu">
|
||||||
@ -1092,7 +1155,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>position: relative</code> on the reference parent establishes a Cartesian positioning context for its child.</li>
|
<li><code>position: relative</code> on the reference parent establishes a Cartesian positioning context for its child.</li>
|
||||||
<li><code>position: absolute</code> takes the popout menu out of the flow of the document and positions it in relation to the parent.</li>
|
<li><code>position: absolute</code> takes the popout menu out of the flow of the document and positions it in relation to the parent.</li>
|
||||||
@ -1101,16 +1164,18 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<li><code>.reference:hover > .popout-menu</code> means that when <code>.reference</code> is hovered over, select immediate children with a class of <code>.popout-menu</code> and change their <code>visibility</code> to <code>visible</code>,
|
<li><code>.reference:hover > .popout-menu</code> means that when <code>.reference</code> is hovered over, select immediate children with a class of <code>.popout-menu</code> and change their <code>visibility</code> to <code>visible</code>,
|
||||||
which shows the popout.</li>
|
which shows the popout.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
99+%
|
99+%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
||||||
|
|
||||||
|
<!-- tags: interactivity -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="pretty-text-underline">Pretty text underline</h3>
|
<h3 id="pretty-text-underline"><span>Pretty text underline</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>A nicer alternative to <code>text-decoration: underline</code> where descenders do not clip the underline. Natively implemented as <code>text-decoration-skip-ink: auto</code> but it has less control over the underline.</p>
|
<p>A nicer alternative to <code>text-decoration: underline</code> where descenders do not clip the underline. Natively implemented as <code>text-decoration-skip-ink: auto</code> but it has less control over the underline.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="pretty-text-underline">Pretty text underline without clipping descending letters.</p>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="pretty-text-underline">Pretty text underline without clipping descending letters.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -1118,10 +1183,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
display: inline;
|
display: inline;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
text-shadow: 1px 1px 0 #f5f6f9,
|
text-shadow: 1px 1px 0 #f5f6f9, -1px 1px 0 #f5f6f9, -1px -1px 0 #f5f6f9, 1px -1px 0 #f5f6f9;
|
||||||
-1px 1px 0 #f5f6f9,
|
|
||||||
-1px -1px 0 #f5f6f9,
|
|
||||||
1px -1px 0 #f5f6f9;
|
|
||||||
background-image: linear-gradient(90deg, currentColor 100%, transparent 100%);
|
background-image: linear-gradient(90deg, currentColor 100%, transparent 100%);
|
||||||
background-position: 0 0.98em;
|
background-position: 0 0.98em;
|
||||||
background-repeat: repeat-x;
|
background-repeat: repeat-x;
|
||||||
@ -1136,7 +1198,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__pretty-text-underline">Pretty text underline without clipping descending letters.</p>
|
<p class="snippet-demo__pretty-text-underline">Pretty text underline without clipping descending letters.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -1160,7 +1222,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>text-shadow: ...</code> has 4 values with offsets that cover a 4x4 px area to ensure the underline has a "thick" shadow that covers the line where descenders clip it. Use a color that matches the background. For a larger font, use
|
<li><code>text-shadow: ...</code> has 4 values with offsets that cover a 4x4 px area to ensure the underline has a "thick" shadow that covers the line where descenders clip it. Use a color that matches the background. For a larger font, use
|
||||||
a larger <code>px</code> size.</li>
|
a larger <code>px</code> size.</li>
|
||||||
@ -1169,7 +1231,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<li>The <code>::selection</code> pseudo selector ensures the text shadow does not interfere with text selection.
|
<li>The <code>::selection</code> pseudo selector ensures the text shadow does not interfere with text selection.
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
94.8%
|
94.8%
|
||||||
@ -1184,9 +1246,11 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<a href="https://caniuse.com/#feat=css-gradients" target="_blank">https://caniuse.com/#feat=css-gradients</a>
|
<a href="https://caniuse.com/#feat=css-gradients" target="_blank">https://caniuse.com/#feat=css-gradients</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="shape-separator">Shape separator</h3>
|
<h3 id="shape-separator"><span>Shape separator</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Uses an SVG shape to separate two different blocks to create more a interesting visual appearance compared to standard horizontal separation.</p>
|
<p>Uses an SVG shape to separate two different blocks to create more a interesting visual appearance compared to standard horizontal separation.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="shape-separator"></div>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="shape-separator"></div>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -1203,7 +1267,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo is-distinct">
|
<div class="snippet-demo is-distinct">
|
||||||
<div class="snippet-demo__shape-separator"></div>
|
<div class="snippet-demo__shape-separator"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -1222,7 +1286,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>position: relative</code> on the element establishes a Cartesian positioning context for pseudo elements.</li>
|
<li><code>position: relative</code> on the element establishes a Cartesian positioning context for pseudo elements.</li>
|
||||||
<li><code>::after</code> defines a pseudo element.</li>
|
<li><code>::after</code> defines a pseudo element.</li>
|
||||||
@ -1233,7 +1297,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<li><code>height: 24px</code> is the same height as the shape.</li>
|
<li><code>height: 24px</code> is the same height as the shape.</li>
|
||||||
<li><code>bottom: 0</code> positions the pseudo element at the bottom of the parent.</li>
|
<li><code>bottom: 0</code> positions the pseudo element at the bottom of the parent.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
98.0%
|
98.0%
|
||||||
@ -1245,17 +1309,20 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<a href="https://caniuse.com/#feat=svg" target="_blank">https://caniuse.com/#feat=svg</a>
|
<a href="https://caniuse.com/#feat=svg" target="_blank">https://caniuse.com/#feat=svg</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="system-font-stack">System font stack</h3>
|
<h3 id="system-font-stack"><span>System font stack</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Uses the native font of the operating system to get close to a native app feel.</p>
|
<p>Uses the native font of the operating system to get close to a native app feel.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="system-font-stack">This text uses the system font.</p>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="system-font-stack">This text uses the system font.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">.system-font-stack {
|
<h4 data-type="CSS">CSS</h4><pre><code class="lang-css">.system-font-stack {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu,
|
||||||
|
Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__system-font-stack">This text uses the system font.</p>
|
<p class="snippet-demo__system-font-stack">This text uses the system font.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -1264,7 +1331,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p>The browser looks for each successive font, preferring the first one if possible, and falls back to the next if it cannot find the font (on the system or defined in CSS).</p>
|
<p>The browser looks for each successive font, preferring the first one if possible, and falls back to the next if it cannot find the font (on the system or defined in CSS).</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>-apple-system</code> is San Francisco, used on iOS and macOS (not Chrome however)</li>
|
<li><code>-apple-system</code> is San Francisco, used on iOS and macOS (not Chrome however)</li>
|
||||||
@ -1277,16 +1344,18 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<li><code>Arial</code> is a font widely supported by all operating systems</li>
|
<li><code>Arial</code> is a font widely supported by all operating systems</li>
|
||||||
<li><code>sans-serif</code> is the fallback sans-serif font if none of the other fonts are supported</li>
|
<li><code>sans-serif</code> is the fallback sans-serif font if none of the other fonts are supported</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
99+%
|
99+%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="triangle">Triangle</h3>
|
<h3 id="triangle"><span>Triangle</span><span class="tags__tag snippet__tag" data-type="visual"><i data-feather="eye"></i>visual</span></h3>
|
||||||
<p>Creates a triangle shape with pure CSS.</p>
|
<p>Creates a triangle shape with pure CSS.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="triangle"></div>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><div class="triangle"></div>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -1298,7 +1367,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
border-right: 20px solid transparent;
|
border-right: 20px solid transparent;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<div class="snippet-demo__triangles">
|
<div class="snippet-demo__triangles">
|
||||||
<div class="snippet-demo__triangle snippet-demo__triangle-1"></div>
|
<div class="snippet-demo__triangle snippet-demo__triangle-1"></div>
|
||||||
@ -1345,22 +1414,24 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
border-right: 15px solid transparent;
|
border-right: 15px solid transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<p>
|
<p>
|
||||||
<a href="https://stackoverflow.com/q/7073484" target="_blank">View this link for a detailed explanation.</a>
|
<a href="https://stackoverflow.com/q/7073484" target="_blank">View this link for a detailed explanation.</a>
|
||||||
</p>
|
</p>
|
||||||
<p>The color of the border is the color of the triangle. The side the triangle tip points corresponds to the opposite <code>border-*</code> property. For example, a color on <code>border-top</code> means the arrow points downward.</p>
|
<p>The color of the border is the color of the triangle. The side the triangle tip points corresponds to the opposite <code>border-*</code> property. For example, a color on <code>border-top</code> means the arrow points downward.</p>
|
||||||
<p>Experiment with the <code>px</code> values to change the proportion of the triangle.</p>
|
<p>Experiment with the <code>px</code> values to change the proportion of the triangle.</p>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
99+%
|
99+%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
<p><span class="snippet__support-note">✅ No caveats.</span></p>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
</div>
|
</div>
|
||||||
<div class="snippet">
|
<div class="snippet">
|
||||||
<h3 id="truncate-text">Truncate text</h3>
|
<h3 id="truncate-text"><span>Truncate text</span><span class="tags__tag snippet__tag" data-type="layout"><i data-feather="layout"></i>layout</span></h3>
|
||||||
<p>If the text is longer than one line, it will be truncated and end with an ellipsis <code>…</code>.</p>
|
<p>If the text is longer than one line, it will be truncated and end with an ellipsis <code>…</code>.</p>
|
||||||
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="truncate-text">If I exceed one line's width, I will be truncated.</p>
|
<h4 data-type="HTML">HTML</h4><pre><code class="lang-html"><p class="truncate-text">If I exceed one line's width, I will be truncated.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
@ -1371,7 +1442,7 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h4 data-type="Demo">Demo</h4>
|
<h4>Demo</h4>
|
||||||
<div class="snippet-demo">
|
<div class="snippet-demo">
|
||||||
<p class="snippet-demo__truncate-text">
|
<p class="snippet-demo__truncate-text">
|
||||||
This text will be truncated if it exceeds 200px in width.
|
This text will be truncated if it exceeds 200px in width.
|
||||||
@ -1386,14 +1457,14 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h4 data-type="Explanation">Explanation</h4>
|
<h4>Explanation</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>overflow: hidden</code> prevents the text from overflowing its dimensions (for a block, 100% width and auto height).</li>
|
<li><code>overflow: hidden</code> prevents the text from overflowing its dimensions (for a block, 100% width and auto height).</li>
|
||||||
<li><code>white-space: nowrap</code> prevents the text from exceeding one line in height.</li>
|
<li><code>white-space: nowrap</code> prevents the text from exceeding one line in height.</li>
|
||||||
<li><code>text-overflow: ellipsis</code> makes it so that if the text exceeds its dimensions, it will end with an ellipsis.</li>
|
<li><code>text-overflow: ellipsis</code> makes it so that if the text exceeds its dimensions, it will end with an ellipsis.</li>
|
||||||
<li><code>width: 200px;</code> ensures the element has a dimension, to know when to get ellipsis</li>
|
<li><code>width: 200px;</code> ensures the element has a dimension, to know when to get ellipsis</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h4 data-type="Browser support">Browser support</h4>
|
<h4>Browser support</h4>
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
98.1%
|
98.1%
|
||||||
@ -1405,10 +1476,11 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
<a href="https://caniuse.com/#feat=text-overflow" target="_blank">https://caniuse.com/#feat=text-overflow</a>
|
<a href="https://caniuse.com/#feat=text-overflow" target="_blank">https://caniuse.com/#feat=text-overflow</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<footer class="footer"></footer>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
13
package-lock.json
generated
13
package-lock.json
generated
@ -1934,6 +1934,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"classnames": {
|
||||||
|
"version": "2.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz",
|
||||||
|
"integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0="
|
||||||
|
},
|
||||||
"cli-boxes": {
|
"cli-boxes": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
|
||||||
@ -3107,6 +3112,14 @@
|
|||||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"feather-icons": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/feather-icons/-/feather-icons-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-/dKhEelpOazdN0MtcBZTgqo1tZHn35y40V0sGPi6FzzwNbQ5H6vzTqYWWMeRtKw5JePmog7RthR/PYPA1lYNFA==",
|
||||||
|
"requires": {
|
||||||
|
"classnames": "2.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"filename-regex": {
|
"filename-regex": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
|
||||||
|
|||||||
@ -25,5 +25,8 @@
|
|||||||
"prettier": "^1.10.2",
|
"prettier": "^1.10.2",
|
||||||
"pretty": "^2.0.0",
|
"pretty": "^2.0.0",
|
||||||
"prismjs": "^1.11.0"
|
"prismjs": "^1.11.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"feather-icons": "^4.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
139
scripts/build.js
139
scripts/build.js
@ -2,71 +2,134 @@ const fs = require('fs')
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const marked = require('marked')
|
const marked = require('marked')
|
||||||
const pretty = require('pretty')
|
const pretty = require('pretty')
|
||||||
const { JSDOM } = require('jsdom')
|
|
||||||
const caniuseDb = require('caniuse-db/data.json')
|
const caniuseDb = require('caniuse-db/data.json')
|
||||||
const { toKebabCase, emptyHTML } = require('../utils/utils.js')
|
const { toKebabCase, createElement, template, dom } = require('../utils/utils.js')
|
||||||
|
|
||||||
const renderer = new marked.Renderer()
|
|
||||||
renderer.heading = (text, level) =>
|
|
||||||
level === 3
|
|
||||||
? `<h${level} id="${toKebabCase(text)}">${text}</h${level}>`
|
|
||||||
: `<h${level} data-type="${text}">${text}</h${level}>`
|
|
||||||
renderer.link = (url, _, text) => `<a href="${url}" target="_blank">${text || url}</a>`
|
|
||||||
|
|
||||||
const SNIPPETS_PATH = './snippets'
|
const SNIPPETS_PATH = './snippets'
|
||||||
const SNIPPET_CONTAINER_SELECTOR = '.main > .container'
|
const TAGS = [
|
||||||
|
{
|
||||||
|
name: 'all',
|
||||||
|
icon: 'check'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'layout',
|
||||||
|
icon: 'layout'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'visual',
|
||||||
|
icon: 'eye'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'animation',
|
||||||
|
icon: 'loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'interactivity',
|
||||||
|
icon: 'edit-2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
const createElement = str => {
|
const renderer = new marked.Renderer()
|
||||||
const el = document.createElement('div')
|
renderer.heading = (text, level) => {
|
||||||
el.innerHTML = str
|
if (level === 3) {
|
||||||
return el.firstElementChild
|
return `<h${level} id="${toKebabCase(text)}"><span>${text}</span></h${level}>`
|
||||||
|
} else {
|
||||||
|
return ['HTML', 'CSS', 'JavaScript'].includes(text)
|
||||||
|
? `<h${level} data-type="${text}">${text}</h${level}>`
|
||||||
|
: `<h${level}>${text}</h${level}>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderer.link = (url, _, text) => `<a href="${url}" target="_blank">${text || url}</a>`
|
||||||
|
|
||||||
|
const document = dom('./src/html/index.html')
|
||||||
|
const components = {
|
||||||
|
backToTopButton: dom('./src/html/components/back-to-top-button.html'),
|
||||||
|
sidebar: dom('./src/html/components/sidebar.html'),
|
||||||
|
header: dom('./src/html/components/header.html'),
|
||||||
|
main: dom('./src/html/components/main.html'),
|
||||||
|
tags: dom('./src/html/components/tags.html')
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = markdown => `
|
const snippetContainer = components.main.querySelector('.container')
|
||||||
<div class="snippet">
|
const sidebarLinkContainer = components.sidebar.querySelector('.sidebar__links')
|
||||||
${markdown}
|
TAGS.slice(1).forEach(tag => {
|
||||||
</div>
|
sidebarLinkContainer.append(
|
||||||
`
|
createElement(`
|
||||||
|
<section data-type="${tag.name}" class="sidebar__section">
|
||||||
const document = new JSDOM(fs.readFileSync('./index.html', 'utf8')).window.document
|
<h4 class="sidebar__section-heading">${tag.name}</h4>
|
||||||
const snippetContainer = document.querySelector('.main > .container')
|
</section>
|
||||||
const sidebarLinks = document.querySelector('.sidebar__links')
|
`)
|
||||||
emptyHTML(snippetContainer, sidebarLinks)
|
)
|
||||||
|
})
|
||||||
|
|
||||||
for (const snippetFile of fs.readdirSync(SNIPPETS_PATH)) {
|
for (const snippetFile of fs.readdirSync(SNIPPETS_PATH)) {
|
||||||
const snippetPath = path.join(SNIPPETS_PATH, snippetFile)
|
const snippetPath = path.join(SNIPPETS_PATH, snippetFile)
|
||||||
const snippetData = fs.readFileSync(snippetPath, 'utf8')
|
const snippetData = fs.readFileSync(snippetPath, 'utf8')
|
||||||
const markdown = marked(snippetData, { renderer })
|
const markdown = marked(snippetData, { renderer })
|
||||||
const snippetTemplate = template(markdown)
|
const snippetEl = createElement(`<div class="snippet">${markdown}</div>`)
|
||||||
const el = createElement(snippetTemplate)
|
snippetContainer.append(snippetEl)
|
||||||
snippetContainer.append(el)
|
|
||||||
|
|
||||||
sidebarLinks.append(
|
|
||||||
createElement(
|
|
||||||
`<a class="sidebar__link" href="#${snippetFile.replace('.md', '')}">${
|
|
||||||
el.querySelector('h3').innerHTML
|
|
||||||
}</a>`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
// browser support usage
|
||||||
const featUsageShares = (snippetData.match(/https?:\/\/caniuse\.com\/#feat=.*/g) || []).map(
|
const featUsageShares = (snippetData.match(/https?:\/\/caniuse\.com\/#feat=.*/g) || []).map(
|
||||||
feat => {
|
feat => {
|
||||||
const featData = caniuseDb.data[feat.match(/#feat=(.*)/)[1]]
|
const featData = caniuseDb.data[feat.match(/#feat=(.*)/)[1]]
|
||||||
return featData ? Number(featData.usage_perc_y + featData.usage_perc_a) : 100
|
return featData ? Number(featData.usage_perc_y + featData.usage_perc_a) : 100
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
const browserSupportHeading = snippetEl.querySelector('h4:last-of-type')
|
||||||
el.querySelector('h4:last-of-type').after(
|
browserSupportHeading.after(
|
||||||
createElement(`
|
createElement(`
|
||||||
<div>
|
<div>
|
||||||
<div class="snippet__browser-support">
|
<div class="snippet__browser-support">
|
||||||
${featUsageShares.length ? Math.min(...featUsageShares).toPrecision(3) : '99+'}%
|
${featUsageShares.length ? Math.min(...featUsageShares).toPrecision(3) : '99+'}%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// sidebar link
|
||||||
|
const link = createElement(
|
||||||
|
`<a class="sidebar__link" href="#${snippetFile.replace('.md', '')}">${
|
||||||
|
snippetEl.querySelector('h3').innerHTML
|
||||||
|
}</a>`
|
||||||
|
)
|
||||||
|
|
||||||
|
// tags
|
||||||
|
const tags = (snippetData.match(/<!--\s*tags:\s*(.+?)-->/) || [, ''])[1]
|
||||||
|
.split(/,\s*/)
|
||||||
|
.forEach(tag => {
|
||||||
|
tag = tag.trim().toLowerCase()
|
||||||
|
snippetEl
|
||||||
|
.querySelector('h3')
|
||||||
|
.append(
|
||||||
|
createElement(
|
||||||
|
`<span class="tags__tag snippet__tag" data-type="${tag}"><i data-feather="${
|
||||||
|
TAGS.find(t => t.name === tag).icon
|
||||||
|
}"></i>${tag}</span>`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
sidebarLinkContainer.querySelector(`section[data-type="${tag}"]`).append(link)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build dom
|
||||||
|
TAGS.forEach(tag =>
|
||||||
|
components.tags.append(
|
||||||
|
createElement(
|
||||||
|
`<button class="tags__tag is-large ${tag.name === 'all' ? 'is-active' : ''}" data-type="${
|
||||||
|
tag.name
|
||||||
|
}"><i data-feather="${tag.icon}"></i>${tag.name}</button>`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const content = document.querySelector('.content-wrapper')
|
||||||
|
content.before(components.backToTopButton)
|
||||||
|
content.before(components.sidebar)
|
||||||
|
content.append(components.header)
|
||||||
|
content.append(components.main)
|
||||||
|
components.main.querySelector('.container').prepend(components.tags)
|
||||||
|
|
||||||
// doctype declaration gets stripped, add it back in
|
// doctype declaration gets stripped, add it back in
|
||||||
const html = `<!DOCTYPE html>
|
const html = `<!DOCTYPE html>
|
||||||
${pretty(document.documentElement.outerHTML, { ocd: true })}
|
${pretty(document.documentElement.outerHTML, { ocd: true })}
|
||||||
|
|||||||
@ -44,3 +44,5 @@ html {
|
|||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=css3-boxsizing
|
* https://caniuse.com/#feat=css3-boxsizing
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
|
|||||||
@ -18,7 +18,7 @@ Ensures that an element self-clears its children.
|
|||||||
|
|
||||||
```css
|
```css
|
||||||
.clearfix::after {
|
.clearfix::after {
|
||||||
content: "";
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
@ -60,3 +60,5 @@ Ensures that an element self-clears its children.
|
|||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
|
|||||||
@ -43,3 +43,5 @@ causes an element's height to become a percentage of its parent's width, i.e. `5
|
|||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
<span class="snippet__support-note">⚠️ `padding-top` pushes any content within the element to the bottom.</span>
|
<span class="snippet__support-note">⚠️ `padding-top` pushes any content within the element to the bottom.</span>
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
|
|||||||
@ -19,13 +19,13 @@ Customizes the scrollbar style for the document and elements with scrollable ove
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
|
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scrollable element */
|
/* Scrollable element */
|
||||||
@ -80,3 +80,5 @@ There are many other pseudo-elements that you can use to style scrollbars. For m
|
|||||||
<span class="snippet__support-note">⚠️ Scrollbar styling doesn't appear to be on any standards track.</span>
|
<span class="snippet__support-note">⚠️ Scrollbar styling doesn't appear to be on any standards track.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=css-scrollbar
|
* https://caniuse.com/#feat=css-scrollbar
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -48,3 +48,5 @@ Changes the styling of text selection.
|
|||||||
in any specification.</span>
|
in any specification.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=css-selection
|
* https://caniuse.com/#feat=css-selection
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -39,3 +39,5 @@ Makes the content unselectable.
|
|||||||
<span class="snippet__support-note">⚠️ Requires prefixes for full support.</span>
|
<span class="snippet__support-note">⚠️ Requires prefixes for full support.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=user-select-none
|
* https://caniuse.com/#feat=user-select-none
|
||||||
|
|
||||||
|
<!-- tags: interactivity -->
|
||||||
|
|||||||
@ -12,8 +12,12 @@ Creates a donut spinner that can be used to indicate the loading of content.
|
|||||||
|
|
||||||
```css
|
```css
|
||||||
@keyframes donut-spin {
|
@keyframes donut-spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% {
|
||||||
100% { transform: rotate(360deg); }
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.donut {
|
.donut {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -59,3 +63,5 @@ serve as the loading indicator for the donut. Use `animation` to rotate the elem
|
|||||||
|
|
||||||
* https://caniuse.com/#feat=css-animation
|
* https://caniuse.com/#feat=css-animation
|
||||||
* https://caniuse.com/#feat=transforms2d
|
* https://caniuse.com/#feat=transforms2d
|
||||||
|
|
||||||
|
<!-- tags: animation -->
|
||||||
|
|||||||
@ -104,3 +104,5 @@ The variables are defined globally within the `:root` CSS pseudo-class which mat
|
|||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=css-variables
|
* https://caniuse.com/#feat=css-variables
|
||||||
|
|
||||||
|
<!-- tags: animation -->
|
||||||
|
|||||||
@ -49,3 +49,5 @@ of the background.
|
|||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=css-textshadow
|
* https://caniuse.com/#feat=css-textshadow
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -51,3 +51,5 @@ Alternatively, use `justify-content: space-around` to distribute the children wi
|
|||||||
<span class="snippet__support-note">⚠️ Needs prefixes for full support.</span>
|
<span class="snippet__support-note">⚠️ Needs prefixes for full support.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=flexbox
|
* https://caniuse.com/#feat=flexbox
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
|
|||||||
@ -49,3 +49,5 @@ Gives text a gradient color.
|
|||||||
<span class="snippet__support-note">⚠️ Uses non-standard properties.</span>
|
<span class="snippet__support-note">⚠️ Uses non-standard properties.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=text-stroke
|
* https://caniuse.com/#feat=text-stroke
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -81,3 +81,5 @@ very sharp and crisp.
|
|||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
\*Chrome does not support subpixel values on `border`. Safari does not support subpixel values on `box-shadow`. Firefox supports subpixel values on both.
|
\*Chrome does not support subpixel values on `border`. Safari does not support subpixel values on `box-shadow`. Firefox supports subpixel values on both.
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -48,3 +48,5 @@ Horizontally and vertically centers a child element within a parent element.
|
|||||||
<span class="snippet__support-note">⚠️ Needs prefixes for full support.</span>
|
<span class="snippet__support-note">⚠️ Needs prefixes for full support.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=flexbox
|
* https://caniuse.com/#feat=flexbox
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
|
|||||||
@ -69,7 +69,7 @@ Creates an animated underline effect when the text is hovered over.
|
|||||||
#### Explanation
|
#### Explanation
|
||||||
|
|
||||||
1. `display: inline-block` makes the block `p` an `inline-block` to prevent the underline from
|
1. `display: inline-block` makes the block `p` an `inline-block` to prevent the underline from
|
||||||
spanning the entire parent width rather than just the content (text).
|
spanning the entire parent width rather than just the content (text).
|
||||||
2. `position: relative` on the element establishes a Cartesian positioning context for pseudo-elements.
|
2. `position: relative` on the element establishes a Cartesian positioning context for pseudo-elements.
|
||||||
3. `::after` defines a pseudo-element.
|
3. `::after` defines a pseudo-element.
|
||||||
4. `position: absolute` takes the pseudo element out of the flow of the document and positions it in relation to the parent.
|
4. `position: absolute` takes the pseudo element out of the flow of the document and positions it in relation to the parent.
|
||||||
@ -77,11 +77,11 @@ spanning the entire parent width rather than just the content (text).
|
|||||||
6. `transform: scaleX(0)` initially scales the pseudo element to 0 so it has no width and is not visible.
|
6. `transform: scaleX(0)` initially scales the pseudo element to 0 so it has no width and is not visible.
|
||||||
7. `bottom: 0` and `left: 0` position it to the bottom left of the block.
|
7. `bottom: 0` and `left: 0` position it to the bottom left of the block.
|
||||||
8. `transition: transform 0.25s ease-out` means changes to `transform` will be transitioned over 0.25 seconds
|
8. `transition: transform 0.25s ease-out` means changes to `transform` will be transitioned over 0.25 seconds
|
||||||
with an `ease-out` timing function.
|
with an `ease-out` timing function.
|
||||||
9. `transform-origin: bottom right` means the transform anchor point is positioned at the bottom right of the block.
|
9. `transform-origin: bottom right` means the transform anchor point is positioned at the bottom right of the block.
|
||||||
10. `:hover::after` then uses `scaleX(1)` to transition the width to 100%, then changes the `transform-origin`
|
10. `:hover::after` then uses `scaleX(1)` to transition the width to 100%, then changes the `transform-origin`
|
||||||
to `bottom left` so that the anchor point is reversed, allowing it transition out in the other direction when
|
to `bottom left` so that the anchor point is reversed, allowing it transition out in the other direction when
|
||||||
hovered off.
|
hovered off.
|
||||||
|
|
||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
@ -89,3 +89,5 @@ hovered off.
|
|||||||
|
|
||||||
* https://caniuse.com/#feat=transforms2d
|
* https://caniuse.com/#feat=transforms2d
|
||||||
* https://caniuse.com/#feat=css-transitions
|
* https://caniuse.com/#feat=css-transitions
|
||||||
|
|
||||||
|
<!-- tags: animation -->
|
||||||
|
|||||||
@ -41,7 +41,7 @@ A hover effect where the gradient follows the mouse cursor.
|
|||||||
height: var(--size);
|
height: var(--size);
|
||||||
background: radial-gradient(circle closest-side, pink, transparent);
|
background: radial-gradient(circle closest-side, pink, transparent);
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
transition: width .2s ease, height .2s ease;
|
transition: width 0.2s ease, height 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mouse-cursor-gradient-tracking:hover::before {
|
.mouse-cursor-gradient-tracking:hover::before {
|
||||||
@ -53,7 +53,7 @@ A hover effect where the gradient follows the mouse cursor.
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
var btn = document.querySelector('.mouse-cursor-gradient-tracking')
|
var btn = document.querySelector('.mouse-cursor-gradient-tracking')
|
||||||
btn.onmousemove = function (e) {
|
btn.onmousemove = function(e) {
|
||||||
var x = e.pageX - btn.offsetLeft
|
var x = e.pageX - btn.offsetLeft
|
||||||
var y = e.pageY - btn.offsetTop
|
var y = e.pageY - btn.offsetTop
|
||||||
btn.style.setProperty('--x', x + 'px')
|
btn.style.setProperty('--x', x + 'px')
|
||||||
@ -131,7 +131,10 @@ var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
<div class="snippet__requires-javascript">Requires JavaScript</div>
|
<div class="snippet__requires-javascript">Requires JavaScript</div>
|
||||||
<span class="snippet__support-note">⚠️ Requires JavaScript.</span>
|
<span class="snippet__support-note">⚠️ Requires JavaScript.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=css-variables
|
* https://caniuse.com/#feat=css-variables
|
||||||
|
|
||||||
|
<!-- tags: visual, interactivity -->
|
||||||
|
|||||||
@ -24,7 +24,10 @@ Adds a fading gradient to an overflowing element to better indicate there is mor
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
background: linear-gradient(rgba(255, 255, 255, 0.001), white); /* transparent keyword is broken in Safari */
|
background: linear-gradient(
|
||||||
|
rgba(255, 255, 255, 0.001),
|
||||||
|
white
|
||||||
|
); /* transparent keyword is broken in Safari */
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.overflow-scroll-gradient__scroller {
|
.overflow-scroll-gradient__scroller {
|
||||||
@ -81,10 +84,10 @@ document.querySelector('.snippet-demo__overflow-scroll-gradient__scroller').inne
|
|||||||
1. `position: relative` on the parent establishes a Cartesian positioning context for pseudo-elements.
|
1. `position: relative` on the parent establishes a Cartesian positioning context for pseudo-elements.
|
||||||
2. `::after` defines a pseudo element.
|
2. `::after` defines a pseudo element.
|
||||||
3. `background-image: linear-gradient(...)` adds a linear gradient that fades from transparent to white
|
3. `background-image: linear-gradient(...)` adds a linear gradient that fades from transparent to white
|
||||||
(top to bottom).
|
(top to bottom).
|
||||||
4. `position: absolute` takes the pseudo element out of the flow of the document and positions it in relation to the parent.
|
4. `position: absolute` takes the pseudo element out of the flow of the document and positions it in relation to the parent.
|
||||||
5. `width: 300px` matches the size of the scrolling element (which is a child of the parent that has
|
5. `width: 300px` matches the size of the scrolling element (which is a child of the parent that has
|
||||||
the pseudo element).
|
the pseudo element).
|
||||||
6. `height: 25px` is the height of the fading gradient pseudo-element, which should be kept relatively small.
|
6. `height: 25px` is the height of the fading gradient pseudo-element, which should be kept relatively small.
|
||||||
7. `bottom: 0` positions the pseudo-element at the bottom of the parent.
|
7. `bottom: 0` positions the pseudo-element at the bottom of the parent.
|
||||||
8. `pointer-events: none` specifies that the pseudo-element cannot be a target of mouse events, allowing text behind it to still be selectable/interactive.
|
8. `pointer-events: none` specifies that the pseudo-element cannot be a target of mouse events, allowing text behind it to still be selectable/interactive.
|
||||||
@ -94,3 +97,5 @@ document.querySelector('.snippet-demo__overflow-scroll-gradient__scroller').inne
|
|||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=css-gradients
|
* https://caniuse.com/#feat=css-gradients
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -75,3 +75,5 @@ Reveals an interactive popout menu on hover.
|
|||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
|
<!-- tags: interactivity -->
|
||||||
|
|||||||
@ -16,10 +16,7 @@ Natively implemented as `text-decoration-skip-ink: auto` but it has less control
|
|||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
display: inline;
|
display: inline;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
text-shadow: 1px 1px 0 #f5f6f9,
|
text-shadow: 1px 1px 0 #f5f6f9, -1px 1px 0 #f5f6f9, -1px -1px 0 #f5f6f9, 1px -1px 0 #f5f6f9;
|
||||||
-1px 1px 0 #f5f6f9,
|
|
||||||
-1px -1px 0 #f5f6f9,
|
|
||||||
1px -1px 0 #f5f6f9;
|
|
||||||
background-image: linear-gradient(90deg, currentColor 100%, transparent 100%);
|
background-image: linear-gradient(90deg, currentColor 100%, transparent 100%);
|
||||||
background-position: 0 0.98em;
|
background-position: 0 0.98em;
|
||||||
background-repeat: repeat-x;
|
background-repeat: repeat-x;
|
||||||
@ -70,13 +67,13 @@ Natively implemented as `text-decoration-skip-ink: auto` but it has less control
|
|||||||
#### Explanation
|
#### Explanation
|
||||||
|
|
||||||
1. `text-shadow: ...` has 4 values with offsets that cover a 4x4 px area to ensure the underline
|
1. `text-shadow: ...` has 4 values with offsets that cover a 4x4 px area to ensure the underline
|
||||||
has a "thick" shadow that covers the line where descenders clip it. Use a color
|
has a "thick" shadow that covers the line where descenders clip it. Use a color
|
||||||
that matches the background. For a larger font, use a larger `px` size.
|
that matches the background. For a larger font, use a larger `px` size.
|
||||||
2. `background-image: linear-gradient(...)` creates a 90deg gradient with the current
|
2. `background-image: linear-gradient(...)` creates a 90deg gradient with the current
|
||||||
text color (`currentColor`).
|
text color (`currentColor`).
|
||||||
3. The `background-*` properties size the gradient as 1x1px at the bottom and repeats it along the x-axis.
|
3. The `background-*` properties size the gradient as 1x1px at the bottom and repeats it along the x-axis.
|
||||||
4. The `::selection` pseudo selector ensures the text shadow does not interfere with text
|
4. The `::selection` pseudo selector ensures the text shadow does not interfere with text
|
||||||
selection.
|
selection.
|
||||||
|
|
||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
@ -84,3 +81,5 @@ Natively implemented as `text-decoration-skip-ink: auto` but it has less control
|
|||||||
|
|
||||||
* https://caniuse.com/#feat=css-textshadow
|
* https://caniuse.com/#feat=css-textshadow
|
||||||
* https://caniuse.com/#feat=css-gradients
|
* https://caniuse.com/#feat=css-gradients
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -64,3 +64,5 @@ Uses an SVG shape to separate two different blocks to create more a interesting
|
|||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=svg
|
* https://caniuse.com/#feat=svg
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -12,7 +12,8 @@ Uses the native font of the operating system to get close to a native app feel.
|
|||||||
|
|
||||||
```css
|
```css
|
||||||
.system-font-stack {
|
.system-font-stack {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu,
|
||||||
|
Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -46,3 +47,5 @@ falls back to the next if it cannot find the font (on the system or defined in C
|
|||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -89,3 +89,5 @@ Experiment with the `px` values to change the proportion of the triangle.
|
|||||||
#### Browser support
|
#### Browser support
|
||||||
|
|
||||||
<span class="snippet__support-note">✅ No caveats.</span>
|
<span class="snippet__support-note">✅ No caveats.</span>
|
||||||
|
|
||||||
|
<!-- tags: visual -->
|
||||||
|
|||||||
@ -51,3 +51,5 @@ If the text is longer than one line, it will be truncated and end with an ellips
|
|||||||
<span class="snippet__support-note">⚠️ Only works for single line elements.</span>
|
<span class="snippet__support-note">⚠️ Only works for single line elements.</span>
|
||||||
|
|
||||||
* https://caniuse.com/#feat=text-overflow
|
* https://caniuse.com/#feat=text-overflow
|
||||||
|
|
||||||
|
<!-- tags: layout -->
|
||||||
|
|||||||
@ -35,6 +35,7 @@
|
|||||||
max-height: 378px;
|
max-height: 378px;
|
||||||
margin-top: 44px;
|
margin-top: 44px;
|
||||||
box-shadow: 0 0.25rem 0.5rem -0.1rem rgba(0, 32, 128, 0.2);
|
box-shadow: 0 0.25rem 0.5rem -0.1rem rgba(0, 32, 128, 0.2);
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
transform: rotateX(0);
|
transform: rotateX(0);
|
||||||
@ -59,6 +60,16 @@
|
|||||||
border-color: pink;
|
border-color: pink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__section {
|
||||||
|
padding: 0 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__section-heading {
|
||||||
|
text-transform: capitalize;
|
||||||
|
color: #e3f5ff;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
@media (min-width: 992px) {
|
||||||
|
|||||||
@ -14,6 +14,10 @@
|
|||||||
margin-bottom: 1.25rem;
|
margin-bottom: 1.25rem;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
|
|
||||||
|
span:not(.snippet__tag) {
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code:not([class*='lang']) {
|
code:not([class*='lang']) {
|
||||||
@ -42,16 +46,20 @@
|
|||||||
h4 {
|
h4 {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 1rem 0 0.5rem;
|
margin: 1rem 0 0.5rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
line-height: 2;
|
line-height: 2;
|
||||||
padding: 0 0.5rem;
|
|
||||||
border-radius: 3px;
|
&[data-type] {
|
||||||
font-size: 0.9rem;
|
background: #333;
|
||||||
text-transform: uppercase;
|
padding: 0 0.5rem;
|
||||||
background: #333;
|
border-radius: 3px;
|
||||||
border: 1px solid #c6d6ea;
|
font-size: 0.9rem;
|
||||||
border-bottom-color: darken(#c6d6ea, 5);
|
text-transform: uppercase;
|
||||||
background: white;
|
border: 1px solid #c6d6ea;
|
||||||
box-shadow: 0 0.25rem 0.5rem -0.1rem rgba(0, 32, 64, 0.15);
|
border-bottom-color: darken(#c6d6ea, 5);
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 0.25rem 0.5rem -0.1rem rgba(0, 32, 64, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
&[data-type='HTML'] {
|
&[data-type='HTML'] {
|
||||||
color: white;
|
color: white;
|
||||||
@ -107,6 +115,9 @@
|
|||||||
top: 1rem;
|
top: 1rem;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__tag {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.snippet-demo {
|
.snippet-demo {
|
||||||
|
|||||||
83
src/css/components/tags.scss
Normal file
83
src/css/components/tags.scss
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
.tags {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
|
&__tag {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #8385aa;
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 1px solid lighten(#8385aa, 15);
|
||||||
|
border-radius: 2px;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: 2;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
transition: all 0.1s ease-out;
|
||||||
|
outline: 0;
|
||||||
|
|
||||||
|
&.is-large {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
|
||||||
|
.feather {
|
||||||
|
top: -2px;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.feather {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 0.25rem;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button.tags__tag {
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #8385aa;
|
||||||
|
border-color: #8385aa;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem transparentize(#8385aa, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
box-shadow: inset 0 0.1rem 0.1rem 0.1rem rgba(0, 0, 0, 0.2);
|
||||||
|
background: darken(#8385aa, 10);
|
||||||
|
border-color: darken(#8385aa, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
background: #7983ff;
|
||||||
|
border-color: #7983ff;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem transparentize(#7983ff, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 579px) {
|
||||||
|
}
|
||||||
@ -4,3 +4,4 @@
|
|||||||
@import './components/header.scss';
|
@import './components/header.scss';
|
||||||
@import './components/snippet.scss';
|
@import './components/snippet.scss';
|
||||||
@import './components/back-to-top-button.scss';
|
@import './components/back-to-top-button.scss';
|
||||||
|
@import './components/tags.scss';
|
||||||
|
|||||||
1
src/html/components/back-to-top-button.html
Normal file
1
src/html/components/back-to-top-button.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<button class="back-to-top-button" aria-label="back to top">↑</button>
|
||||||
1
src/html/components/footer.html
Normal file
1
src/html/components/footer.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<footer class="footer"></footer>
|
||||||
10
src/html/components/header.html
Normal file
10
src/html/components/header.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<header class="header">
|
||||||
|
<div class="container">
|
||||||
|
<img class="header__logo" draggable="false" src="./src/img/logo.png">
|
||||||
|
<h1 class="header__heading">30 Seconds of <strong class="header__css">CSS</strong></h1>
|
||||||
|
<p class="header__description">
|
||||||
|
A curated collection of useful CSS snippets you can understand in 30 seconds or less.
|
||||||
|
</p>
|
||||||
|
<a class="github-button header__github-button" href="https://github.com/atomiks/30-seconds-of-css" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star atomiks/30-seconds-of-css on GitHub">Star</a>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
4
src/html/components/main.html
Normal file
4
src/html/components/main.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<main class="main" id="main">
|
||||||
|
<div class="container">
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
9
src/html/components/sidebar.html
Normal file
9
src/html/components/sidebar.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<nav class="sidebar" aria-label="Table of Contents">
|
||||||
|
<button class="hamburger hamburger--spin sidebar__menu" type="button" aria-label="Menu" aria-expanded="false">
|
||||||
|
<span class="hamburger-box">
|
||||||
|
<span class="hamburger-inner"></span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<div class="sidebar__links">
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
1
src/html/components/tags.html
Normal file
1
src/html/components/tags.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<nav class="tags" aria-label="Filter by tags"></nav>
|
||||||
15
src/html/index.html
Normal file
15
src/html/index.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>30 Seconds of CSS</title>
|
||||||
|
<meta name="description" content="A curated collection of useful CSS snippets you can understand in 30 seconds or less. From foundational elements such as clearfix to gradient text color and gradient cursor tracking to CSS easing and far beyond.">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png">
|
||||||
|
<script src="./src/js/index.js" defer=""></script>
|
||||||
|
<script async="" defer="" src="https://buttons.github.io/buttons.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content-wrapper"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1,27 +1,23 @@
|
|||||||
import jump from '../deps/jump'
|
|
||||||
import { select, selectAll, easeOutQuint } from '../deps/utils'
|
import { select, selectAll, easeOutQuint } from '../deps/utils'
|
||||||
|
|
||||||
const menu = select('.hamburger')
|
const menu = select('.hamburger')
|
||||||
const links = select('.sidebar__links')
|
const links = select('.sidebar__links')
|
||||||
|
const sections = selectAll('.sidebar__section')
|
||||||
const ACTIVE_CLASS = 'is-active'
|
const ACTIVE_CLASS = 'is-active'
|
||||||
|
|
||||||
const toggle = () => {
|
const toggle = () => {
|
||||||
const els = [menu, links]
|
if (window.innerWidth <= 991) {
|
||||||
els.forEach(el => el.classList.toggle(ACTIVE_CLASS))
|
const els = [menu, links]
|
||||||
menu.setAttribute('aria-expanded', menu.classList.contains(ACTIVE_CLASS) ? 'true' : 'false')
|
els.forEach(el => el.classList.toggle(ACTIVE_CLASS))
|
||||||
|
menu.setAttribute('aria-expanded', menu.classList.contains(ACTIVE_CLASS) ? 'true' : 'false')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.addEventListener('click', toggle)
|
menu.addEventListener('click', toggle)
|
||||||
|
|
||||||
links.addEventListener('click', e => {
|
links.addEventListener('click', e => {
|
||||||
setTimeout(toggle, 40)
|
|
||||||
if (e.target.classList.contains('sidebar__link')) {
|
if (e.target.classList.contains('sidebar__link')) {
|
||||||
e.preventDefault()
|
setTimeout(toggle, 100)
|
||||||
jump(e.target.getAttribute('href'), {
|
|
||||||
duration: 750,
|
|
||||||
offset: window.innerWidth <= 768 ? -64 : -32,
|
|
||||||
easing: easeOutQuint
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -35,4 +31,13 @@ document.addEventListener('click', e => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
EventHub.on('Tag.click', data => {
|
||||||
|
sections.forEach(section => {
|
||||||
|
section.style.display = 'block'
|
||||||
|
if (section.dataset.type !== data.type && data.type !== 'all') {
|
||||||
|
section.style.display = 'none'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
export default { toggle }
|
export default { toggle }
|
||||||
13
src/js/components/Snippet.js
Normal file
13
src/js/components/Snippet.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { selectAll } from '../deps/utils'
|
||||||
|
|
||||||
|
const snippets = selectAll('.snippet')
|
||||||
|
EventHub.on('Tag.click', data => {
|
||||||
|
snippets.forEach(snippet => {
|
||||||
|
snippet.style.display = 'block'
|
||||||
|
if (data.type === 'all') return
|
||||||
|
const tags = selectAll('.tags__tag', snippet)
|
||||||
|
if (!selectAll('.tags__tag', snippet).some(el => el.dataset.type === data.type)) {
|
||||||
|
snippet.style.display = 'none'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
14
src/js/components/Tag.js
Normal file
14
src/js/components/Tag.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { select, selectAll, on } from '../deps/utils'
|
||||||
|
|
||||||
|
const tagButtons = selectAll('button.tags__tag')
|
||||||
|
|
||||||
|
const onClick = function() {
|
||||||
|
tagButtons.forEach(button => button.classList.remove('is-active'))
|
||||||
|
this.classList.add('is-active')
|
||||||
|
|
||||||
|
EventHub.emit('Tag.click', {
|
||||||
|
type: this.dataset.type
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tagButtons.forEach(button => on(button, 'click', onClick))
|
||||||
@ -1,196 +0,0 @@
|
|||||||
;(function(global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory())
|
|
||||||
: typeof define === 'function' && define.amd ? define(factory) : (global.Jump = factory())
|
|
||||||
})(this, function() {
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
// Robert Penner's easeInOutQuad
|
|
||||||
|
|
||||||
// find the rest of his easing functions here: http://robertpenner.com/easing/
|
|
||||||
// find them exported for ES6 consumption here: https://github.com/jaxgeller/ez.js
|
|
||||||
|
|
||||||
var easeInOutQuad = function easeInOutQuad(t, b, c, d) {
|
|
||||||
t /= d / 2
|
|
||||||
if (t < 1) return c / 2 * t * t + b
|
|
||||||
t--
|
|
||||||
return -c / 2 * (t * (t - 2) - 1) + b
|
|
||||||
}
|
|
||||||
|
|
||||||
var _typeof =
|
|
||||||
typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol'
|
|
||||||
? function(obj) {
|
|
||||||
return typeof obj
|
|
||||||
}
|
|
||||||
: function(obj) {
|
|
||||||
return obj &&
|
|
||||||
typeof Symbol === 'function' &&
|
|
||||||
obj.constructor === Symbol &&
|
|
||||||
obj !== Symbol.prototype
|
|
||||||
? 'symbol'
|
|
||||||
: typeof obj
|
|
||||||
}
|
|
||||||
|
|
||||||
var jumper = function jumper() {
|
|
||||||
// private variable cache
|
|
||||||
// no variables are created during a jump, preventing memory leaks
|
|
||||||
|
|
||||||
var element = void 0 // element to scroll to (node)
|
|
||||||
|
|
||||||
var start = void 0 // where scroll starts (px)
|
|
||||||
var stop = void 0 // where scroll stops (px)
|
|
||||||
|
|
||||||
var offset = void 0 // adjustment from the stop position (px)
|
|
||||||
var easing = void 0 // easing function (function)
|
|
||||||
var a11y = void 0 // accessibility support flag (boolean)
|
|
||||||
|
|
||||||
var distance = void 0 // distance of scroll (px)
|
|
||||||
var duration = void 0 // scroll duration (ms)
|
|
||||||
|
|
||||||
var timeStart = void 0 // time scroll started (ms)
|
|
||||||
var timeElapsed = void 0 // time spent scrolling thus far (ms)
|
|
||||||
|
|
||||||
var next = void 0 // next scroll position (px)
|
|
||||||
|
|
||||||
var callback = void 0 // to call when done scrolling (function)
|
|
||||||
|
|
||||||
// scroll position helper
|
|
||||||
|
|
||||||
function location() {
|
|
||||||
return window.scrollY || window.pageYOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// element offset helper
|
|
||||||
|
|
||||||
function top(element) {
|
|
||||||
return element.getBoundingClientRect().top + start
|
|
||||||
}
|
|
||||||
|
|
||||||
// rAF loop helper
|
|
||||||
|
|
||||||
function loop(timeCurrent) {
|
|
||||||
// store time scroll started, if not started already
|
|
||||||
if (!timeStart) {
|
|
||||||
timeStart = timeCurrent
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine time spent scrolling so far
|
|
||||||
timeElapsed = timeCurrent - timeStart
|
|
||||||
|
|
||||||
// calculate next scroll position
|
|
||||||
next = easing(timeElapsed, start, distance, duration)
|
|
||||||
|
|
||||||
// scroll to it
|
|
||||||
window.scrollTo(0, next)
|
|
||||||
|
|
||||||
// check progress
|
|
||||||
timeElapsed < duration
|
|
||||||
? window.requestAnimationFrame(loop) // continue scroll loop
|
|
||||||
: done() // scrolling is done
|
|
||||||
}
|
|
||||||
|
|
||||||
// scroll finished helper
|
|
||||||
|
|
||||||
function done() {
|
|
||||||
// account for rAF time rounding inaccuracies
|
|
||||||
window.scrollTo(0, start + distance)
|
|
||||||
|
|
||||||
// if scrolling to an element, and accessibility is enabled
|
|
||||||
if (element && a11y) {
|
|
||||||
// add tabindex indicating programmatic focus
|
|
||||||
element.setAttribute('tabindex', '-1')
|
|
||||||
|
|
||||||
// focus the element
|
|
||||||
element.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it exists, fire the callback
|
|
||||||
if (typeof callback === 'function') {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset time for next jump
|
|
||||||
timeStart = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// API
|
|
||||||
|
|
||||||
function jump(target) {
|
|
||||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}
|
|
||||||
|
|
||||||
// resolve options, or use defaults
|
|
||||||
duration = options.duration || 1000
|
|
||||||
offset = options.offset || 0
|
|
||||||
callback = options.callback // "undefined" is a suitable default, and won't be called
|
|
||||||
easing = options.easing || easeInOutQuad
|
|
||||||
a11y = options.a11y || false
|
|
||||||
|
|
||||||
// cache starting position
|
|
||||||
start = location()
|
|
||||||
|
|
||||||
// resolve target
|
|
||||||
switch (typeof target === 'undefined' ? 'undefined' : _typeof(target)) {
|
|
||||||
// scroll from current position
|
|
||||||
case 'number':
|
|
||||||
element = undefined // no element to scroll to
|
|
||||||
a11y = false // make sure accessibility is off
|
|
||||||
stop = start + target
|
|
||||||
break
|
|
||||||
|
|
||||||
// scroll to element (node)
|
|
||||||
// bounding rect is relative to the viewport
|
|
||||||
case 'object':
|
|
||||||
element = target
|
|
||||||
stop = top(element)
|
|
||||||
break
|
|
||||||
|
|
||||||
// scroll to element (selector)
|
|
||||||
// bounding rect is relative to the viewport
|
|
||||||
case 'string':
|
|
||||||
element = document.querySelector(target)
|
|
||||||
stop = top(element)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolve scroll distance, accounting for offset
|
|
||||||
distance = stop - start + offset
|
|
||||||
|
|
||||||
// resolve duration
|
|
||||||
switch (_typeof(options.duration)) {
|
|
||||||
// number in ms
|
|
||||||
case 'number':
|
|
||||||
duration = options.duration
|
|
||||||
break
|
|
||||||
|
|
||||||
// function passed the distance of the scroll
|
|
||||||
case 'function':
|
|
||||||
duration = options.duration(distance)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the loop
|
|
||||||
window.requestAnimationFrame(loop)
|
|
||||||
}
|
|
||||||
|
|
||||||
// expose only the jump method
|
|
||||||
return jump
|
|
||||||
}
|
|
||||||
|
|
||||||
// export singleton
|
|
||||||
|
|
||||||
var singleton = jumper()
|
|
||||||
|
|
||||||
return (() => {
|
|
||||||
let scrolling
|
|
||||||
const end = () => (scrolling = false)
|
|
||||||
return (to, options = {}) => {
|
|
||||||
if (scrolling) return
|
|
||||||
const scrollY = window.scrollY || window.pageYOffset
|
|
||||||
if (to !== '.header') location.hash = to
|
|
||||||
scroll(0, scrollY)
|
|
||||||
scrolling = true
|
|
||||||
setTimeout(end, options.duration || 0)
|
|
||||||
return singleton(to, options)
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
})
|
|
||||||
@ -1,8 +1,34 @@
|
|||||||
export const select = s => document.querySelector(s)
|
export const select = (s, parent = document) => parent.querySelector(s)
|
||||||
export const selectAll = s => [].slice.call(document.querySelectorAll(s))
|
|
||||||
|
export const selectAll = (s, parent = document) => [].slice.call(parent.querySelectorAll(s))
|
||||||
|
|
||||||
export const scrollY = () => window.scrollY || window.pageYOffset
|
export const scrollY = () => window.scrollY || window.pageYOffset
|
||||||
|
|
||||||
export const easeOutQuint = (t, b, c, d) => c * ((t = t / d - 1) * t ** 4 + 1) + b
|
export const easeOutQuint = (t, b, c, d) => c * ((t = t / d - 1) * t ** 4 + 1) + b
|
||||||
|
|
||||||
|
export const on = (el, evt, fn, opts = {}) => {
|
||||||
|
const delegatorFn = e => e.target.matches(opts.target) && fn.call(e.target, e)
|
||||||
|
el.addEventListener(evt, opts.target ? delegatorFn : fn, opts.options || false)
|
||||||
|
if (opts.target) return delegatorFn
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createEventHub = () => ({
|
||||||
|
hub: Object.create(null),
|
||||||
|
emit(event, data) {
|
||||||
|
;(this.hub[event] || []).forEach(handler => handler(data))
|
||||||
|
},
|
||||||
|
on(event, handler) {
|
||||||
|
if (!this.hub[event]) this.hub[event] = []
|
||||||
|
this.hub[event].push(handler)
|
||||||
|
},
|
||||||
|
off(event, handler) {
|
||||||
|
const i = (this.hub[event] || []).findIndex(h => h === handler)
|
||||||
|
if (i > -1) this.hub[event].splice(i, 1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.EventHub = createEventHub()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make iOS behave normally.
|
* Make iOS behave normally.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
// Deps
|
// Deps
|
||||||
import 'normalize.css'
|
import 'normalize.css'
|
||||||
import 'prismjs'
|
import 'prismjs'
|
||||||
|
import feather from 'feather-icons'
|
||||||
|
feather.replace()
|
||||||
|
|
||||||
// CSS
|
// CSS
|
||||||
import '../css/deps/prism.css'
|
import '../css/deps/prism.css'
|
||||||
@ -10,5 +12,7 @@ import '../css/index.scss'
|
|||||||
import './deps/polyfills'
|
import './deps/polyfills'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import Menu from './components/Menu'
|
import Sidebar from './components/Sidebar'
|
||||||
import BackToTopButton from './components/BackToTopButton'
|
import BackToTopButton from './components/BackToTopButton'
|
||||||
|
import Tag from './components/Tag'
|
||||||
|
import Snippet from './components/Snippet'
|
||||||
|
|||||||
@ -1,8 +1,20 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
const { JSDOM } = require('jsdom')
|
||||||
|
|
||||||
exports.toKebabCase = str =>
|
exports.toKebabCase = str =>
|
||||||
str &&
|
str &&
|
||||||
str
|
str
|
||||||
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
||||||
.map(x => x.toLowerCase())
|
.map(x => x.toLowerCase())
|
||||||
.join('-');
|
.join('-')
|
||||||
|
|
||||||
exports.emptyHTML = (...els) => els.forEach(el => (el.innerHTML = ''))
|
exports.dom = path => {
|
||||||
|
const doc = new JSDOM(fs.readFileSync(path, 'utf8')).window.document
|
||||||
|
return path.includes('component') ? doc.body.firstElementChild : doc
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.createElement = str => {
|
||||||
|
const el = new JSDOM().window.document.createElement('div')
|
||||||
|
el.innerHTML = str
|
||||||
|
return el.firstElementChild
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user