mirror of
https://github.com/kognise/water.css.git
synced 2025-08-09 06:37:05 +02:00
Merge branch 'documentation' into development
This commit is contained in:
5
.changeset/famous-timers-sparkle.md
Normal file
5
.changeset/famous-timers-sparkle.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"water.css": minor
|
||||
---
|
||||
|
||||
Add description list styles
|
5
.changeset/nice-pens-hang.md
Normal file
5
.changeset/nice-pens-hang.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"water.css": patch
|
||||
---
|
||||
|
||||
Fix lack of top margin in details children
|
5
.changeset/weak-berries-sit.md
Normal file
5
.changeset/weak-berries-sit.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"water.css": minor
|
||||
---
|
||||
|
||||
Add header styles, change footer margin to last-of-type only
|
109
docs/docs.html
Normal file
109
docs/docs.html
Normal file
@@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns#">
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Element Docs | Water.css</title>
|
||||
<link rel="canonical" href="https://watercss.kognise.dev/docs.html" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Get started with Water.css, a drop-in collection of classless CSS styles."
|
||||
/>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="./icons/apple-touch-icon.png" />
|
||||
<link rel="icon" id="icon-16" type="image/png" sizes="16x16" href="./icons/favicon-16x16.png" />
|
||||
<link rel="icon" id="icon-32" type="image/png" sizes="32x32" href="./icons/favicon-32x32.png" />
|
||||
<link rel="manifest" href="./site.webmanifest" />
|
||||
<link rel="mask-icon" href="./icons/safari-pinned-tab.svg" color="#5bbad5" />
|
||||
<link rel="shortcut icon" id="icon-ico" href="./icons/favicon.ico" />
|
||||
<meta name="apple-mobile-web-app-title" content="Water.css" />
|
||||
<meta name="application-name" content="Water.css" />
|
||||
<meta name="msapplication-TileColor" content="#00aba9" />
|
||||
<meta name="msapplication-config" content="./icons/browserconfig.xml" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<!-- Startup styles of water.css, so styles don't have to wait until JS is loaded -->
|
||||
<link rel="stylesheet" id="js-startup-stylesheet" href="./water.css/water.min.css" />
|
||||
|
||||
<!-- Dynamic version of water.css, overwrites startup styles. JavaScript sets & updates href -->
|
||||
<link rel="stylesheet" id="js-stylesheet" />
|
||||
|
||||
<!-- Custom styles for the documentation / version picker -->
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://watercss.kognise.dev/docs.html" />
|
||||
<meta property="og:title" content="Element Docs" />
|
||||
<meta property="og:site_name" content="Water.css" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Get started with Water.css, a drop-in collection of classless CSS styles."
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://raw.githubusercontent.com/kognise/water.css/master/assets/logo.png"
|
||||
/>
|
||||
<meta property="og:image:width" content="1154" />
|
||||
<meta property="og:image:height" content="444" />
|
||||
|
||||
<script>
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
window.navigator.clipboard || document.write('<script src="https://unpkg.com/clipboard-polyfill@2.8.6/dist/clipboard-polyfill.promise.js"><\/script>')
|
||||
</script>
|
||||
|
||||
<!-- Use bright favicons when the browser is in dark mode. -->
|
||||
<script type="module">
|
||||
import faviconSwitcher from 'https://unpkg.com/favicon-mode-switcher@1.0.4/dist/index.min.mjs'
|
||||
faviconSwitcher([
|
||||
{ element: '#icon-ico', href: { dark: './icons/light-favicon.ico' } },
|
||||
{ element: '#icon-16', href: { dark: './icons/light-favicon-16x16.png' } },
|
||||
{ element: '#icon-32', href: { dark: './icons/light-favicon-32x32.png' } }
|
||||
])
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form id="theme-form" class="top-theme-form">
|
||||
<input type="radio" value="auto" checked name="theme" id="theme-auto" />
|
||||
<label for="theme-auto">Automatic 🌙 / ☀</label>
|
||||
|
||||
<input type="radio" value="dark" name="theme" id="theme-dark" />
|
||||
<label for="theme-dark">Dark theme 🌙</label>
|
||||
|
||||
<input type="radio" value="light" name="theme" id="theme-light" />
|
||||
<label for="theme-light">Light theme ☀</label>
|
||||
</form>
|
||||
|
||||
<header>
|
||||
<h1>Element Docs</h1>
|
||||
<p>
|
||||
Get started with Water.css, a drop-in collection of classless CSS styles.
|
||||
</p>
|
||||
|
||||
<h2>Table of contents</h2>
|
||||
<ul id="toc"></ul>
|
||||
</header>
|
||||
|
||||
<main id="demos"></main>
|
||||
|
||||
<footer>
|
||||
<a href="#">Back to top ⬆</a>
|
||||
</footer>
|
||||
|
||||
<dialog id="dialog">
|
||||
<header>This is a sample dialog</header>
|
||||
<form method="dialog">
|
||||
<p>What is your favorite pet animal?</p>
|
||||
<menu>
|
||||
<button value="feline">Cats</button>
|
||||
<button value="canine">Dogs</button>
|
||||
<button value="other">Others</button>
|
||||
</menu>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<script src="scripts/docs.js"></script>
|
||||
<script src="scripts/themer.js" defer></script>
|
||||
</body>
|
||||
</html>
|
268
docs/index.html
268
docs/index.html
@@ -23,8 +23,6 @@
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<!-- Startup styles of water.css, so styles don't have to wait until JS is loaded -->
|
||||
<link rel="preload" as="style" href="./water.css/dark.min.css" />
|
||||
<link rel="preload" as="style" href="./water.css/light.min.css" />
|
||||
<link rel="stylesheet" id="js-startup-stylesheet" href="./water.css/water.min.css" />
|
||||
|
||||
<!-- Dynamic version of water.css, overwrites startup styles. JavaScript sets & updates href -->
|
||||
@@ -37,6 +35,7 @@
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://watercss.kognise.dev/" />
|
||||
<meta property="og:title" content="Water.css" />
|
||||
<meta property="og:site_name" content="Water.css" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="A drop-in collection of CSS styles to make simple websites like this just a little bit nicer."
|
||||
@@ -74,41 +73,49 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Water.css</h1>
|
||||
<header>
|
||||
<div class="row">
|
||||
<h1>Water.css</h1>
|
||||
|
||||
<p>
|
||||
Water.css is a drop-in collection of CSS styles to make simple websites like this just a
|
||||
little bit nicer.
|
||||
</p>
|
||||
<p>
|
||||
Now you can write your simple static site with nice semantic html, and Water.css will manage
|
||||
the styling for you.
|
||||
</p>
|
||||
|
||||
<div class="row">
|
||||
<div>
|
||||
<a href="#installation"><b>Get it already!</b></a>
|
||||
<br />
|
||||
<a href="https://github.com/kognise/water.css"><b>GitHub</b></a>
|
||||
<a
|
||||
href="https://www.producthunt.com/posts/water-css?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-water-css"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<img
|
||||
id="product-hunt"
|
||||
src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=150490&theme=dark&period=daily"
|
||||
alt="Water.css - Make your tiny website just a little nicer | Product Hunt Embed"
|
||||
style="width: 250px; height: 54px;"
|
||||
width="250px"
|
||||
height="54px"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="https://www.producthunt.com/posts/water-css?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-water-css"
|
||||
id="product-hunt"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<img
|
||||
src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=150490&theme=dark&period=daily"
|
||||
alt="Water.css - Make your tiny website just a little nicer | Product Hunt Embed"
|
||||
style="width: 250px; height: 54px;"
|
||||
width="250px"
|
||||
height="54px"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<p>
|
||||
Water.css is a drop-in collection of CSS styles to make simple websites like this just a little bit nicer.
|
||||
</p>
|
||||
<p>
|
||||
Now you can write your simple static site with nice semantic html, and Water.css will manage the styling for you.
|
||||
</p>
|
||||
<ul>
|
||||
<li>It's responsive</li>
|
||||
<li>It's easy to theme</li>
|
||||
<li>It has great browser support</li>
|
||||
<li>It has a tiny size</li>
|
||||
<li>It doesn't require <strong>any</strong> classes</li>
|
||||
<li>It looks beautiful</li>
|
||||
<li>It encourages semantic code</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>Go to <a href="/docs.html" target="_blank">element documentation</a></b> or check out the
|
||||
<a href="https://github.com/kognise/water.css" target="_blank" rel="nooopener noreferrer">GitHub</a>.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<h2>Installation</h2>
|
||||
|
||||
<div id="installation">
|
||||
<header class="row">
|
||||
<h3 id="link-snippet-headline">
|
||||
@@ -162,24 +169,14 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 id="goals">Goals</h2>
|
||||
<ul>
|
||||
<li>Responsive</li>
|
||||
<li>Good code quality</li>
|
||||
<li>Good browser support</li>
|
||||
<li>Small size (< 2kb)</li>
|
||||
<li>Beautiful</li>
|
||||
<li>No classes</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="responsive">Is it responsive?</h2>
|
||||
<p>
|
||||
<strong>Heck yeah!</strong> It doesn't include any fancy styles so it's easily mobile
|
||||
responsive. Just add the famous
|
||||
<a href="https://www.w3schools.com/css/css_rwd_viewport.asp">responsive viewport tag</a> and
|
||||
<strong>Heck yeah!</strong> It doesn't include any fancy styles so it's mobile
|
||||
responsive by default. Just add the famous
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag#viewport_basics">responsive viewport tag</a> and
|
||||
you'll be good to go!
|
||||
</p>
|
||||
<p>In fact, try resizing this page. Everything flows super nicely as you'll see.</p>
|
||||
<p>In fact, try resizing this page. Everything will flow super nicely.</p>
|
||||
|
||||
<h2 id="bookmarklet">Bookmarklet</h2>
|
||||
<p>
|
||||
@@ -194,182 +191,7 @@
|
||||
</a>
|
||||
</strong>
|
||||
|
||||
<h2 id="demo">Element demos</h2>
|
||||
<p>This is supposed to be a demo page so we need more elements!</p>
|
||||
|
||||
<h3 id="form-elements">Form elements</h3>
|
||||
<form onsubmit="return false;">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" name="email" id="email" placeholder="john.doe@gmail.com" />
|
||||
|
||||
<label for="id">User id (read only)</label>
|
||||
<input readonly name="id" id="id" value="04D6H89Z" />
|
||||
|
||||
<label for="disabled">Random disabled input</label>
|
||||
<input disabled name="disabled" id="disabled" placeholder="Because why not?" />
|
||||
|
||||
<label for="about">About me</label>
|
||||
<textarea name="about" id="about" placeholder="I am a textarea..."></textarea>
|
||||
|
||||
<label for="rating">Rate this site</label>
|
||||
<input name="rating" id="rating" type="range" min="1" max="10"></input>
|
||||
|
||||
<label for="flavor">Choose a flavor</label>
|
||||
<select name="flavor" id="flavor">
|
||||
<option>Chocolate</option>
|
||||
<option>Strawberry</option>
|
||||
<option>Vanilla</option>
|
||||
</select>
|
||||
|
||||
<fieldset>
|
||||
<legend>Choose a Doe</legend>
|
||||
<div>
|
||||
<input type="radio" id="john" name="drone" value="john" checked />
|
||||
<label for="john">John Doe</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="jane" name="drone" value="jane" />
|
||||
<label for="jane">Jane Doe</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="johnny" name="drone" value="johnny" />
|
||||
<label for="johnny">Johnny Doe</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<br />
|
||||
|
||||
<input type="checkbox" name="remember" id="remember" checked />
|
||||
<label for="remember">Remember me</label>
|
||||
|
||||
<input type="submit" value="Submit" />
|
||||
<input type="reset" value="Reset" />
|
||||
</form>
|
||||
|
||||
<h3 id="code">Code</h3>
|
||||
<p>
|
||||
Below is some code, you can copy it with <kbd>Ctrl-C</kbd>. Did you know,
|
||||
<code>alert(1)</code> can show an alert in JavaScript!
|
||||
</p>
|
||||
<pre><code>// This logs a message to the console and check out the scrollbar.<br>console.log('Hello, world!')</code></pre>
|
||||
|
||||
<h3 id="other">Other</h3>
|
||||
<p>Here's a horizontal rule and image because I don't know where else to put them.</p>
|
||||
<img src="https://placekitten.com/408/287" alt="Example kitten" />
|
||||
<hr />
|
||||
|
||||
<p>And here's a nicely marked up table!</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Quantity</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Godzilla</td>
|
||||
<td>2</td>
|
||||
<td>$299.99</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mozilla</td>
|
||||
<td>10</td>
|
||||
<td>$100,000.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Quesadilla</td>
|
||||
<td>1</td>
|
||||
<td>$2.22</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<details>
|
||||
<summary>Some summary/details can't hurt!</summary>
|
||||
<p>Lorem ipsum dolor sit blah blah.</p>
|
||||
</details>
|
||||
|
||||
<p>The dialog (form, and menu) tag</p>
|
||||
|
||||
<div>
|
||||
<button type="button" id="dialog-trigger">
|
||||
Show me the dialog!
|
||||
</button>
|
||||
<span id="dialog-result"></span>
|
||||
</div>
|
||||
|
||||
<dialog id="dialog">
|
||||
<header>This is a sample dialog</header>
|
||||
<form method="dialog">
|
||||
<p>What is your favorite pet animal?</p>
|
||||
<menu>
|
||||
<button value="feline">Cats</button>
|
||||
<button value="canine">Dogs</button>
|
||||
<button value="other">Others</button>
|
||||
</menu>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<h3 id="typography">Typography</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque dictum hendrerit velit, quis
|
||||
ullamcorper sem congue ac. Quisque id magna rhoncus, sodales massa vel, vestibulum elit. Duis
|
||||
ornare accumsan egestas. Proin maximus lacus interdum leo molestie convallis. Orci varius
|
||||
natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut iaculis risus eu
|
||||
felis feugiat, eu mollis neque elementum. Donec interdum, nisl id dignissim iaculis, felis dui
|
||||
aliquet dui, non fermentum velit lectus ac quam. Class aptent taciti sociosqu ad litora
|
||||
torquent per conubia nostra, per inceptos himenaeos.
|
||||
<strong>This is strong,</strong> this is normal, <b>this is just bold,</b>
|
||||
<em>and this is emphasized!</em> And heck, <a href="/">here</a>'s a link.
|
||||
</p>
|
||||
|
||||
<blockquote cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote">
|
||||
"The HTML blockquote Element (or HTML Block Quotation Element) indicates that the enclosed
|
||||
text is an extended quotation. Usually, this is rendered visually by indentation (see
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote#Usage_notes"
|
||||
>Notes</a
|
||||
>
|
||||
for how to change it). A URL for the source of the quotation may be given using the
|
||||
<code>cite</code> attribute, while a text representation of the source can be given using the
|
||||
<code><cite></code> cite element."
|
||||
|
||||
<footer>
|
||||
<cite>MDN, "The Block Quotation element"</cite>
|
||||
</footer>
|
||||
</blockquote>
|
||||
|
||||
<ul>
|
||||
<li>Unordered list item 1</li>
|
||||
<li>Unordered list item 2</li>
|
||||
<li>Unordered list item 3</li>
|
||||
</ul>
|
||||
<ol>
|
||||
<li>Ordered list item 1</li>
|
||||
<li>Ordered list item 2</li>
|
||||
<li>Ordered list item 3</li>
|
||||
</ol>
|
||||
|
||||
<p>Addresses are also styled to be <strong>awesome</strong>!</p>
|
||||
<address>
|
||||
<a href="mailto:john.doe@example.com">john.doe@example.com</a><br />
|
||||
<a href="tel:778-330-2389">778-330-2389</a><br />
|
||||
<a href="sms:666-666-6666">666-666-6666</a><br />
|
||||
</address>
|
||||
|
||||
<br />
|
||||
|
||||
<h1>Heading 1</h1>
|
||||
<h2>Heading 2</h2>
|
||||
<h3>Heading 3</h3>
|
||||
<h4>Heading 4</h4>
|
||||
<h5>Heading 5</h5>
|
||||
<h6>Heading 6</h6>
|
||||
|
||||
<footer>
|
||||
<a href="#">Back to top ⬆</a>
|
||||
</footer>
|
||||
<script src="script.js" defer></script>
|
||||
<script src="scripts/themer.js" defer></script>
|
||||
<script src="scripts/index.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,88 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const localBase = './water.css/'
|
||||
|
||||
const fileSizes = {
|
||||
dark: 2.57,
|
||||
light: 2.55,
|
||||
auto: 3.27
|
||||
}
|
||||
|
||||
const themeForm = document.getElementById('theme-form')
|
||||
const stylesheet = document.getElementById('js-stylesheet')
|
||||
const startupStylesheet = document.getElementById('js-startup-stylesheet')
|
||||
const productHunt = document.querySelector('#product-hunt > img')
|
||||
const copyButton = document.getElementById('copy-button')
|
||||
const copyButtonFeedback = document.getElementById('copy-button-feedback')
|
||||
const linkSnippets = [].slice.call(document.querySelectorAll('#link-snippet-container > pre'))
|
||||
|
||||
const table = {
|
||||
fileName: document.getElementById('table-file-name'),
|
||||
fileSize: document.getElementById('table-file-size'),
|
||||
theme: document.getElementById('table-theme')
|
||||
}
|
||||
|
||||
const prefersColorScheme = window.matchMedia('(prefers-color-scheme: light)')
|
||||
|
||||
const updateProductHunt = (theme) => {
|
||||
theme = theme || (prefersColorScheme.matches ? 'light' : 'dark')
|
||||
productHunt.src = `https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=150490&theme=${theme}&period=daily`
|
||||
}
|
||||
|
||||
const updateTheme = () => {
|
||||
const theme = themeForm.querySelector('input[name="theme"]:checked').value
|
||||
|
||||
const fileName = `${theme === 'auto' ? 'water' : theme}.min.css`
|
||||
const localUrl = `${localBase}${fileName}`
|
||||
|
||||
stylesheet.href = localUrl
|
||||
|
||||
for (const snippet of linkSnippets) {
|
||||
snippet.hidden = snippet.id.indexOf(theme) === -1
|
||||
}
|
||||
|
||||
table.fileName.innerText = fileName
|
||||
table.fileSize.innerText = `${fileSizes[theme].toFixed(2)} kb`
|
||||
|
||||
if (theme === 'auto') {
|
||||
updateProductHunt()
|
||||
table.theme.innerHTML = `
|
||||
Respects user-defined theme settings using <a style="--links: var(--code)" href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme" target="_blank" rel="noopener"><code>prefers-color-scheme</code></a>.<br>
|
||||
Light in browsers where the theme settings can't be detected.
|
||||
`
|
||||
} else {
|
||||
updateProductHunt(theme)
|
||||
table.theme.innerText = `Theme is forced to ${theme}.`
|
||||
}
|
||||
}
|
||||
|
||||
themeForm.addEventListener('change', updateTheme)
|
||||
|
||||
updateProductHunt()
|
||||
prefersColorScheme.addListener(() => {
|
||||
if (themeForm.theme.value !== 'auto') return
|
||||
updateProductHunt()
|
||||
})
|
||||
|
||||
updateTheme()
|
||||
startupStylesheet.parentElement.removeChild(startupStylesheet)
|
||||
|
||||
copyButton.addEventListener('click', () => {
|
||||
const clipboard = navigator.clipboard || window.clipboard
|
||||
const theme = themeForm.querySelector('input[name="theme"]:checked').value
|
||||
const snippetText = document.querySelector(`#link-snippet-${theme} code`).textContent
|
||||
|
||||
clipboard.writeText(snippetText)
|
||||
.then(() => { copyButtonFeedback.textContent = '✔' })
|
||||
.catch(() => { copyButtonFeedback.textContent = '❌' })
|
||||
.then(() => setTimeout(() => { copyButtonFeedback.textContent = '' }, 1000))
|
||||
})
|
||||
|
||||
document.getElementById('dialog-trigger').addEventListener('click', () => {
|
||||
document.getElementById('dialog-result').innerText = ''
|
||||
document.getElementById('dialog').showModal()
|
||||
})
|
||||
|
||||
document.getElementById('dialog').addEventListener('close', (event) => {
|
||||
document.getElementById('dialog-result').innerText = `Your answer: ${event.target.returnValue}`
|
||||
})
|
407
docs/scripts/docs.js
Normal file
407
docs/scripts/docs.js
Normal file
@@ -0,0 +1,407 @@
|
||||
const categories = [
|
||||
{
|
||||
id: 'typography',
|
||||
name: 'Typography',
|
||||
description: 'HTML, being a markup language, has abundantly clear semantics for basic typography. Water.css leaves those semantics untouched.',
|
||||
snippets: [
|
||||
{
|
||||
id: 'copy',
|
||||
name: 'Headings and copy',
|
||||
code: `
|
||||
<h1>Heading 1</h1>
|
||||
<p>
|
||||
This is a paragraph that could contain long-form text. Heck, <a href="#">here's a link</a>.
|
||||
<strong>This is important,</strong> this is normal, <em>and this is emphasized!</em>
|
||||
</p>
|
||||
<p>This is another paragraph that could contain long-form text.</p>
|
||||
|
||||
<h2>Heading 2</h2>
|
||||
<p>You probably get the idea by now!</p>
|
||||
|
||||
<h3>Heading 3</h3>
|
||||
<h4>Heading 4</h4>
|
||||
<h5>Heading 5</h5>
|
||||
<h5>Heading 6</h5>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'quotes',
|
||||
name: 'Quotes',
|
||||
code: `
|
||||
<blockquote cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote">
|
||||
"The HTML blockquote Element (or HTML Block Quotation Element) indicates that the enclosed text is an extended quotation. Usually, this is rendered visually by indentation (see <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote#Usage_notes">Notes</a> for how to change it). A URL for the source of the quotation may be given using the <code>cite</code> attribute, while a text representation of the source can be given using the <code><cite></code> cite element."
|
||||
<footer>
|
||||
<cite>MDN, "The Block Quotation element"</cite>
|
||||
</footer>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Did you know HTML supports inline quotes? I didn't, until I read that
|
||||
<q cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q">
|
||||
the <code><q></code> HTML element indicates that the enclosed text is a short inline quotation
|
||||
</q>.
|
||||
</p>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'lists',
|
||||
name: 'Lists',
|
||||
code: `
|
||||
<ul>
|
||||
<li>Unordered list item 1</li>
|
||||
<li>Unordered list item 2</li>
|
||||
<li>Unordered list item 3</li>
|
||||
</ul>
|
||||
<ol>
|
||||
<li>Ordered list item 1</li>
|
||||
<li>Ordered list item 2</li>
|
||||
<li>Ordered list item 3</li>
|
||||
</ol>
|
||||
<dl>
|
||||
<dt>Unordered lists</dt>
|
||||
<dd>Represents an unordered list of items, typically rendered as a bulleted list</dd>
|
||||
<dt>Ordered lists</dt>
|
||||
<dd>Represents an ordered list of items, typically rendered as a numbered list</dd>
|
||||
<dt>Description lists</dt>
|
||||
<dd>Encloses a list of groups of terms and descriptions</dd>
|
||||
<dd>Not commonly used, but still nifty</dd>
|
||||
</dl>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'code-etc',
|
||||
name: 'Code samples, keyboard shortcuts, oh my',
|
||||
code: `
|
||||
<p>
|
||||
Below is some code. If you select it, you can copy using <kbd>Ctrl-C</kbd>.
|
||||
Did you know that <code>alert(1)</code> can show an alert in JavaScript?
|
||||
</p>
|
||||
<pre><code>// This logs a message to the console and check out the scrollbar.
|
||||
console.log('Hello, world!')</code></pre>
|
||||
|
||||
<p>HTML also has elements for <var>variables</var> and sample output: <samp>Hello, world!</samp></p>
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'forms',
|
||||
name: 'Form controls',
|
||||
description: 'Water.css provides a set of styles for form controls, including text inputs, select boxes, buttons, and more.',
|
||||
snippets: [
|
||||
{
|
||||
id: 'text-inputs',
|
||||
name: 'Text inputs',
|
||||
code: `
|
||||
<form onsubmit="return false;">
|
||||
<label for="email">Email</label>
|
||||
<input type="email" name="email" id="email" placeholder="john.doe@gmail.com" />
|
||||
|
||||
<label for="id">User id (read only)</label>
|
||||
<input readonly name="id" id="id" value="04D6H89Z" />
|
||||
|
||||
<label for="disabled">Random disabled input</label>
|
||||
<input disabled name="disabled" id="disabled" placeholder="Because why not?" />
|
||||
|
||||
<label for="about">About me</label>
|
||||
<textarea name="about" id="about" placeholder="I am a textarea..."></textarea>
|
||||
</form>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'buttons',
|
||||
name: 'Buttons',
|
||||
code: `
|
||||
<button onclick="alert('Clicked!')">Hey look, a button!</button>
|
||||
<br>
|
||||
<form onsubmit="alert('Form submitted!'); return false;">
|
||||
<label for="name-field">Your name</label>
|
||||
<input type="text" id="name-field" name="name" />
|
||||
<input type="submit" value="Submit" />
|
||||
<input type="reset" value="Reset" />
|
||||
</form>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'assorted-inputs',
|
||||
name: 'Assorted other controls',
|
||||
code: `
|
||||
<form onsubmit="return false;">
|
||||
<label for="rating">Rate this site</label>
|
||||
<input name="rating" id="rating" type="range" min="1" max="10"></input>
|
||||
|
||||
<label for="flavor">Choose a flavor</label>
|
||||
<select name="flavor" id="flavor">
|
||||
<option>Chocolate</option>
|
||||
<option>Strawberry</option>
|
||||
<option>Vanilla</option>
|
||||
</select>
|
||||
|
||||
<fieldset>
|
||||
<legend>Choose a Doe</legend>
|
||||
<div>
|
||||
<input type="radio" id="john" name="drone" value="john" checked />
|
||||
<label for="john">John Doe</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="jane" name="drone" value="jane" />
|
||||
<label for="jane">Jane Doe</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="johnny" name="drone" value="johnny" />
|
||||
<label for="johnny">Johnny Doe</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<input type="checkbox" name="remember" id="remember" checked />
|
||||
<label for="remember">Remember me</label>
|
||||
</form>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'dialogs',
|
||||
name: 'Dialogs',
|
||||
caniuse: 'https://caniuse.com/dialog',
|
||||
code: `
|
||||
<div>
|
||||
<button type="button" id="dialog-trigger">
|
||||
Show me the dialog!
|
||||
</button>
|
||||
<span id="dialog-result"></span>
|
||||
</div>
|
||||
|
||||
<dialog id="dialog">
|
||||
<header>This is a sample dialog</header>
|
||||
<form method="dialog">
|
||||
<p>What is your favorite pet animal?</p>
|
||||
<menu>
|
||||
<button value="feline">Cats</button>
|
||||
<button value="canine">Dogs</button>
|
||||
<button value="other">Others</button>
|
||||
</menu>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<script>
|
||||
document.getElementById('dialog-trigger').addEventListener('click', () => {
|
||||
document.getElementById('dialog-result').innerText = ''
|
||||
document.getElementById('dialog').showModal()
|
||||
})
|
||||
|
||||
document.getElementById('dialog').addEventListener('close', (event) => {
|
||||
document.getElementById('dialog-result').innerText = \`Your answer: \${event.target.returnValue}\`
|
||||
})
|
||||
</script>
|
||||
`,
|
||||
realCode: `
|
||||
<div>
|
||||
<button type="button" id="dialog-trigger">
|
||||
Show me the dialog!
|
||||
</button>
|
||||
<span id="dialog-result"></span>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'misc',
|
||||
name: 'Miscellaneous',
|
||||
description: 'Styles are also provided for various other elements that don\'t strictly fit into the other categories. These include tables, dialogs, and images.',
|
||||
snippets: [
|
||||
{
|
||||
id: 'tables',
|
||||
name: 'Tables',
|
||||
code: `
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Quantity</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Godzilla</td>
|
||||
<td>2</td>
|
||||
<td>$299.99</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mozilla</td>
|
||||
<td>10</td>
|
||||
<td>$100,000.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Quesadilla</td>
|
||||
<td>1</td>
|
||||
<td>$2.22</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'details',
|
||||
name: 'Summary/details',
|
||||
caniuse: 'https://caniuse.com/details',
|
||||
code: `
|
||||
<details>
|
||||
<summary>Some summary/details can't hurt!</summary>
|
||||
<p>Lorem ipsum dolor sit blah blah.</p>
|
||||
</details>
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'rules-etc',
|
||||
name: 'Rules, images, and addresses',
|
||||
code: `
|
||||
<p>Here's a horizontal rule and image because I don't know where else to put them.</p>
|
||||
<img src="https://placekitten.com/408/287" alt="Example kitten" />
|
||||
<hr />
|
||||
|
||||
<p>Addresses are also styled to be <strong>awesome</strong>!</p>
|
||||
<address>
|
||||
<a href="mailto:john.doe@example.com">john.doe@example.com</a><br>
|
||||
<a href="tel:778-330-2389">778-330-2389</a><br>
|
||||
<a href="sms:666-666-6666">666-666-6666</a><br>
|
||||
</address>
|
||||
`
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const tocContainer = document.getElementById('toc')
|
||||
for (const category of categories) {
|
||||
const li = document.createElement('li')
|
||||
const a = document.createElement('a')
|
||||
a.href = `#${category.id}`
|
||||
a.innerText = category.name
|
||||
li.appendChild(a)
|
||||
|
||||
const ul = document.createElement('ul')
|
||||
for (const snippet of category.snippets) {
|
||||
const li = document.createElement('li')
|
||||
const a = document.createElement('a')
|
||||
a.href = `#${snippet.id}`
|
||||
a.innerText = snippet.name
|
||||
li.appendChild(a)
|
||||
ul.appendChild(li)
|
||||
}
|
||||
|
||||
li.appendChild(ul)
|
||||
tocContainer.appendChild(li)
|
||||
}
|
||||
|
||||
const demosContainer = document.getElementById('demos')
|
||||
let first = true
|
||||
for (const category of categories) {
|
||||
const h2 = document.createElement('h2')
|
||||
h2.id = category.id
|
||||
h2.innerText = category.name
|
||||
demosContainer.appendChild(h2)
|
||||
|
||||
const p = document.createElement('p')
|
||||
p.innerText = category.description
|
||||
demosContainer.appendChild(p)
|
||||
|
||||
for (const snippet of category.snippets) {
|
||||
const h3 = document.createElement('h3')
|
||||
h3.id = snippet.id
|
||||
h3.innerText = snippet.name
|
||||
demosContainer.appendChild(h3)
|
||||
|
||||
if (snippet.caniuse) {
|
||||
const p = document.createElement('p')
|
||||
p.innerText = '⚠️ This may not be supported in all browsers. '
|
||||
const a = document.createElement('a')
|
||||
a.href = snippet.caniuse
|
||||
a.target = '_blank'
|
||||
a.rel = 'noopener noreferrer'
|
||||
a.innerText = 'See caniuse for more info.'
|
||||
p.appendChild(a)
|
||||
demosContainer.appendChild(p)
|
||||
}
|
||||
|
||||
const pre = document.createElement('pre')
|
||||
const code = document.createElement('code')
|
||||
code.innerText = snippet.code.trim()
|
||||
code.style.position = 'relative'
|
||||
|
||||
const button = document.createElement('button')
|
||||
button.innerText = 'Copy'
|
||||
Object.assign(button.style, {
|
||||
position: 'absolute',
|
||||
top: '0',
|
||||
right: '0',
|
||||
margin: '6px',
|
||||
padding: '8px'
|
||||
})
|
||||
|
||||
let timeout = null
|
||||
button.addEventListener('click', () => {
|
||||
navigator.clipboard.writeText(snippet.code.trim())
|
||||
button.innerText = 'Copied!'
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(() => { button.innerText = 'Copy' }, 1000)
|
||||
})
|
||||
|
||||
code.appendChild(button)
|
||||
|
||||
pre.appendChild(code)
|
||||
demosContainer.appendChild(pre)
|
||||
|
||||
const details = document.createElement('details')
|
||||
details.id = `${snippet.id}-details`
|
||||
details.innerHTML = snippet.realCode || snippet.code
|
||||
|
||||
// Execute any scripts in the HTML.
|
||||
Array.from(details.querySelectorAll('script')).forEach((oldScript) => {
|
||||
const newScript = document.createElement('script')
|
||||
for (const { name, value } of oldScript.attributes) { newScript.setAttribute(name, value) }
|
||||
newScript.appendChild(document.createTextNode(oldScript.innerHTML))
|
||||
oldScript.parentNode.replaceChild(newScript, oldScript)
|
||||
})
|
||||
|
||||
const summary = document.createElement('summary')
|
||||
summary.innerText = 'Show output'
|
||||
details.prepend(summary)
|
||||
demosContainer.appendChild(details)
|
||||
|
||||
if (first) {
|
||||
details.open = true
|
||||
first = false
|
||||
|
||||
let firstToggle = true
|
||||
details.addEventListener('toggle', () => {
|
||||
if (!details.open || firstToggle) return
|
||||
firstToggle = false
|
||||
history.pushState({}, '', '#' + snippet.id)
|
||||
})
|
||||
} else {
|
||||
details.addEventListener('toggle', () => {
|
||||
if (!details.open) return
|
||||
history.pushState({}, '', '#' + snippet.id)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hashChange = () => {
|
||||
const details = document.getElementById(`${window.location.hash.slice(1)}-details`)
|
||||
if (!details) return
|
||||
details.open = true
|
||||
}
|
||||
window.addEventListener('hashchange', hashChange, false)
|
||||
hashChange()
|
||||
|
||||
// Dialog demo scripting.
|
||||
document.getElementById('dialog-trigger').addEventListener('click', () => {
|
||||
document.getElementById('dialog-result').innerText = ''
|
||||
document.getElementById('dialog').showModal()
|
||||
})
|
||||
|
||||
document.getElementById('dialog').addEventListener('close', (event) => {
|
||||
document.getElementById('dialog-result').innerText = `Your answer: ${event.target.returnValue}`
|
||||
})
|
14
docs/scripts/index.js
Normal file
14
docs/scripts/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const copyButton = document.getElementById('copy-button')
|
||||
const copyButtonFeedback = document.getElementById('copy-button-feedback')
|
||||
const themeForm = document.getElementById('theme-form')
|
||||
|
||||
copyButton.addEventListener('click', () => {
|
||||
const clipboard = navigator.clipboard || window.clipboard
|
||||
const theme = themeForm.querySelector('input[name="theme"]:checked').value
|
||||
const snippetText = document.querySelector(`#link-snippet-${theme} code`).textContent
|
||||
|
||||
clipboard.writeText(snippetText)
|
||||
.then(() => { copyButtonFeedback.textContent = '✅' })
|
||||
.catch(() => { copyButtonFeedback.textContent = '❌' })
|
||||
.then(() => setTimeout(() => { copyButtonFeedback.textContent = '' }, 1000))
|
||||
})
|
73
docs/scripts/themer.js
Normal file
73
docs/scripts/themer.js
Normal file
@@ -0,0 +1,73 @@
|
||||
'use strict'
|
||||
|
||||
const localBase = './water.css/'
|
||||
|
||||
const fileSizes = {
|
||||
dark: 2.57,
|
||||
light: 2.55,
|
||||
auto: 3.27
|
||||
}
|
||||
|
||||
const themeForm = document.getElementById('theme-form')
|
||||
const stylesheet = document.getElementById('js-stylesheet')
|
||||
const startupStylesheet = document.getElementById('js-startup-stylesheet')
|
||||
const productHunt = document.getElementById('product-hunt')
|
||||
const linkSnippets = [...document.querySelectorAll('#link-snippet-container > pre')]
|
||||
|
||||
const table = {
|
||||
fileName: document.getElementById('table-file-name'),
|
||||
fileSize: document.getElementById('table-file-size'),
|
||||
theme: document.getElementById('table-theme')
|
||||
}
|
||||
|
||||
const prefersColorScheme = window.matchMedia('(prefers-color-scheme: light)')
|
||||
|
||||
const updateProductHunt = (theme) => {
|
||||
if (!productHunt) return
|
||||
theme = theme || (prefersColorScheme.matches ? 'light' : 'dark')
|
||||
productHunt.src = `https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=150490&theme=${theme}&period=daily`
|
||||
}
|
||||
|
||||
const updateTheme = () => {
|
||||
const theme = document.querySelector('input[name="theme"]:checked').value
|
||||
localStorage.setItem('theme', theme)
|
||||
|
||||
const fileName = `${theme === 'auto' ? 'water' : theme}.min.css`
|
||||
const localUrl = `${localBase}${fileName}`
|
||||
|
||||
stylesheet.href = localUrl
|
||||
|
||||
for (const snippet of linkSnippets) {
|
||||
snippet.hidden = snippet.id.indexOf(theme) === -1
|
||||
}
|
||||
|
||||
if (table.theme) {
|
||||
table.fileName.innerText = fileName
|
||||
table.fileSize.innerText = `${fileSizes[theme].toFixed(2)} kb`
|
||||
|
||||
if (theme === 'auto') {
|
||||
updateProductHunt()
|
||||
table.theme.innerHTML = `
|
||||
Respects user-defined theme settings using <a style="--links: var(--code)" href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme" target="_blank" rel="noopener"><code>prefers-color-scheme</code></a>.<br>
|
||||
Light in browsers where the theme settings can't be detected.
|
||||
`
|
||||
} else {
|
||||
updateProductHunt(theme)
|
||||
table.theme.innerText = `Theme is forced to ${theme}.`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const storedTheme = localStorage.getItem('theme')
|
||||
if (storedTheme) {
|
||||
themeForm.querySelector(`input[name="theme"][value="${storedTheme}"]`).checked = true
|
||||
}
|
||||
|
||||
updateTheme()
|
||||
themeForm.addEventListener('change', updateTheme)
|
||||
startupStylesheet.parentElement.removeChild(startupStylesheet)
|
||||
|
||||
prefersColorScheme.addListener(() => {
|
||||
if (themeForm.theme.value !== 'auto') return
|
||||
updateProductHunt()
|
||||
})
|
@@ -1,7 +1,3 @@
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
#product-hunt {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
@@ -63,3 +59,14 @@ body > footer {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Hmmm yes great class name */
|
||||
.top-theme-form {
|
||||
padding: 10px 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
position: sticky;
|
||||
margin-top: -20px;
|
||||
z-index: 999;
|
||||
background: var(--background-body);
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ const postcssImport = require('postcss-import')
|
||||
const postcssInlineSvg = require('postcss-inline-svg')
|
||||
|
||||
const paths = {
|
||||
docs: { src: 'docs/**', dest: 'out/docs' },
|
||||
docs: { src: 'docs/**/*', dest: 'out/docs' },
|
||||
styles: { src: 'src/builds/*.css', dest: 'out', watch: 'src/**/*.css' }
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ const docs = () => {
|
||||
|
||||
return (
|
||||
gulp
|
||||
// Exclude all HTML files but index.html
|
||||
.src(paths.docs.src, { ignore: '**/!(index).html' })
|
||||
// Exclude all HTML files except for those ending with .html
|
||||
.src(paths.docs.src, { ignore: '**/!(*).html' })
|
||||
|
||||
// * Process HTML *
|
||||
.pipe(htmlOnly)
|
||||
|
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"build": "gulp build",
|
||||
"dev": "gulp watch",
|
||||
"lint:js": "eslint bookmarklet/original.js docs/script.js docs/index.html gulpfile.js",
|
||||
"lint:js": "eslint bookmarklet/original.js docs/scripts/*.js docs/*.html gulpfile.js",
|
||||
"lint:css": "stylelint src/**/*.css docs/style.css",
|
||||
"lint": "yarn lint:js --fix && yarn lint:css --fix",
|
||||
"accessibility": "yarn build && node accessibility.js",
|
||||
|
@@ -114,7 +114,7 @@ summary:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
details > :not(summary) {
|
||||
details > :not(summary):first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@@ -151,6 +151,11 @@ footer {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
body > footer {
|
||||
body > footer:last-of-type {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
body > header:first-of-type {
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
@@ -78,3 +78,17 @@ a > code,
|
||||
a > strong {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 600;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 5px 0;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
dd + dt {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
5
swift-dots-run.md
Normal file
5
swift-dots-run.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"water.css": patch
|
||||
---
|
||||
|
||||
Add comprehensive element documentation
|
Reference in New Issue
Block a user