Travis build: 407

This commit is contained in:
30secondsofcode
2019-08-26 10:03:49 +00:00
parent 2776b342dd
commit 983bc086c1
57 changed files with 376 additions and 873 deletions

View File

@ -25,7 +25,7 @@ Here's what you can do to help:
- All snippet titles must be prefixed with `title:` and be at the very first line of your snippet's frontmatter.
- Snippet titles must be unique (although if you cannot find a better title, just add some placeholder at the end of the filename and title and we will figure it out).
- Follow snippet titles with an empty line.
- **Snippet descriptions** must be short and to the point. Try to explain *what* the snippet does and *how* the snippet works and what Javascript features are used. Remember to include what functions you are using and why.
- **Snippet descriptions** must be short and to the point. Try to explain _what_ the snippet does and _how_ the snippet works and what Javascript features are used. Remember to include what functions you are using and why.
- Follow snippet descriptions with an empty line.
- **Snippet code** must be enclosed inside ` ```html `, ` ```css ` or ` ```js ` and ` ``` `.
- Remember to start your snippet's code on a new line below the opening backticks.
@ -38,6 +38,6 @@ Here's what you can do to help:
- **Snippet browser support** should be specified as a list of links to https://www.caniuse.com/ features.
- Use the `#` next to the feature that you want in the website to get a link to it.
- Snippets should be short. If your snippet is long, you can still submit it, and we can help you shorten it or figure out ways to improve it.
- Snippets *should* solve real-world problems, no matter how simple.
- Snippets *should* be abstract enough to be applied to different scenarios.
- Snippets _should_ solve real-world problems, no matter how simple.
- Snippets _should_ be abstract enough to be applied to different scenarios.
- You can start creating a new snippet, by using the [snippet template](snippet-template.md) to format your snippets.

125
README.md
View File

@ -173,9 +173,6 @@ Note: `1rem` is usually `16px`.
- https://caniuse.com/#feat=css-animation
<br>[⬆ Back to top](#contents)
### Button border animation
@ -281,9 +278,6 @@ Creates a donut spinner that can be used to indicate the loading of content.
- https://caniuse.com/#feat=css-animation
- https://caniuse.com/#feat=transforms2d
<br>[⬆ Back to top](#contents)
### Easing variables
@ -351,9 +345,6 @@ powerful than the built-in `ease`, `ease-in`, `ease-out` and `ease-in-out`.
- https://caniuse.com/#feat=css-variables
<br>[⬆ Back to top](#contents)
### Height transition
@ -393,7 +384,9 @@ el.style.setProperty('--max-height', height + 'px')
2. `overflow: hidden` prevents the contents of the hidden element from overflowing its container.
3. `max-height: 0` specifies that the element has no height initially.
4. `.target:hover > .el` specifies that when the parent is hovered over, target a child `.el` within it and use the `--max-height` variable which was defined by JavaScript.
---
1. `el.scrollHeight` is the height of the element including overflow, which will change dynamically based on the content of the element.
2. `el.style.setProperty(...)` sets the `--max-height` CSS variable which is used to specify the `max-height` of the element the target is hovered over, allowing it to transition smoothly from 0 to auto.
@ -411,9 +404,6 @@ el.style.setProperty('--max-height', height + 'px')
- https://caniuse.com/#feat=css-variables
- https://caniuse.com/#feat=css-transitions
<br>[⬆ Back to top](#contents)
### Hover shadow box animation
@ -462,9 +452,6 @@ Creates a shadow box around the text when it is hovered.
- https://caniuse.com/#feat=transforms3d
- https://caniuse.com/#feat=css-transitions
<br>[⬆ Back to top](#contents)
### Hover underline animation
@ -524,9 +511,6 @@ Creates an animated underline effect when the text is hovered over.
- https://caniuse.com/#feat=transforms2d
- https://caniuse.com/#feat=css-transitions
<br>[⬆ Back to top](#contents)
---
@ -566,9 +550,6 @@ Makes the content unselectable.
- https://caniuse.com/#feat=user-select-none
<br>[⬆ Back to top](#contents)
### Popout menu
@ -618,9 +599,6 @@ Reveals an interactive popout menu on hover and focus.
100.0%
<br>[⬆ Back to top](#contents)
### Sibling fade
@ -660,9 +638,6 @@ span {
- https://caniuse.com/#feat=css-sel3
- https://caniuse.com/#feat=css-transitions
<br>[⬆ Back to top](#contents)
---
@ -716,9 +691,6 @@ html {
- https://caniuse.com/#feat=css3-boxsizing
<br>[⬆ Back to top](#contents)
### Clearfix
@ -762,9 +734,6 @@ Ensures that an element self-clears its children.
<span class="snippet__support-note">⚠️ For this snippet to work properly you need to ensure that there are no non-floating children in the container and that there are no tall floats before the clearfixed container but in the same formatting context (e.g. floated columns).</span>
<br>[⬆ Back to top](#contents)
### Constant width to height ratio
@ -805,9 +774,6 @@ Given an element of variable width, it will ensure its height remains proportion
100.0%
<br>[⬆ Back to top](#contents)
### Display table centering
@ -859,9 +825,6 @@ Vertically and horizontally centers a child element within its parent element us
- https://caniuse.com/#search=display%3A%20table
<br>[⬆ Back to top](#contents)
### Evenly distributed children
@ -901,9 +864,6 @@ Evenly distributes child elements within a parent element.
- https://caniuse.com/#feat=flexbox
<br>[⬆ Back to top](#contents)
### Fit image in container
@ -985,9 +945,6 @@ Horizontally and vertically centers a child element within a parent element usin
- https://caniuse.com/#feat=flexbox
<br>[⬆ Back to top](#contents)
### Ghost trick
@ -1032,9 +989,6 @@ p {
- https://caniuse.com/#feat=inline-block
<br>[⬆ Back to top](#contents)
### Grid centering
@ -1069,9 +1023,6 @@ Horizontally and vertically centers a child element within a parent element usin
- https://caniuse.com/#feat=css-grid
<br>[⬆ Back to top](#contents)
### Last item with remaining available height
@ -1171,9 +1122,6 @@ A bulletproof way to completely hide an element visually and positionally in the
- https://caniuse.com/#search=clip
<br>[⬆ Back to top](#contents)
### Transform centering
@ -1220,9 +1168,6 @@ Vertically and horizontally centers a child element within its parent element us
- https://caniuse.com/#feat=transforms2d
<br>[⬆ Back to top](#contents)
### Truncate text multiline
@ -1276,9 +1221,6 @@ If the text is longer than one line, it will be truncated for `n` lines and end
- https://caniuse.com/#feat=css-gradients
<br>[⬆ Back to top](#contents)
### Truncate text
@ -1316,9 +1258,6 @@ If the text is longer than one line, it will be truncated and end with an ellips
- https://caniuse.com/#feat=text-overflow
<br>[⬆ Back to top](#contents)
---
@ -1358,9 +1297,6 @@ The function calc() allows to define CSS values with the use of mathematical exp
- https://caniuse.com/#feat=calc
<br>[⬆ Back to top](#contents)
### Custom variables
@ -1403,9 +1339,6 @@ CSS variables that contain specific values to be reused throughout a document.
- https://caniuse.com/#feat=css-variables
<br>[⬆ Back to top](#contents)
---
@ -1444,9 +1377,6 @@ Creates a circle shape with pure CSS.
- https://caniuse.com/#feat=border-radius
<br>[⬆ Back to top](#contents)
### Counter
@ -1498,9 +1428,6 @@ li::before {
- https://caniuse.com/#feat=css-counters
<br>[⬆ Back to top](#contents)
### Custom scrollbar
@ -1560,9 +1487,6 @@ There are many other pseudo-elements that you can use to style scrollbars. For m
- https://caniuse.com/#feat=css-scrollbar
<br>[⬆ Back to top](#contents)
### Custom text selection
@ -1600,9 +1524,6 @@ in any specification.</span>
- https://caniuse.com/#feat=css-selection
<br>[⬆ Back to top](#contents)
### Dynamic shadow
@ -1658,9 +1579,6 @@ Creates a shadow similar to `box-shadow` but based on the colors of the element
- https://caniuse.com/#feat=css-filters
<br>[⬆ Back to top](#contents)
### Etched text
@ -1695,9 +1613,6 @@ Creates an effect where text appears to be "etched" or engraved into the backgro
- https://caniuse.com/#feat=css-textshadow
<br>[⬆ Back to top](#contents)
### Focus Within
@ -1744,9 +1659,6 @@ If no link is provided, it defaults to 99+%. -->
- https://caniuse.com/#feat=css-focus-within
<br>[⬆ Back to top](#contents)
### Fullscreen
@ -1808,9 +1720,6 @@ The :fullscreen CSS pseudo-class represents an element that's displayed when the
- https://developer.mozilla.org/en-US/docs/Web/CSS/:fullscreen
- https://caniuse.com/#feat=fullscreen
<br>[⬆ Back to top](#contents)
### Gradient text
@ -1846,9 +1755,6 @@ Gives text a gradient color.
- https://caniuse.com/#feat=text-stroke
<br>[⬆ Back to top](#contents)
### Hairline border
@ -1905,9 +1811,6 @@ very sharp and crisp.
\*Chrome does not support subpixel values on `border`. Safari does not support subpixel values on `box-shadow`. Firefox supports subpixel values on both.
<br>[⬆ Back to top](#contents)
### Mouse cursor gradient tracking
@ -1982,9 +1885,6 @@ btn.onmousemove = function(e) {
- https://caniuse.com/#feat=css-variables
<br>[⬆ Back to top](#contents)
### :not selector
@ -2033,9 +1933,6 @@ li:not(:last-child) {
- https://caniuse.com/#feat=css-sel3
<br>[⬆ Back to top](#contents)
### Overflow scroll gradient
@ -2103,9 +2000,6 @@ Adds a fading gradient to an overflowing element to better indicate there is mor
- https://caniuse.com/#feat=css-gradients
<br>[⬆ Back to top](#contents)
### Pretty text underline
@ -2153,9 +2047,6 @@ Natively implemented as `text-decoration-skip-ink: auto` but it has less control
- https://caniuse.com/#feat=css-textshadow
- https://caniuse.com/#feat=css-gradients
<br>[⬆ Back to top](#contents)
### Reset all styles
@ -2194,9 +2085,6 @@ Resets all styles to default values with one property. This will not affect `dir
- https://caniuse.com/#feat=css-all
<br>[⬆ Back to top](#contents)
### Shape separator
@ -2242,9 +2130,6 @@ Uses an SVG shape to separate two different blocks to create more a interesting
- https://caniuse.com/#feat=svg
<br>[⬆ Back to top](#contents)
### System font stack
@ -2284,9 +2169,6 @@ Uses the native font of the operating system to get close to a native app feel.
100.0%
<br>[⬆ Back to top](#contents)
### Toggle switch
@ -2390,9 +2272,6 @@ Creates a triangle shape with pure CSS.
100.0%
<br>[⬆ Back to top](#contents)
### Zebra striped list

View File

@ -14,5 +14,5 @@ module.exports = {
// General information
language: `css`,
secondLanguage: `html`,
optionalLanguage: `js`,
};
optionalLanguage: `js`
}

View File

@ -5,4 +5,4 @@
*/
// You can delete this file if you're not using it
export { default as wrapRootElement } from './src/docs/state/ReduxWrapper';
export { default as wrapRootElement } from './src/docs/state/ReduxWrapper'

View File

@ -1,11 +1,11 @@
const config = require('./config');
const config = require('./config')
module.exports = {
siteMetadata: {
title: `${config.name}`,
description: `${config.description}`,
author: `@30-seconds`,
siteUrl: `${config.siteUrl}`,
siteUrl: `${config.siteUrl}`
},
plugins: [
`gatsby-plugin-sitemap`,
@ -14,28 +14,28 @@ module.exports = {
resolve: `gatsby-source-filesystem`,
options: {
name: `snippets`,
path: `${__dirname}/${config.snippetPath}`,
},
path: `${__dirname}/${config.snippetPath}`
}
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `snippet_data`,
path: `${__dirname}/${config.snippetDataPath}`,
},
path: `${__dirname}/${config.snippetDataPath}`
}
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `assets`,
path: `${__dirname}/${config.assetPath}`,
},
path: `${__dirname}/${config.assetPath}`
}
},
{
resolve: `gatsby-plugin-page-creator`,
options: {
path: `${__dirname}/${config.pagePath}`,
},
path: `${__dirname}/${config.pagePath}`
}
},
{
resolve: `gatsby-transformer-remark`,
@ -44,13 +44,13 @@ module.exports = {
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 590,
},
maxWidth: 590
}
},
`gatsby-remark-prismjs`,
`gatsby-remark-copy-linked-files`,
],
},
`gatsby-remark-copy-linked-files`
]
}
},
`gatsby-plugin-sass`,
`gatsby-transformer-json`,
@ -62,8 +62,8 @@ module.exports = {
trackingId: `UA-117141635-1`,
anonymize: true, // Always set this to true, try to comply with GDPR out of the box
respectDNT: true, // Always set to true, be respectful of people who ask not to be tracked
cookieExpires: 0, // Always set to 0, minimum tracking for your users
},
cookieExpires: 0 // Always set to 0, minimum tracking for your users
}
},
{
resolve: `gatsby-plugin-manifest`,
@ -74,11 +74,11 @@ module.exports = {
background_color: `#1e253d`,
theme_color: `#1e253d`,
display: `standalone`,
icon: `assets/30s-icon.png`, // This path is relative to the root of the site.
},
icon: `assets/30s-icon.png` // This path is relative to the root of the site.
}
},
`gatsby-plugin-offline`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-netlify`,
],
};
`gatsby-plugin-netlify`
]
}

View File

@ -1,25 +1,22 @@
const path = require(`path`);
const { createFilePath } = require(`gatsby-source-filesystem`);
const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)
const toKebabCase = 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)
.map(x => x.toLowerCase())
.join('-');
.join('-')
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions;
const { createPage } = actions
const snippetPage = path.resolve(`./src/docs/templates/SnippetPage.js`);
const tagPage = path.resolve(`./src/docs/templates/TagPage.js`);
const snippetPage = path.resolve(`./src/docs/templates/SnippetPage.js`)
const tagPage = path.resolve(`./src/docs/templates/TagPage.js`)
return graphql(
`
{
allMarkdownRemark(
sort: { fields: [frontmatter___title], order: ASC }
limit: 1000
) {
allMarkdownRemark(sort: { fields: [frontmatter___title], order: ASC }, limit: 1000) {
edges {
node {
fields {
@ -33,61 +30,60 @@ exports.createPages = ({ graphql, actions }) => {
}
}
}
`,
`
).then(result => {
if (result.errors) {
throw result.errors;
throw result.errors
}
// Create individual snippet pages.
const snippets = result.data.allMarkdownRemark.edges;
const snippets = result.data.allMarkdownRemark.edges
snippets.forEach((post, index) => {
if (post.node.fileAbsolutePath.indexOf('README') !== -1)
return;
if (post.node.fileAbsolutePath.indexOf('README') !== -1) return
createPage({
path: `/snippet${post.node.fields.slug}`,
component: snippetPage,
context: {
slug: post.node.fields.slug,
},
});
});
slug: post.node.fields.slug
}
})
})
// Create tag pages.
const tags = snippets.reduce((acc, post) => {
if (!post.node.frontmatter || !post.node.frontmatter.tags) return acc;
const primaryTag = post.node.frontmatter.tags.split(',')[0];
if (!acc.includes(primaryTag)) acc.push(primaryTag);
return acc;
}, []);
if (!post.node.frontmatter || !post.node.frontmatter.tags) return acc
const primaryTag = post.node.frontmatter.tags.split(',')[0]
if (!acc.includes(primaryTag)) acc.push(primaryTag)
return acc
}, [])
tags.forEach(tag => {
const tagPath = `/tag/${toKebabCase(tag)}/`;
const tagRegex = `/^\\s*${tag}/`;
const tagPath = `/tag/${toKebabCase(tag)}/`
const tagRegex = `/^\\s*${tag}/`
createPage({
path: tagPath,
component: tagPage,
context: {
tag,
tagRegex,
},
});
});
tagRegex
}
})
})
return null;
});
};
return null
})
}
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode });
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
});
value
})
}
};
}

View File

@ -5,4 +5,4 @@
*/
// You can delete this file if you're not using it
export { default as wrapRootElement } from './src/docs/state/ReduxWrapper';
export { default as wrapRootElement } from './src/docs/state/ReduxWrapper'

View File

@ -3,29 +3,22 @@
Run using `npm run builder`.
*/
// Load modules
const fs = require('fs-extra');
const path = require('path');
const { green, red } = require('kleur');
const util = require('./util');
const markdown = require('markdown-builder');
const { headers, misc, lists } = markdown;
const config = require('../config');
const fs = require('fs-extra')
const path = require('path')
const { green, red } = require('kleur')
const util = require('./util')
const markdown = require('markdown-builder')
const { headers, misc, lists } = markdown
const config = require('../config')
// Paths (relative to package.json)
const SNIPPETS_PATH = `./${config.snippetPath}`;
const STATIC_PARTS_PATH = `./${config.staticPartsPath}`;
const SNIPPETS_PATH = `./${config.snippetPath}`
const STATIC_PARTS_PATH = `./${config.staticPartsPath}`
// Terminate if parent commit is a Travis build
if (
util.isTravisCI() &&
/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])
) {
console.log(
`${green(
'NOBUILD',
)} README build terminated, parent commit is a Travis build!`,
);
process.exit(0);
if (util.isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) {
console.log(`${green('NOBUILD')} README build terminated, parent commit is a Travis build!`)
process.exit(0)
}
// Setup everything
@ -33,51 +26,43 @@ let snippets = {},
snippetsArray = [],
startPart = '',
endPart = '',
output = '';
const EMOJIS = {};
output = ''
const EMOJIS = {}
console.time('Builder');
console.time('Builder')
// Synchronously read all snippets from snippets folder and sort them as necessary (case-insensitive)
snippets = util.readSnippets(SNIPPETS_PATH);
snippets = util.readSnippets(SNIPPETS_PATH)
snippetsArray = Object.keys(snippets).reduce((acc, key) => {
acc.push(snippets[key]);
return acc;
}, []);
acc.push(snippets[key])
return acc
}, [])
// Load static parts for the README file
try {
startPart = fs.readFileSync(
path.join(STATIC_PARTS_PATH, 'README-start.md'),
'utf8',
);
endPart = fs.readFileSync(
path.join(STATIC_PARTS_PATH, 'README-end.md'),
'utf8',
);
startPart = fs.readFileSync(path.join(STATIC_PARTS_PATH, 'README-start.md'), 'utf8')
endPart = fs.readFileSync(path.join(STATIC_PARTS_PATH, 'README-end.md'), 'utf8')
} catch (err) {
console.log(`${red('ERROR!')} During static part loading: ${err}`);
process.exit(1);
console.log(`${red('ERROR!')} During static part loading: ${err}`)
process.exit(1)
}
// Create the output for the README file
try {
const tags = util.prepTaggedData(
Object.keys(snippets).reduce((acc, key) => {
acc[key] = snippets[key].attributes.tags;
return acc;
}, {}),
);
acc[key] = snippets[key].attributes.tags
return acc
}, {})
)
output += `${startPart}\n`;
output += `${startPart}\n`
// Loop over tags and snippets to create the table of contents
for (const tag of tags) {
const capitalizedTag = util.capitalize(tag, true);
const taggedSnippets = snippetsArray.filter(
snippet => snippet.attributes.tags[0] === tag,
);
output += headers.h3((EMOJIS[tag] || '') + ' ' + capitalizedTag).trim();
const capitalizedTag = util.capitalize(tag, true)
const taggedSnippets = snippetsArray.filter(snippet => snippet.attributes.tags[0] === tag)
output += headers.h3((EMOJIS[tag] || '') + ' ' + capitalizedTag).trim()
output +=
misc.collapsible(
@ -87,56 +72,49 @@ try {
`\`${snippet.title}\``,
`${misc.anchor(snippet.title)}${
snippet.attributes.tags.includes('advanced') ? '-' : ''
}`,
),
),
) + '\n';
}`
)
)
) + '\n'
}
for (const tag of tags) {
const capitalizedTag = util.capitalize(tag, true);
const taggedSnippets = snippetsArray.filter(
snippet => snippet.attributes.tags[0] === tag,
);
const capitalizedTag = util.capitalize(tag, true)
const taggedSnippets = snippetsArray.filter(snippet => snippet.attributes.tags[0] === tag)
output +=
misc.hr() + headers.h2((EMOJIS[tag] || '') + ' ' + capitalizedTag) + '\n';
output += misc.hr() + headers.h2((EMOJIS[tag] || '') + ' ' + capitalizedTag) + '\n'
for (let snippet of taggedSnippets) {
if (snippet.attributes.tags.includes('advanced'))
output +=
headers.h3(
snippet.title + ' ' + misc.image('advanced', '/advanced.svg'),
) + '\n';
else output += headers.h3(snippet.title) + '\n';
output += headers.h3(snippet.title + ' ' + misc.image('advanced', '/advanced.svg')) + '\n'
else output += headers.h3(snippet.title) + '\n'
output += snippet.attributes.text;
output += snippet.attributes.text
output += `\`\`\`${config.secondLanguage}\n${snippet.attributes.codeBlocks.html}\n\`\`\`\n\n`;
output += `\`\`\`${config.language}\n${snippet.attributes.codeBlocks.css}\n\`\`\`\n\n`;
output += `\`\`\`${config.secondLanguage}\n${snippet.attributes.codeBlocks.html}\n\`\`\`\n\n`
output += `\`\`\`${config.language}\n${snippet.attributes.codeBlocks.css}\n\`\`\`\n\n`
if (snippet.attributes.codeBlocks.js)
output += `\`\`\`${config.optionalLanguage}\n${snippet.attributes.codeBlocks.js}\n\`\`\`\n\n`;
output += `\`\`\`${config.optionalLanguage}\n${snippet.attributes.codeBlocks.js}\n\`\`\`\n\n`
output += headers.h4('Explanation');
output += snippet.attributes.explanation;
output += headers.h4('Explanation')
output += snippet.attributes.explanation
output += headers.h4('Browser support') + '\n';
output += snippet.attributes.browserSupport.supportPercentage.toFixed(1) + '%';
output += snippet.attributes.browserSupport.text;
output += headers.h4('Browser support') + '\n'
output += snippet.attributes.browserSupport.supportPercentage.toFixed(1) + '%'
output += snippet.attributes.browserSupport.text
output +=
'\n<br>' + misc.link('⬆ Back to top', misc.anchor('Contents')) + '\n';
output += '\n<br>' + misc.link('⬆ Back to top', misc.anchor('Contents')) + '\n'
}
}
// Add the ending static part
output += `\n${endPart}\n`;
output += `\n${endPart}\n`
// Write to the README file
fs.writeFileSync('README.md', output);
fs.writeFileSync('README.md', output)
} catch (err) {
console.log(`${red('ERROR!')} During README generation: ${err}`);
process.exit(1);
console.log(`${red('ERROR!')} During README generation: ${err}`)
process.exit(1)
}
console.log(`${green('SUCCESS!')} README file generated!`);
console.timeEnd('Builder');
console.log(`${green('SUCCESS!')} README file generated!`)
console.timeEnd('Builder')

View File

@ -3,15 +3,15 @@
Run using `npm run extractor`.
*/
// Load modules
const fs = require('fs-extra');
const path = require('path');
const { green } = require('kleur');
const util = require('./util');
const config = require('../config');
const fs = require('fs-extra')
const path = require('path')
const { green } = require('kleur')
const util = require('./util')
const config = require('../config')
// Paths (relative to package.json)
const SNIPPETS_PATH = `./${config.snippetPath}`;
const OUTPUT_PATH = `./${config.snippetDataPath}`;
const SNIPPETS_PATH = `./${config.snippetPath}`
const OUTPUT_PATH = `./${config.snippetDataPath}`
// Check if running on Travis, only build for cron jobs and custom builds
if (
@ -19,33 +19,29 @@ if (
process.env['TRAVIS_EVENT_TYPE'] !== 'cron' &&
process.env['TRAVIS_EVENT_TYPE'] !== 'api'
) {
console.log(
`${green(
'NOBUILD',
)} snippet extraction terminated, not a cron or api build!`,
);
process.exit(0);
console.log(`${green('NOBUILD')} snippet extraction terminated, not a cron or api build!`)
process.exit(0)
}
// Setup everything
let snippets = {},
snippetsArray = [];
console.time('Extractor');
snippetsArray = []
console.time('Extractor')
// Synchronously read all snippets from snippets folder and sort them as necessary (case-insensitive)
snippets = util.readSnippets(SNIPPETS_PATH);
snippets = util.readSnippets(SNIPPETS_PATH)
snippetsArray = Object.keys(snippets).reduce((acc, key) => {
acc.push(snippets[key]);
return acc;
}, []);
acc.push(snippets[key])
return acc
}, [])
const completeData = {
data: [...snippetsArray],
meta: {
specification: 'http://jsonapi.org/format/',
type: 'snippetArray',
},
};
type: 'snippetArray'
}
}
let listingData = {
data: completeData.data.map(v => ({
id: v.id,
@ -53,28 +49,20 @@ let listingData = {
title: v.title,
attributes: {
text: v.attributes.text,
tags: v.attributes.tags,
tags: v.attributes.tags
},
meta: {
hash: v.meta.hash,
},
hash: v.meta.hash
}
})),
meta: {
specification: 'http://jsonapi.org/format/',
type: 'snippetListingArray',
},
};
type: 'snippetListingArray'
}
}
// Write files
fs.writeFileSync(
path.join(OUTPUT_PATH, 'snippets.json'),
JSON.stringify(completeData, null, 2),
);
fs.writeFileSync(
path.join(OUTPUT_PATH, 'snippetList.json'),
JSON.stringify(listingData, null, 2),
);
fs.writeFileSync(path.join(OUTPUT_PATH, 'snippets.json'), JSON.stringify(completeData, null, 2))
fs.writeFileSync(path.join(OUTPUT_PATH, 'snippetList.json'), JSON.stringify(listingData, null, 2))
// Display messages and time
console.log(
`${green('SUCCESS!')} snippets.json and snippetList.json files generated!`,
);
console.timeEnd('Extractor');
console.log(`${green('SUCCESS!')} snippets.json and snippetList.json files generated!`)
console.timeEnd('Extractor')

View File

@ -1,12 +1,11 @@
// Checks if current environment is Travis CI, Cron builds, API builds
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env
const isTravisCronOrAPI = () =>
process.env['TRAVIS_EVENT_TYPE'] === 'cron' ||
process.env['TRAVIS_EVENT_TYPE'] === 'api';
const isNotTravisCronOrAPI = () => !isTravisCronOrAPI();
process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env['TRAVIS_EVENT_TYPE'] === 'api'
const isNotTravisCronOrAPI = () => !isTravisCronOrAPI()
module.exports = {
isTravisCI,
isTravisCronOrAPI,
isNotTravisCronOrAPI,
};
isNotTravisCronOrAPI
}

View File

@ -1,4 +1,4 @@
const config = require('../../config');
const config = require('../../config')
const getMarkDownAnchor = paragraphTitle =>
paragraphTitle
@ -6,24 +6,23 @@ const getMarkDownAnchor = paragraphTitle =>
.toLowerCase()
.replace(/[^\w\- ]+/g, '')
.replace(/\s/g, '-')
.replace(/\-+$/, '');
.replace(/\-+$/, '')
// Creates an object from pairs
const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {});
const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {})
// Optimizes nodes in an HTML document
const optimizeNodes = (data, regexp, replacer) => {
let count = 0;
let output = data;
let count = 0
let output = data
do {
output = output.replace(regexp, replacer);
count = 0;
while (regexp.exec(output) !== null) ++count;
} while (count > 0);
return output;
};
output = output.replace(regexp, replacer)
count = 0
while (regexp.exec(output) !== null) ++count
} while (count > 0)
return output
}
// Capitalizes the first letter of a string
const capitalize = (str, lowerRest = false) =>
str.slice(0, 1).toUpperCase() +
(lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1))
const prepTaggedData = tagDbData =>
[...new Set(Object.entries(tagDbData).map(t => t[1][0]))]
.filter(v => v)
@ -32,23 +31,18 @@ const prepTaggedData = tagDbData =>
? 1
: capitalize(b, true) === 'Uncategorized'
? -1
: a.localeCompare(b),
);
: a.localeCompare(b)
)
const makeExamples = data => {
data =
data.slice(0, data.lastIndexOf(`\`\`\`${config.language}`)).trim() +
misc.collapsible(
'Examples',
data.slice(
data.lastIndexOf(`\`\`\`${config.language}`),
data.lastIndexOf('```'),
) + data.slice(data.lastIndexOf('```')),
);
return `${data}\n<br>${misc.link(
'⬆ Back to top',
misc.anchor('Contents'),
)}\n\n`;
};
data.slice(data.lastIndexOf(`\`\`\`${config.language}`), data.lastIndexOf('```')) +
data.slice(data.lastIndexOf('```'))
)
return `${data}\n<br>${misc.link('⬆ Back to top', misc.anchor('Contents'))}\n\n`
}
module.exports = {
getMarkDownAnchor,
@ -56,5 +50,5 @@ module.exports = {
optimizeNodes,
capitalize,
prepTaggedData,
makeExamples,
};
makeExamples
}

View File

@ -1,23 +1,19 @@
const {
isTravisCI,
isTravisCronOrAPI,
isNotTravisCronOrAPI,
} = require('./environmentCheck');
const { isTravisCI, isTravisCronOrAPI, isNotTravisCronOrAPI } = require('./environmentCheck')
const {
getMarkDownAnchor,
objectFromPairs,
optimizeNodes,
capitalize,
prepTaggedData,
makeExamples,
} = require('./helpers');
makeExamples
} = require('./helpers')
const {
getFilesInDir,
hashData,
getCodeBlocks,
getTextualContent,
readSnippets,
} = require('./snippetParser');
readSnippets
} = require('./snippetParser')
module.exports = {
isTravisCI,
@ -33,5 +29,5 @@ module.exports = {
hashData,
getCodeBlocks,
getTextualContent,
readSnippets,
};
readSnippets
}

View File

@ -2,164 +2,150 @@ const fs = require('fs-extra'),
path = require('path'),
{ red } = require('kleur'),
crypto = require('crypto'),
frontmatter = require('front-matter');
const sass = require('node-sass');
const caniuseDb = require('caniuse-db/data.json');
const config = require('../../config');
frontmatter = require('front-matter')
const sass = require('node-sass')
const caniuseDb = require('caniuse-db/data.json')
const config = require('../../config')
// Reade all files in a directory
const getFilesInDir = (directoryPath, withPath, exclude = null) => {
try {
let directoryFilenames = fs.readdirSync(directoryPath);
let directoryFilenames = fs.readdirSync(directoryPath)
directoryFilenames.sort((a, b) => {
a = a.toLowerCase();
b = b.toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
a = a.toLowerCase()
b = b.toLowerCase()
if (a < b) return -1
if (a > b) return 1
return 0
})
if (withPath) {
// a hacky way to do conditional array.map
return directoryFilenames.reduce((fileNames, fileName) => {
if (
exclude == null ||
!exclude.some(toExclude => fileName === toExclude)
)
fileNames.push(`${directoryPath}/${fileName}`);
return fileNames;
}, []);
if (exclude == null || !exclude.some(toExclude => fileName === toExclude))
fileNames.push(`${directoryPath}/${fileName}`)
return fileNames
}, [])
}
return directoryFilenames.filter(v => v !== 'README.md');
return directoryFilenames.filter(v => v !== 'README.md')
} catch (err) {
console.log(`${red('ERROR!')} During snippet loading: ${err}`);
process.exit(1);
console.log(`${red('ERROR!')} During snippet loading: ${err}`)
process.exit(1)
}
};
}
// Creates a hash for a value using the SHA-256 algorithm.
const hashData = val =>
crypto
.createHash('sha256')
.update(val)
.digest('hex');
.digest('hex')
// Gets the code blocks for a snippet file.
const getCodeBlocks = str => {
const regex = /```[.\S\s]*?```/g;
let results = [];
let m = null;
const regex = /```[.\S\s]*?```/g
let results = []
let m = null
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) regex.lastIndex += 1;
if (m.index === regex.lastIndex) regex.lastIndex += 1
m.forEach((match, groupIndex) => {
results.push(match);
});
results.push(match)
})
}
const replacer = new RegExp(
`\`\`\`${config.language}([\\s\\S]*?)\`\`\``,
'g',
);
const secondReplacer = new RegExp(
`\`\`\`${config.secondLanguage}([\\s\\S]*?)\`\`\``,
'g',
);
const optionalReplacer = new RegExp(
`\`\`\`${config.optionalLanguage}([\\s\\S]*?)\`\`\``,
'g',
);
const replacer = new RegExp(`\`\`\`${config.language}([\\s\\S]*?)\`\`\``, 'g')
const secondReplacer = new RegExp(`\`\`\`${config.secondLanguage}([\\s\\S]*?)\`\`\``, 'g')
const optionalReplacer = new RegExp(`\`\`\`${config.optionalLanguage}([\\s\\S]*?)\`\`\``, 'g')
results = results.map(v =>
v
.replace(replacer, '$1')
.replace(secondReplacer, '$1')
.replace(optionalReplacer, '$1')
.trim()
);
)
if (results.length > 2)
return {
html: results[0],
css: results[1],
js: results[2],
};
js: results[2]
}
return {
html: results[0],
css: results[1],
js: '',
};
};
js: ''
}
}
// Gets the textual content for a snippet file.
const getTextualContent = str => {
const regex = /([\s\S]*?)```/g;
const results = [];
let m = null;
const regex = /([\s\S]*?)```/g
const results = []
let m = null
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) regex.lastIndex += 1;
if (m.index === regex.lastIndex) regex.lastIndex += 1
m.forEach((match, groupIndex) => {
results.push(match);
});
results.push(match)
})
}
return results[1].replace(/\r\n/g, '\n');
};
return results[1].replace(/\r\n/g, '\n')
}
// Gets the explanation for a snippet file.
const getExplanation = str => {
const regex = /####\s*Explanation([\s\S]*)####/g;
const results = [];
let m = null;
const regex = /####\s*Explanation([\s\S]*)####/g
const results = []
let m = null
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) regex.lastIndex += 1;
if (m.index === regex.lastIndex) regex.lastIndex += 1
m.forEach((match, groupIndex) => {
results.push(match);
});
results.push(match)
})
}
// console.log(results);
return results[1].replace(/\r\n/g, '\n');
};
return results[1].replace(/\r\n/g, '\n')
}
// Gets the browser support for a snippet file.
const getBrowserSupport = str => {
const regex = /####\s*Browser [s|S]upport([\s\S]*)/g;
const results = [];
let m = null;
const regex = /####\s*Browser [s|S]upport([\s\S]*)/g
const results = []
let m = null
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) regex.lastIndex += 1;
if (m.index === regex.lastIndex) regex.lastIndex += 1
m.forEach((match, groupIndex) => {
results.push(match);
});
results.push(match)
})
}
let browserSupportText = results[1].replace(/\r\n/g, '\n');
const supportPercentage = (browserSupportText.match(/https?:\/\/caniuse\.com\/#feat=.*/g) || []).map(
feat => {
const featData = caniuseDb.data[feat.match(/#feat=(.*)/)[1]];
let browserSupportText = results[1].replace(/\r\n/g, '\n')
const supportPercentage = (
browserSupportText.match(/https?:\/\/caniuse\.com\/#feat=.*/g) || []
).map(feat => {
const featData = caniuseDb.data[feat.match(/#feat=(.*)/)[1]]
// caniuse doesn't count "untracked" users, which makes the overall share appear much lower
// than it probably is. Most of these untracked browsers probably support these features.
// Currently it's around 5.3% untracked, so we'll use 4% as probably supporting the feature.
// Also the npm package appears to be show higher usage % than the main website, this shows
// about 0.2% lower than the main website when selecting "tracked users" (as of Feb 2019).
const UNTRACKED_PERCENT = 4;
const UNTRACKED_PERCENT = 4
const usage = featData
? Number(featData.usage_perc_y + featData.usage_perc_a) + UNTRACKED_PERCENT
: 100;
return Math.min(100, usage);
}
)
: 100
return Math.min(100, usage)
})
return {
text: browserSupportText,
supportPercentage: Math.min(...supportPercentage,100)
supportPercentage: Math.min(...supportPercentage, 100)
}
};
}
// Synchronously read all snippets and sort them as necessary (case-insensitive)
const readSnippets = snippetsPath => {
const snippetFilenames = getFilesInDir(snippetsPath, false);
const snippetFilenames = getFilesInDir(snippetsPath, false)
let snippets = {};
let snippets = {}
try {
for (let snippet of snippetFilenames) {
let data = frontmatter(
fs.readFileSync(path.join(snippetsPath, snippet), 'utf8'),
);
let data = frontmatter(fs.readFileSync(path.join(snippetsPath, snippet), 'utf8'))
snippets[snippet] = {
id: snippet.slice(0, -3),
title: data.attributes.title,
@ -170,22 +156,24 @@ const readSnippets = snippetsPath => {
explanation: getExplanation(data.body),
browserSupport: getBrowserSupport(data.body),
codeBlocks: getCodeBlocks(data.body),
tags: data.attributes.tags.split(',').map(t => t.trim()),
tags: data.attributes.tags.split(',').map(t => t.trim())
},
meta: {
hash: hashData(data.body),
},
};
snippets[snippet].attributes.codeBlocks.scopedCss = sass.renderSync({
hash: hashData(data.body)
}
}
snippets[snippet].attributes.codeBlocks.scopedCss = sass
.renderSync({
data: `[data-scope="${snippets[snippet].id}"] { ${snippets[snippet].attributes.codeBlocks.css} }`
}).css.toString();
})
.css.toString()
}
} catch (err) {
console.log(`${red('ERROR!')} During snippet loading: ${err}`);
process.exit(1);
console.log(`${red('ERROR!')} During snippet loading: ${err}`)
process.exit(1)
}
return snippets;
};
return snippets
}
module.exports = {
getFilesInDir,
@ -194,5 +182,5 @@ module.exports = {
getTextualContent,
getExplanation,
getBrowserSupport,
readSnippets,
};
readSnippets
}

View File

@ -6,9 +6,7 @@
"title": "Bouncing loader",
"attributes": {
"text": "Creates a bouncing loader animation.\n\n",
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "9ddb53b4f0d4d889f585ce69e46dc403ccd12f40dff305134bccf8b8a399bb7a"
@ -20,9 +18,7 @@
"title": "Box-sizing reset",
"attributes": {
"text": "Resets the box-model so that `width`s and `height`s are not affected by their `border`s or `padding`.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "f435b9fcc289760199b4b4781e608438b866887fa91394e94063b42f3841fab7"
@ -34,9 +30,7 @@
"title": "Button border animation",
"attributes": {
"text": "Creates a border animation on hover.\n\n",
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "ff6401cc784b92a9672e74968719c029de224c29fcfdc3eaeaa764274108f648"
@ -48,9 +42,7 @@
"title": "Calc()",
"attributes": {
"text": "The function calc() allows to define CSS values with the use of mathematical expressions, the value adopted for the property is the result of a mathematical expression.\n\n",
"tags": [
"other"
]
"tags": ["other"]
},
"meta": {
"hash": "dc3464c5df00866bdea869d2e02f1a3f040f97301259020828df9951de9ada8c"
@ -62,9 +54,7 @@
"title": "Circle",
"attributes": {
"text": "Creates a circle shape with pure CSS.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "1a068c6a0209bfd1e7155326fb219f7590193e3b81802dfecc6d705e9705adf8"
@ -76,9 +66,7 @@
"title": "Clearfix",
"attributes": {
"text": "Ensures that an element self-clears its children.\n\n###### 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.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "9479dfb4ec61a01045f480c93e21829b08017765585edbc511a653d5791e2f87"
@ -90,9 +78,7 @@
"title": "Constant width to height ratio",
"attributes": {
"text": "Given an element of variable width, it will ensure its height remains proportionate in a responsive fashion\n(i.e., its width to height ratio remains constant).\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "f94bb8368d8074d3d00ca449841b16d0fd4c4267a4abf373c43f41f2b9b6bcd1"
@ -104,10 +90,7 @@
"title": "Counter",
"attributes": {
"text": "Counters are, in essence, variables maintained by CSS whose values may be incremented by CSS rules to track how many times they're used.\n\n",
"tags": [
"visual",
"other"
]
"tags": ["visual", "other"]
},
"meta": {
"hash": "9d12a06e8dfbe67458098bb9e5fb4041a5ebd7cf5d652940ddbb8ae6f49a58dd"
@ -119,9 +102,7 @@
"title": "Custom scrollbar",
"attributes": {
"text": "Customizes the scrollbar style for the document and elements with scrollable overflow, on WebKit platforms.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "bf63836daec92d4b85128faff57480f8297c4005a25c70ee93da97bd54eaa7bf"
@ -133,9 +114,7 @@
"title": "Custom text selection",
"attributes": {
"text": "Changes the styling of text selection.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "7095b8bab3e1b3736bf0b8a8a4e429d905bceaf2aec83983377d6151e9a0f660"
@ -147,9 +126,7 @@
"title": "Custom variables",
"attributes": {
"text": "CSS variables that contain specific values to be reused throughout a document.\n\n",
"tags": [
"other"
]
"tags": ["other"]
},
"meta": {
"hash": "b07f694e77ae7a8c107c78aa6c4b27d1d1ef0bae5cab96a7a2fe49d48296a8aa"
@ -161,9 +138,7 @@
"title": "Disable selection",
"attributes": {
"text": "Makes the content unselectable.\n\n",
"tags": [
"interactivity"
]
"tags": ["interactivity"]
},
"meta": {
"hash": "6b99a98dfec252430da591aed665c0310b013710546c6c2d7bc4259bd7709a4a"
@ -175,9 +150,7 @@
"title": "Display table centering",
"attributes": {
"text": "Vertically and horizontally centers a child element within its parent element using `display: table` (as an alternative to `flexbox`).\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "08682925f9ae378097e8b3cc1d2a66f9afdcdd4bd052e2f379e03a124a1a613d"
@ -189,9 +162,7 @@
"title": "Donut spinner",
"attributes": {
"text": "Creates a donut spinner that can be used to indicate the loading of content.\n\n",
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "b7aa7db9756605dfa39631fd05139fb668b910030b71d5046c4149ac2d152b21"
@ -203,9 +174,7 @@
"title": "Dynamic shadow",
"attributes": {
"text": "Creates a shadow similar to `box-shadow` but based on the colors of the element itself.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "355f4fabe546f389f59a9cf08b825dca636a471a1413b753d20ea7f1f471428a"
@ -217,9 +186,7 @@
"title": "Easing variables",
"attributes": {
"text": "Variables that can be reused for `transition-timing-function` properties, more\npowerful than the built-in `ease`, `ease-in`, `ease-out` and `ease-in-out`.\n\n",
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "48d8123982a07c883c2b8a844a1d57c0e1efb5b4f6e3e828b982c54ee8d6b6fa"
@ -231,9 +198,7 @@
"title": "Etched text",
"attributes": {
"text": "Creates an effect where text appears to be \"etched\" or engraved into the background.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "e86bdd1cef913538b157fc7fa052d989d6777be0552d9b6e9ebb474f1629d8fe"
@ -245,9 +210,7 @@
"title": "Evenly distributed children",
"attributes": {
"text": "Evenly distributes child elements within a parent element.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "1204bc1df035e1c0d0b3808669a3a3d19201d7bc10500d8242c86fdd68a2a4d9"
@ -259,10 +222,7 @@
"title": "Fit image in container",
"attributes": {
"text": "Changes the fit and position of an image within its container while preserving its aspect ratio. Previously only possible using a background image and the `background-size` property.\n\n",
"tags": [
"layout",
"visual"
]
"tags": ["layout", "visual"]
},
"meta": {
"hash": "5d09d5e54b7436f047db61223cff15dce2f17f6cffe5e71e0f9061337de3068e"
@ -274,9 +234,7 @@
"title": "Flexbox centering",
"attributes": {
"text": "Horizontally and vertically centers a child element within a parent element using `flexbox`.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "9b17338858339d7bb228e85fc7f8609b4728c9ba2107a636c486779c9c696c0c"
@ -288,10 +246,7 @@
"title": "Focus Within",
"attributes": {
"text": "Changes the appearance of a form if any of its children are focused.\n\n",
"tags": [
"visual",
"interactivity"
]
"tags": ["visual", "interactivity"]
},
"meta": {
"hash": "6fd9c086b06248408f3934b3d21b513dc751ab023defea1841b03a5a9503fff3"
@ -303,9 +258,7 @@
"title": "Fullscreen",
"attributes": {
"text": "The :fullscreen CSS pseudo-class represents an element that's displayed when the browser is in fullscreen mode.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "bc28c8d11259e58cb448d898b3ed31e8fc5b22e9840eee14c392368685755787"
@ -317,9 +270,7 @@
"title": "Ghost trick",
"attributes": {
"text": "Vertically centers an element in another.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "1e9448a7a3fdfda03eb9a43715bd508ea0ce84eaebedf147043fba2f586dc8dc"
@ -331,9 +282,7 @@
"title": "Gradient text",
"attributes": {
"text": "Gives text a gradient color.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "974db536cfe1022d46c3a3fbec5f599a961de986a694c21fa9f493c880263f0d"
@ -345,9 +294,7 @@
"title": "Grid centering",
"attributes": {
"text": "Horizontally and vertically centers a child element within a parent element using `grid`.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "6435b7dc7a403884583c6ed2062dce4e2a43d144578c5d4f6b3ab0882ca959f4"
@ -359,9 +306,7 @@
"title": "Hairline border",
"attributes": {
"text": "Gives an element a border equal to 1 native device pixel in width, which can look\nvery sharp and crisp.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "89a7003fb239612b9ce94ebfaff95bc6bf88fec6990ab6256fff7b2ddfa6d42f"
@ -373,9 +318,7 @@
"title": "Height transition",
"attributes": {
"text": "Transitions an element's height from `0` to `auto` when its height is unknown.\n\n",
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "737b2ca54126cbcb200496d2c61a12ab5e43b9f09a084cfc8cc4f7afa242ad43"
@ -387,9 +330,7 @@
"title": "Hover shadow box animation",
"attributes": {
"text": "Creates a shadow box around the text when it is hovered.\n\n",
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "b0e6bab9cb552d038d24121cfff46c630e6feeb073b3af6f055e9418c511e63b"
@ -401,9 +342,7 @@
"title": "Hover underline animation",
"attributes": {
"text": "Creates an animated underline effect when the text is hovered over.\n\n<small>**Credit:** https://flatuicolors.com/</small>\n\n",
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "9a97ba2c7f2f28ff9047373a3046d95eb7a9ff03de42d23568d669d61f30c6f1"
@ -415,9 +354,7 @@
"title": "Last item with remaining available height",
"attributes": {
"text": "Take advantage of available viewport space by giving the last element the remaining available space in current viewport, even when resizing the window.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "2f925cc190a9744532de97bb4add65e53cc0b2f3833760f4e7263f5df17cfad5"
@ -429,10 +366,7 @@
"title": "Mouse cursor gradient tracking",
"attributes": {
"text": "A hover effect where the gradient follows the mouse cursor.\n\n<small class=\"snippet__credit\">**Credit:** [Tobias Reich](https://codepen.io/electerious/pen/MQrRxX)</small>\n\n",
"tags": [
"visual",
"interactivity"
]
"tags": ["visual", "interactivity"]
},
"meta": {
"hash": "95356deaaa912ba2c168ee418678ad99d1e000163c7b95f725364ba3cbbb5b85"
@ -444,9 +378,7 @@
"title": ":not selector",
"attributes": {
"text": "The `:not` psuedo selector is useful for styling a group of elements, while leaving the last (or specified) element unstyled.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "129748a7f6e0ee74a87e4ff4c62df53c40359c57047586c887fad9fc76872c04"
@ -458,10 +390,7 @@
"title": "Offscreen",
"attributes": {
"text": "A bulletproof way to completely hide an element visually and positionally in the DOM while still allowing it to be accessed by JavaScript and readable by screen readers. This method is very useful for accessibility ([ADA](https://adata.org/learn-about-ada)) development when more context is needed for visually-impaired users. As an alternative to `display: none` which is not readable by screen readers or `visibility: hidden` which takes up physical space in the DOM.\n\n",
"tags": [
"layout",
"visual"
]
"tags": ["layout", "visual"]
},
"meta": {
"hash": "233e33b59ef7be00766dd0034ab54c6e788af637d761e71efb5c552153a9d163"
@ -473,9 +402,7 @@
"title": "Overflow scroll gradient",
"attributes": {
"text": "Adds a fading gradient to an overflowing element to better indicate there is more content to be scrolled.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "938536c0407ce1d5edcf443ec9a51bdb22815662175ffdd372f5a7bc1446c865"
@ -487,9 +414,7 @@
"title": "Popout menu",
"attributes": {
"text": "Reveals an interactive popout menu on hover and focus.\n\n",
"tags": [
"interactivity"
]
"tags": ["interactivity"]
},
"meta": {
"hash": "c4ac484b5e94d0c326d1ac122ba9d9f98b71cd3ab3cce1cd3077fbd6e1afe4ee"
@ -501,9 +426,7 @@
"title": "Pretty text underline",
"attributes": {
"text": "A nicer alternative to `text-decoration: underline` or `<u></u>` where descenders do not clip the underline.\nNatively implemented as `text-decoration-skip-ink: auto` but it has less control over the underline.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "f91299fbd8d5233de42e09ef7c381a1cce23a83288f9e619f153af22a1275fd2"
@ -515,9 +438,7 @@
"title": "Reset all styles",
"attributes": {
"text": "Resets all styles to default values with one property. This will not affect `direction` and `unicode-bidi` properties.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "1e52c4cc2c03669576b53d4be44357e6fea843cffd671419c881b31c927c9170"
@ -529,9 +450,7 @@
"title": "Shape separator",
"attributes": {
"text": "Uses an SVG shape to separate two different blocks to create more a interesting visual appearance compared to standard horizontal separation.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "75e712c07e184d8dbf34818ba245f5b1a4273dfb491a21262b88042ef9e42d6c"
@ -543,9 +462,7 @@
"title": "Sibling fade",
"attributes": {
"text": "Fades out the siblings of a hovered item.\n\n",
"tags": [
"interactivity"
]
"tags": ["interactivity"]
},
"meta": {
"hash": "c4b3ad85a5137635283abe843a9f180027bd751c40be9ca465b0b3e3f52b9fe9"
@ -557,9 +474,7 @@
"title": "System font stack",
"attributes": {
"text": "Uses the native font of the operating system to get close to a native app feel.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "23cfcc3319fd473b39269b2745abb7f52752a970307fc561159275208d04a554"
@ -571,10 +486,7 @@
"title": "Toggle switch",
"attributes": {
"text": "Creates a toggle switch with CSS only.\n\n",
"tags": [
"visual",
"interactivity"
]
"tags": ["visual", "interactivity"]
},
"meta": {
"hash": "e29182514bd83550705267a43d21eec8886ed011c6259f2b3efec9862541f90e"
@ -586,9 +498,7 @@
"title": "Transform centering",
"attributes": {
"text": "Vertically and horizontally centers a child element within its parent element using `position: absolute` and `transform: translate()` (as an alternative to `flexbox` or `display: table`). Similar to `flexbox`, this method does not require you to know the height or width of your parent or child so it is ideal for responsive applications.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "377d480a141a8890f793ef28212d7ed9d60c9d6831286bcea703ab43daca73ce"
@ -600,9 +510,7 @@
"title": "Triangle",
"attributes": {
"text": "Creates a triangle shape with pure CSS.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "08382966ae74825502676c0bcdb77426abbf6202d813f5dfd6679d864fc1292e"
@ -614,9 +522,7 @@
"title": "Truncate text multiline",
"attributes": {
"text": "If the text is longer than one line, it will be truncated for `n` lines and end with an gradient fade.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "ab94193bfb305844badfe15bda3594e75c40ac9660c11c06efd750119a916f8e"
@ -628,9 +534,7 @@
"title": "Truncate text",
"attributes": {
"text": "If the text is longer than one line, it will be truncated and end with an ellipsis `…`.\n\n",
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "0fbe2c0df9663735aed522286556ac0383756ab0a1a5f673bb81dcb42f89d4d1"
@ -642,9 +546,7 @@
"title": "Zebra striped list",
"attributes": {
"text": "Creates a striped list with alternating background colors, which is useful for differentiating siblings that have content spread across a wide row.\n\n",
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "43bc0cd7776468f3b74791017349ef278921c8ded7ba0bd7788d2b01bdb68c7a"

View File

@ -18,9 +18,7 @@
"js": "",
"scopedCss": "@keyframes bouncing-loader {\n to {\n opacity: 0.1;\n transform: translate3d(0, -1rem, 0); } }\n\n[data-scope=\"bouncing-loader\"] .bouncing-loader {\n display: flex;\n justify-content: center; }\n\n[data-scope=\"bouncing-loader\"] .bouncing-loader > div {\n width: 1rem;\n height: 1rem;\n margin: 3rem 0.2rem;\n background: #8385aa;\n border-radius: 50%;\n animation: bouncing-loader 0.6s infinite alternate; }\n\n[data-scope=\"bouncing-loader\"] .bouncing-loader > div:nth-child(2) {\n animation-delay: 0.2s; }\n\n[data-scope=\"bouncing-loader\"] .bouncing-loader > div:nth-child(3) {\n animation-delay: 0.4s; }\n"
},
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "9ddb53b4f0d4d889f585ce69e46dc403ccd12f40dff305134bccf8b8a399bb7a"
@ -44,9 +42,7 @@
"js": "",
"scopedCss": "[data-scope=\"box-sizing-reset\"] html {\n box-sizing: border-box; }\n\n[data-scope=\"box-sizing-reset\"] *,\n[data-scope=\"box-sizing-reset\"] *::before,\n[data-scope=\"box-sizing-reset\"] *::after {\n box-sizing: inherit; }\n\n[data-scope=\"box-sizing-reset\"] .box {\n display: inline-block;\n width: 150px;\n height: 150px;\n padding: 10px;\n background: tomato;\n color: white;\n border: 10px solid red; }\n\n[data-scope=\"box-sizing-reset\"] .content-box {\n box-sizing: content-box; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "f435b9fcc289760199b4b4781e608438b866887fa91394e94063b42f3841fab7"
@ -70,9 +66,7 @@
"js": "",
"scopedCss": "[data-scope=\"button-border-animation\"] .button {\n background-color: #c47135;\n border: none;\n color: #ffffff;\n outline: none;\n padding: 12px 40px 10px;\n position: relative; }\n\n[data-scope=\"button-border-animation\"] .button:before,\n[data-scope=\"button-border-animation\"] .button:after {\n border: 0 solid transparent;\n transition: all 0.25s;\n content: '';\n height: 24px;\n position: absolute;\n width: 24px; }\n\n[data-scope=\"button-border-animation\"] .button:before {\n border-top: 2px solid #c47135;\n left: 0px;\n top: -5px; }\n\n[data-scope=\"button-border-animation\"] .button:after {\n border-bottom: 2px solid #c47135;\n bottom: -5px;\n right: 0px; }\n\n[data-scope=\"button-border-animation\"] .button:hover {\n background-color: #c47135; }\n\n[data-scope=\"button-border-animation\"] .button:hover:before,\n[data-scope=\"button-border-animation\"] .button:hover:after {\n height: 100%;\n width: 100%; }\n"
},
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "ff6401cc784b92a9672e74968719c029de224c29fcfdc3eaeaa764274108f648"
@ -96,9 +90,7 @@
"js": "",
"scopedCss": "[data-scope=\"calc\"] .box-example {\n height: 280px;\n background: #222 url(\"https://image.ibb.co/fUL9nS/wolf.png\") no-repeat;\n background-position: calc(100% - 20px) calc(100% - 20px); }\n"
},
"tags": [
"other"
]
"tags": ["other"]
},
"meta": {
"hash": "dc3464c5df00866bdea869d2e02f1a3f040f97301259020828df9951de9ada8c"
@ -122,9 +114,7 @@
"js": "",
"scopedCss": "[data-scope=\"circle\"] .circle {\n border-radius: 50%;\n width: 2rem;\n height: 2rem;\n background: #333; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "1a068c6a0209bfd1e7155326fb219f7590193e3b81802dfecc6d705e9705adf8"
@ -148,9 +138,7 @@
"js": "",
"scopedCss": "[data-scope=\"clearfix\"] .clearfix::after {\n content: '';\n display: block;\n clear: both; }\n\n[data-scope=\"clearfix\"] .floated {\n float: left; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "9479dfb4ec61a01045f480c93e21829b08017765585edbc511a653d5791e2f87"
@ -174,9 +162,7 @@
"js": "",
"scopedCss": "[data-scope=\"constant-width-to-height-ratio\"] .constant-width-to-height-ratio {\n background: #333;\n width: 50%; }\n\n[data-scope=\"constant-width-to-height-ratio\"] .constant-width-to-height-ratio::before {\n content: '';\n padding-top: 100%;\n float: left; }\n\n[data-scope=\"constant-width-to-height-ratio\"] .constant-width-to-height-ratio::after {\n content: '';\n display: block;\n clear: both; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "f94bb8368d8074d3d00ca449841b16d0fd4c4267a4abf373c43f41f2b9b6bcd1"
@ -200,10 +186,7 @@
"js": "",
"scopedCss": "[data-scope=\"counter\"] ul {\n counter-reset: counter; }\n\n[data-scope=\"counter\"] li::before {\n counter-increment: counter;\n content: counters(counter, \".\") \" \"; }\n"
},
"tags": [
"visual",
"other"
]
"tags": ["visual", "other"]
},
"meta": {
"hash": "9d12a06e8dfbe67458098bb9e5fb4041a5ebd7cf5d652940ddbb8ae6f49a58dd"
@ -227,9 +210,7 @@
"js": "",
"scopedCss": "[data-scope=\"custom-scrollbar\"] {\n /* To style the document scrollbar, remove `.custom-scrollbar` */ }\n [data-scope=\"custom-scrollbar\"] .custom-scrollbar {\n height: 70px;\n overflow-y: scroll; }\n [data-scope=\"custom-scrollbar\"] .custom-scrollbar::-webkit-scrollbar {\n width: 8px; }\n [data-scope=\"custom-scrollbar\"] .custom-scrollbar::-webkit-scrollbar-track {\n box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);\n border-radius: 10px; }\n [data-scope=\"custom-scrollbar\"] .custom-scrollbar::-webkit-scrollbar-thumb {\n border-radius: 10px;\n box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5); }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "bf63836daec92d4b85128faff57480f8297c4005a25c70ee93da97bd54eaa7bf"
@ -253,9 +234,7 @@
"js": "",
"scopedCss": "[data-scope=\"custom-text-selection\"] ::selection {\n background: aquamarine;\n color: black; }\n\n[data-scope=\"custom-text-selection\"] .custom-text-selection::selection {\n background: deeppink;\n color: white; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "7095b8bab3e1b3736bf0b8a8a4e429d905bceaf2aec83983377d6151e9a0f660"
@ -279,9 +258,7 @@
"js": "",
"scopedCss": "[data-scope=\"custom-variables\"] :root {\n /* Place variables within here to use the variables globally. */ }\n\n[data-scope=\"custom-variables\"] .custom-variables {\n --some-color: #da7800;\n --some-keyword: italic;\n --some-size: 1.25em;\n --some-complex-value: 1px 1px 2px whitesmoke, 0 0 1em slategray, 0 0 0.2em slategray;\n color: var(--some-color);\n font-size: var(--some-size);\n font-style: var(--some-keyword);\n text-shadow: var(--some-complex-value); }\n"
},
"tags": [
"other"
]
"tags": ["other"]
},
"meta": {
"hash": "b07f694e77ae7a8c107c78aa6c4b27d1d1ef0bae5cab96a7a2fe49d48296a8aa"
@ -305,9 +282,7 @@
"js": "",
"scopedCss": "[data-scope=\"disable-selection\"] .unselectable {\n user-select: none; }\n"
},
"tags": [
"interactivity"
]
"tags": ["interactivity"]
},
"meta": {
"hash": "6b99a98dfec252430da591aed665c0310b013710546c6c2d7bc4259bd7709a4a"
@ -331,9 +306,7 @@
"js": "",
"scopedCss": "[data-scope=\"display-table-centering\"] .container {\n border: 1px solid #333;\n height: 250px;\n width: 250px; }\n\n[data-scope=\"display-table-centering\"] .center {\n display: table;\n height: 100%;\n width: 100%; }\n\n[data-scope=\"display-table-centering\"] .center > span {\n display: table-cell;\n text-align: center;\n vertical-align: middle; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "08682925f9ae378097e8b3cc1d2a66f9afdcdd4bd052e2f379e03a124a1a613d"
@ -357,9 +330,7 @@
"js": "",
"scopedCss": "@keyframes donut-spin {\n 0% {\n transform: rotate(0deg); }\n 100% {\n transform: rotate(360deg); } }\n\n[data-scope=\"donut-spinner\"] .donut {\n display: inline-block;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-left-color: #7983ff;\n border-radius: 50%;\n width: 30px;\n height: 30px;\n animation: donut-spin 1.2s linear infinite; }\n"
},
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "b7aa7db9756605dfa39631fd05139fb668b910030b71d5046c4149ac2d152b21"
@ -383,9 +354,7 @@
"js": "",
"scopedCss": "[data-scope=\"dynamic-shadow\"] .dynamic-shadow {\n position: relative;\n width: 10rem;\n height: 10rem;\n background: linear-gradient(75deg, #6d78ff, #00ffb8);\n z-index: 1; }\n\n[data-scope=\"dynamic-shadow\"] .dynamic-shadow::after {\n content: '';\n width: 100%;\n height: 100%;\n position: absolute;\n background: inherit;\n top: 0.5rem;\n filter: blur(0.4rem);\n opacity: 0.7;\n z-index: -1; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "355f4fabe546f389f59a9cf08b825dca636a471a1413b753d20ea7f1f471428a"
@ -409,9 +378,7 @@
"js": "",
"scopedCss": "[data-scope=\"easing-variables\"] :root {\n /* Place variables in here to use globally */ }\n\n[data-scope=\"easing-variables\"] .easing-variables {\n --ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53);\n --ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19);\n --ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22);\n --ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);\n --ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035);\n --ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335);\n --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);\n --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);\n --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);\n --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);\n --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);\n --ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1);\n --ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955);\n --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);\n --ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1);\n --ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);\n --ease-in-out-expo: cubic-bezier(1, 0, 0, 1);\n --ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86);\n display: inline-block;\n width: 75px;\n height: 75px;\n padding: 10px;\n color: white;\n line-height: 50px;\n text-align: center;\n background: #333;\n transition: transform 1s var(--ease-out-quart); }\n\n[data-scope=\"easing-variables\"] .easing-variables:hover {\n transform: rotate(45deg); }\n"
},
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "48d8123982a07c883c2b8a844a1d57c0e1efb5b4f6e3e828b982c54ee8d6b6fa"
@ -435,9 +402,7 @@
"js": "",
"scopedCss": "[data-scope=\"etched-text\"] .etched-text {\n text-shadow: 0 2px white;\n font-size: 1.5rem;\n font-weight: bold;\n color: #b8bec5; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "e86bdd1cef913538b157fc7fa052d989d6777be0552d9b6e9ebb474f1629d8fe"
@ -461,9 +426,7 @@
"js": "",
"scopedCss": "[data-scope=\"evenly-distributed-children\"] .evenly-distributed-children {\n display: flex;\n justify-content: space-between; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "1204bc1df035e1c0d0b3808669a3a3d19201d7bc10500d8242c86fdd68a2a4d9"
@ -487,10 +450,7 @@
"js": "",
"scopedCss": "[data-scope=\"fit-image-in-container\"] .image {\n background: #34495e;\n border: 1px solid #34495e;\n width: 200px;\n height: 200px; }\n\n[data-scope=\"fit-image-in-container\"] .image-contain {\n object-fit: contain;\n object-position: center; }\n\n[data-scope=\"fit-image-in-container\"] .image-cover {\n object-fit: cover;\n object-position: right top; }\n"
},
"tags": [
"layout",
"visual"
]
"tags": ["layout", "visual"]
},
"meta": {
"hash": "5d09d5e54b7436f047db61223cff15dce2f17f6cffe5e71e0f9061337de3068e"
@ -514,9 +474,7 @@
"js": "",
"scopedCss": "[data-scope=\"flexbox-centering\"] .flexbox-centering {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100px; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "9b17338858339d7bb228e85fc7f8609b4728c9ba2107a636c486779c9c696c0c"
@ -540,10 +498,7 @@
"js": "",
"scopedCss": "[data-scope=\"focus-within\"] form {\n border: 3px solid #2d98da;\n color: #000000;\n padding: 4px; }\n\n[data-scope=\"focus-within\"] form:focus-within {\n background: #f7b731;\n color: #000000; }\n"
},
"tags": [
"visual",
"interactivity"
]
"tags": ["visual", "interactivity"]
},
"meta": {
"hash": "6fd9c086b06248408f3934b3d21b513dc751ab023defea1841b03a5a9503fff3"
@ -567,9 +522,7 @@
"js": "",
"scopedCss": "[data-scope=\"fullscreen\"] .container {\n margin: 40px auto;\n max-width: 700px; }\n\n[data-scope=\"fullscreen\"] .element {\n padding: 20px;\n height: 300px;\n width: 100%;\n background-color: skyblue; }\n\n[data-scope=\"fullscreen\"] .element p {\n text-align: center;\n color: white;\n font-size: 3em; }\n\n[data-scope=\"fullscreen\"] .element:-ms-fullscreen p {\n visibility: visible; }\n\n[data-scope=\"fullscreen\"] .element:fullscreen {\n background-color: #e4708a;\n width: 100vw;\n height: 100vh; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "bc28c8d11259e58cb448d898b3ed31e8fc5b22e9840eee14c392368685755787"
@ -593,9 +546,7 @@
"js": "",
"scopedCss": "[data-scope=\"ghost-trick\"] .ghosting {\n height: 300px;\n background: #0ff; }\n\n[data-scope=\"ghost-trick\"] .ghosting:before {\n content: '';\n display: inline-block;\n height: 100%;\n vertical-align: middle; }\n\n[data-scope=\"ghost-trick\"] p {\n display: inline-block;\n vertical-align: middle; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "1e9448a7a3fdfda03eb9a43715bd508ea0ce84eaebedf147043fba2f586dc8dc"
@ -619,9 +570,7 @@
"js": "",
"scopedCss": "[data-scope=\"gradient-text\"] .gradient-text {\n background: -webkit-linear-gradient(pink, red);\n -webkit-text-fill-color: transparent;\n -webkit-background-clip: text; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "974db536cfe1022d46c3a3fbec5f599a961de986a694c21fa9f493c880263f0d"
@ -645,9 +594,7 @@
"js": "",
"scopedCss": "[data-scope=\"grid-centering\"] .grid-centering {\n display: grid;\n justify-content: center;\n align-items: center;\n height: 100px; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "6435b7dc7a403884583c6ed2062dce4e2a43d144578c5d4f6b3ab0882ca959f4"
@ -671,9 +618,7 @@
"js": "",
"scopedCss": "[data-scope=\"hairline-border\"] .hairline-border {\n box-shadow: 0 0 0 1px; }\n\n@media (min-resolution: 2dppx) {\n [data-scope=\"hairline-border\"] .hairline-border {\n box-shadow: 0 0 0 0.5px; } }\n\n@media (min-resolution: 3dppx) {\n [data-scope=\"hairline-border\"] .hairline-border {\n box-shadow: 0 0 0 0.33333333px; } }\n\n@media (min-resolution: 4dppx) {\n [data-scope=\"hairline-border\"] .hairline-border {\n box-shadow: 0 0 0 0.25px; } }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "89a7003fb239612b9ce94ebfaff95bc6bf88fec6990ab6256fff7b2ddfa6d42f"
@ -697,9 +642,7 @@
"js": "var el = document.querySelector('.el')\nvar height = el.scrollHeight\nel.style.setProperty('--max-height', height + 'px')",
"scopedCss": "[data-scope=\"height-transition\"] .el {\n transition: max-height 0.5s;\n overflow: hidden;\n max-height: 0; }\n\n[data-scope=\"height-transition\"] .trigger:hover > .el {\n max-height: var(--max-height); }\n"
},
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "737b2ca54126cbcb200496d2c61a12ab5e43b9f09a084cfc8cc4f7afa242ad43"
@ -723,9 +666,7 @@
"js": "",
"scopedCss": "[data-scope=\"hover-shadow-box-animation\"] .hover-shadow-box-animation {\n display: inline-block;\n vertical-align: middle;\n transform: perspective(1px) translateZ(0);\n box-shadow: 0 0 1px transparent;\n margin: 10px;\n transition-duration: 0.3s;\n transition-property: box-shadow, transform; }\n\n[data-scope=\"hover-shadow-box-animation\"] .hover-shadow-box-animation:hover,\n[data-scope=\"hover-shadow-box-animation\"] .hover-shadow-box-animation:focus,\n[data-scope=\"hover-shadow-box-animation\"] .hover-shadow-box-animation:active {\n box-shadow: 1px 10px 10px -10px rgba(0, 0, 24, 0.5);\n transform: scale(1.2); }\n"
},
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "b0e6bab9cb552d038d24121cfff46c630e6feeb073b3af6f055e9418c511e63b"
@ -749,9 +690,7 @@
"js": "",
"scopedCss": "[data-scope=\"hover-underline-animation\"] .hover-underline-animation {\n display: inline-block;\n position: relative;\n color: #0087ca; }\n\n[data-scope=\"hover-underline-animation\"] .hover-underline-animation::after {\n content: '';\n position: absolute;\n width: 100%;\n transform: scaleX(0);\n height: 2px;\n bottom: 0;\n left: 0;\n background-color: #0087ca;\n transform-origin: bottom right;\n transition: transform 0.25s ease-out; }\n\n[data-scope=\"hover-underline-animation\"] .hover-underline-animation:hover::after {\n transform: scaleX(1);\n transform-origin: bottom left; }\n"
},
"tags": [
"animation"
]
"tags": ["animation"]
},
"meta": {
"hash": "9a97ba2c7f2f28ff9047373a3046d95eb7a9ff03de42d23568d669d61f30c6f1"
@ -775,9 +714,7 @@
"js": "",
"scopedCss": "[data-scope=\"last-item-with-remaining-available-height\"] html,\n[data-scope=\"last-item-with-remaining-available-height\"] body {\n height: 100%;\n margin: 0; }\n\n[data-scope=\"last-item-with-remaining-available-height\"] .container {\n height: 100%;\n display: flex;\n flex-direction: column; }\n\n[data-scope=\"last-item-with-remaining-available-height\"] .container > div:last-child {\n background-color: tomato;\n flex: 1; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "2f925cc190a9744532de97bb4add65e53cc0b2f3833760f4e7263f5df17cfad5"
@ -801,10 +738,7 @@
"js": "var btn = document.querySelector('.mouse-cursor-gradient-tracking')\nbtn.onmousemove = function(e) {\n var x = e.pageX - btn.offsetLeft - btn.offsetParent.offsetLeft\n var y = e.pageY - btn.offsetTop - btn.offsetParent.offsetTop\n btn.style.setProperty('--x', x + 'px')\n btn.style.setProperty('--y', y + 'px')\n}",
"scopedCss": "[data-scope=\"mouse-cursor-gradient-tracking\"] .mouse-cursor-gradient-tracking {\n position: relative;\n background: #7983ff;\n padding: 0.5rem 1rem;\n font-size: 1.2rem;\n border: none;\n color: white;\n cursor: pointer;\n outline: none;\n overflow: hidden; }\n\n[data-scope=\"mouse-cursor-gradient-tracking\"] .mouse-cursor-gradient-tracking span {\n position: relative; }\n\n[data-scope=\"mouse-cursor-gradient-tracking\"] .mouse-cursor-gradient-tracking::before {\n --size: 0;\n content: '';\n position: absolute;\n left: var(--x);\n top: var(--y);\n width: var(--size);\n height: var(--size);\n background: radial-gradient(circle closest-side, pink, transparent);\n transform: translate(-50%, -50%);\n transition: width 0.2s ease, height 0.2s ease; }\n\n[data-scope=\"mouse-cursor-gradient-tracking\"] .mouse-cursor-gradient-tracking:hover::before {\n --size: 200px; }\n"
},
"tags": [
"visual",
"interactivity"
]
"tags": ["visual", "interactivity"]
},
"meta": {
"hash": "95356deaaa912ba2c168ee418678ad99d1e000163c7b95f725364ba3cbbb5b85"
@ -828,9 +762,7 @@
"js": "",
"scopedCss": "[data-scope=\"not-selector\"] .css-not-selector-shortcut {\n display: flex; }\n\n[data-scope=\"not-selector\"] ul {\n padding-left: 0; }\n\n[data-scope=\"not-selector\"] li {\n list-style-type: none;\n margin: 0;\n padding: 0 0.75rem; }\n\n[data-scope=\"not-selector\"] li:not(:last-child) {\n border-right: 2px solid #d2d5e4; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "129748a7f6e0ee74a87e4ff4c62df53c40359c57047586c887fad9fc76872c04"
@ -854,10 +786,7 @@
"js": "",
"scopedCss": "[data-scope=\"offscreen\"] .offscreen {\n border: 0;\n clip: rect(0 0 0 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px; }\n"
},
"tags": [
"layout",
"visual"
]
"tags": ["layout", "visual"]
},
"meta": {
"hash": "233e33b59ef7be00766dd0034ab54c6e788af637d761e71efb5c552153a9d163"
@ -881,9 +810,7 @@
"js": "",
"scopedCss": "[data-scope=\"overflow-scroll-gradient\"] .overflow-scroll-gradient {\n position: relative; }\n\n[data-scope=\"overflow-scroll-gradient\"] .overflow-scroll-gradient::after {\n content: '';\n position: absolute;\n bottom: 0;\n width: 240px;\n height: 25px;\n background: linear-gradient(rgba(255, 255, 255, 0.001), white);\n /* transparent keyword is broken in Safari */\n pointer-events: none; }\n\n[data-scope=\"overflow-scroll-gradient\"] .overflow-scroll-gradient__scroller {\n overflow-y: scroll;\n background: white;\n width: 240px;\n height: 200px;\n padding: 15px;\n line-height: 1.2; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "938536c0407ce1d5edcf443ec9a51bdb22815662175ffdd372f5a7bc1446c865"
@ -907,9 +834,7 @@
"js": "",
"scopedCss": "[data-scope=\"popout-menu\"] .reference {\n position: relative;\n background: tomato;\n width: 100px;\n height: 100px; }\n\n[data-scope=\"popout-menu\"] .popout-menu {\n position: absolute;\n visibility: hidden;\n left: 100%;\n background: #333;\n color: white;\n padding: 15px; }\n\n[data-scope=\"popout-menu\"] .reference:hover > .popout-menu,\n[data-scope=\"popout-menu\"] .reference:focus > .popout-menu,\n[data-scope=\"popout-menu\"] .reference:focus-within > .popout-menu {\n visibility: visible; }\n"
},
"tags": [
"interactivity"
]
"tags": ["interactivity"]
},
"meta": {
"hash": "c4ac484b5e94d0c326d1ac122ba9d9f98b71cd3ab3cce1cd3077fbd6e1afe4ee"
@ -933,9 +858,7 @@
"js": "",
"scopedCss": "[data-scope=\"pretty-text-underline\"] .pretty-text-underline {\n display: inline;\n text-shadow: 1px 1px #f5f6f9, -1px 1px #f5f6f9, -1px -1px #f5f6f9, 1px -1px #f5f6f9;\n background-image: linear-gradient(90deg, currentColor 100%, transparent 100%);\n background-position: bottom;\n background-repeat: no-repeat;\n background-size: 100% 1px; }\n\n[data-scope=\"pretty-text-underline\"] .pretty-text-underline::-moz-selection {\n background-color: rgba(0, 150, 255, 0.3);\n text-shadow: none; }\n\n[data-scope=\"pretty-text-underline\"] .pretty-text-underline::selection {\n background-color: rgba(0, 150, 255, 0.3);\n text-shadow: none; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "f91299fbd8d5233de42e09ef7c381a1cce23a83288f9e619f153af22a1275fd2"
@ -959,9 +882,7 @@
"js": "",
"scopedCss": "[data-scope=\"reset-all-styles\"] .reset-all-styles {\n all: initial; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "1e52c4cc2c03669576b53d4be44357e6fea843cffd671419c881b31c927c9170"
@ -985,9 +906,7 @@
"js": "",
"scopedCss": "[data-scope=\"shape-separator\"] .shape-separator {\n position: relative;\n height: 48px;\n background: #333; }\n\n[data-scope=\"shape-separator\"] .shape-separator::after {\n content: '';\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cpath d='m12 0l12 12h-24z' fill='%23fff'/%3E%3C/svg%3E\");\n position: absolute;\n width: 100%;\n height: 12px;\n bottom: 0; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "75e712c07e184d8dbf34818ba245f5b1a4273dfb491a21262b88042ef9e42d6c"
@ -1011,9 +930,7 @@
"js": "",
"scopedCss": "[data-scope=\"sibling-fade\"] span {\n padding: 0 1rem;\n transition: opacity 0.2s; }\n\n[data-scope=\"sibling-fade\"] .sibling-fade:hover span:not(:hover) {\n opacity: 0.5; }\n"
},
"tags": [
"interactivity"
]
"tags": ["interactivity"]
},
"meta": {
"hash": "c4b3ad85a5137635283abe843a9f180027bd751c40be9ca465b0b3e3f52b9fe9"
@ -1037,9 +954,7 @@
"js": "",
"scopedCss": "[data-scope=\"system-font-stack\"] .system-font-stack {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "23cfcc3319fd473b39269b2745abb7f52752a970307fc561159275208d04a554"
@ -1063,10 +978,7 @@
"js": "",
"scopedCss": "[data-scope=\"toggle-switch\"] .switch {\n position: relative;\n display: inline-block;\n width: 40px;\n height: 20px;\n background-color: rgba(0, 0, 0, 0.25);\n border-radius: 20px;\n transition: all 0.3s; }\n\n[data-scope=\"toggle-switch\"] .switch::after {\n content: '';\n position: absolute;\n width: 18px;\n height: 18px;\n border-radius: 18px;\n background-color: white;\n top: 1px;\n left: 1px;\n transition: all 0.3s; }\n\n[data-scope=\"toggle-switch\"] input[type='checkbox']:checked + .switch::after {\n transform: translateX(20px); }\n\n[data-scope=\"toggle-switch\"] input[type='checkbox']:checked + .switch {\n background-color: #7983ff; }\n\n[data-scope=\"toggle-switch\"] .offscreen {\n position: absolute;\n left: -9999px; }\n"
},
"tags": [
"visual",
"interactivity"
]
"tags": ["visual", "interactivity"]
},
"meta": {
"hash": "e29182514bd83550705267a43d21eec8886ed011c6259f2b3efec9862541f90e"
@ -1090,9 +1002,7 @@
"js": "",
"scopedCss": "[data-scope=\"transform-centering\"] .parent {\n border: 1px solid #333;\n height: 250px;\n position: relative;\n width: 250px; }\n\n[data-scope=\"transform-centering\"] .child {\n left: 50%;\n position: absolute;\n top: 50%;\n transform: translate(-50%, -50%);\n text-align: center; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "377d480a141a8890f793ef28212d7ed9d60c9d6831286bcea703ab43daca73ce"
@ -1116,9 +1026,7 @@
"js": "",
"scopedCss": "[data-scope=\"triangle\"] .triangle {\n width: 0;\n height: 0;\n border-top: 20px solid #333;\n border-left: 20px solid transparent;\n border-right: 20px solid transparent; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "08382966ae74825502676c0bcdb77426abbf6202d813f5dfd6679d864fc1292e"
@ -1142,9 +1050,7 @@
"js": "",
"scopedCss": "[data-scope=\"truncate-text-multiline\"] .truncate-text-multiline {\n overflow: hidden;\n display: block;\n height: 109.2px;\n margin: 0 auto;\n font-size: 26px;\n line-height: 1.4;\n width: 400px;\n position: relative; }\n\n[data-scope=\"truncate-text-multiline\"] .truncate-text-multiline:after {\n content: '';\n position: absolute;\n bottom: 0;\n right: 0;\n width: 150px;\n height: 36.4px;\n background: linear-gradient(to right, rgba(0, 0, 0, 0), #f5f6f9 50%); }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "ab94193bfb305844badfe15bda3594e75c40ac9660c11c06efd750119a916f8e"
@ -1168,9 +1074,7 @@
"js": "",
"scopedCss": "[data-scope=\"truncate-text\"] .truncate-text {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n width: 200px; }\n"
},
"tags": [
"layout"
]
"tags": ["layout"]
},
"meta": {
"hash": "0fbe2c0df9663735aed522286556ac0383756ab0a1a5f673bb81dcb42f89d4d1"
@ -1194,9 +1098,7 @@
"js": "",
"scopedCss": "[data-scope=\"zebra-striped-list\"] li:nth-child(odd) {\n background-color: #ddd; }\n"
},
"tags": [
"visual"
]
"tags": ["visual"]
},
"meta": {
"hash": "43bc0cd7776468f3b74791017349ef278921c8ded7ba0bd7788d2b01bdb68c7a"

View File

@ -18,7 +18,9 @@ Explain briefly what the snippet does.
```
```js
console.log("This is optional, if your snippet doesn't require JavaScript, be sure to delete this block!")
console.log(
"This is optional, if your snippet doesn't require JavaScript, be sure to delete this block!"
)
```
#### Explanation

View File

@ -55,6 +55,3 @@ Note: `1rem` is usually `16px`.
#### Browser support
- https://caniuse.com/#feat=css-animation

View File

@ -41,6 +41,3 @@ html {
#### Browser support
- https://caniuse.com/#feat=css3-boxsizing

View File

@ -27,6 +27,3 @@ The function calc() allows to define CSS values with the use of mathematical exp
#### Browser support
- https://caniuse.com/#feat=calc

View File

@ -26,6 +26,3 @@ Creates a circle shape with pure CSS.
#### Browser support
- https://caniuse.com/#feat=border-radius

View File

@ -36,6 +36,3 @@ Ensures that an element self-clears its children.
#### Browser support
<span class="snippet__support-note">⚠️ For this snippet to work properly you need to ensure that there are no non-floating children in the container and that there are no tall floats before the clearfixed container but in the same formatting context (e.g. floated columns).</span>

View File

@ -33,6 +33,3 @@ Given an element of variable width, it will ensure its height remains proportion
- This method also allows content to be placed inside the element normally.
#### Browser support

View File

@ -44,6 +44,3 @@ li::before {
#### Browser support
- https://caniuse.com/#feat=css-counters

View File

@ -52,6 +52,3 @@ 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>
- https://caniuse.com/#feat=css-scrollbar

View File

@ -30,6 +30,3 @@ Changes the styling of text selection.
in any specification.</span>
- https://caniuse.com/#feat=css-selection

View File

@ -35,6 +35,3 @@ CSS variables that contain specific values to be reused throughout a document.
#### Browser support
- https://caniuse.com/#feat=css-variables

View File

@ -27,6 +27,3 @@ Makes the content unselectable.
<span class="snippet__support-note">⚠️ This is not a secure method to prevent users from copying content.</span>
- https://caniuse.com/#feat=user-select-none

View File

@ -44,6 +44,3 @@ Vertically and horizontally centers a child element within its parent element us
#### Browser support
- https://caniuse.com/#search=display%3A%20table

View File

@ -39,6 +39,3 @@ Creates a donut spinner that can be used to indicate the loading of content.
- https://caniuse.com/#feat=css-animation
- https://caniuse.com/#feat=transforms2d

View File

@ -48,6 +48,3 @@ Creates a shadow similar to `box-shadow` but based on the colors of the element
<span class="snippet__support-note">⚠️ Requires prefixes for full support.</span>
- https://caniuse.com/#feat=css-filters

View File

@ -60,6 +60,3 @@ powerful than the built-in `ease`, `ease-in`, `ease-out` and `ease-in-out`.
#### Browser support
- https://caniuse.com/#feat=css-variables

View File

@ -27,6 +27,3 @@ Creates an effect where text appears to be "etched" or engraved into the backgro
#### Browser support
- https://caniuse.com/#feat=css-textshadow

View File

@ -32,6 +32,3 @@ Evenly distributes child elements within a parent element.
<span class="snippet__support-note">⚠️ Needs prefixes for full support.</span>
- https://caniuse.com/#feat=flexbox

View File

@ -29,6 +29,3 @@ Horizontally and vertically centers a child element within a parent element usin
<span class="snippet__support-note">⚠️ Needs prefixes for full support.</span>
- https://caniuse.com/#feat=flexbox

View File

@ -41,6 +41,3 @@ form:focus-within {
If no link is provided, it defaults to 99+%. -->
- https://caniuse.com/#feat=css-focus-within

View File

@ -54,6 +54,3 @@ The :fullscreen CSS pseudo-class represents an element that's displayed when the
- https://developer.mozilla.org/en-US/docs/Web/CSS/:fullscreen
- https://caniuse.com/#feat=fullscreen

View File

@ -37,6 +37,3 @@ p {
#### Browser support
- https://caniuse.com/#feat=inline-block

View File

@ -28,6 +28,3 @@ Gives text a gradient color.
<span class="snippet__support-note">⚠️ Uses non-standard properties.</span>
- https://caniuse.com/#feat=text-stroke

View File

@ -27,6 +27,3 @@ Horizontally and vertically centers a child element within a parent element usin
#### Browser support
- https://caniuse.com/#feat=css-grid

View File

@ -49,6 +49,3 @@ very sharp and crisp.
<hr>
\*Chrome does not support subpixel values on `border`. Safari does not support subpixel values on `box-shadow`. Firefox supports subpixel values on both.

View File

@ -36,7 +36,9 @@ el.style.setProperty('--max-height', height + 'px')
2. `overflow: hidden` prevents the contents of the hidden element from overflowing its container.
3. `max-height: 0` specifies that the element has no height initially.
4. `.target:hover > .el` specifies that when the parent is hovered over, target a child `.el` within it and use the `--max-height` variable which was defined by JavaScript.
---
1. `el.scrollHeight` is the height of the element including overflow, which will change dynamically based on the content of the element.
2. `el.style.setProperty(...)` sets the `--max-height` CSS variable which is used to specify the `max-height` of the element the target is hovered over, allowing it to transition smoothly from 0 to auto.
@ -50,6 +52,3 @@ el.style.setProperty('--max-height', height + 'px')
- https://caniuse.com/#feat=css-variables
- https://caniuse.com/#feat=css-transitions

View File

@ -41,6 +41,3 @@ Creates a shadow box around the text when it is hovered.
- https://caniuse.com/#feat=transforms3d
- https://caniuse.com/#feat=css-transitions

View File

@ -52,6 +52,3 @@ Creates an animated underline effect when the text is hovered over.
- https://caniuse.com/#feat=transforms2d
- https://caniuse.com/#feat=css-transitions

View File

@ -67,6 +67,3 @@ btn.onmousemove = function(e) {
<span class="snippet__support-note">⚠️ Requires JavaScript.</span>
- https://caniuse.com/#feat=css-variables

View File

@ -41,6 +41,3 @@ li:not(:last-child) {
#### Browser support
- https://caniuse.com/#feat=css-sel3

View File

@ -39,6 +39,3 @@ A bulletproof way to completely hide an element visually and positionally in the
(Although `clip` technically has been depreciated, the newer `clip-path` currently has very limited browser support.)
- https://caniuse.com/#search=clip

View File

@ -60,6 +60,3 @@ Adds a fading gradient to an overflowing element to better indicate there is mor
#### Browser support
- https://caniuse.com/#feat=css-gradients

View File

@ -42,6 +42,3 @@ Reveals an interactive popout menu on hover and focus.
7. `.reference:focus-within > .popout-menu` ensures that the popout is shown when the focus is _within_ the reference.
#### Browser support

View File

@ -40,6 +40,3 @@ Natively implemented as `text-decoration-skip-ink: auto` but it has less control
- https://caniuse.com/#feat=css-textshadow
- https://caniuse.com/#feat=css-gradients

View File

@ -31,6 +31,3 @@ Resets all styles to default values with one property. This will not affect `dir
<span class="snippet__support-note">⚠️ MS Edge status is under consideration.</span>
- https://caniuse.com/#feat=css-all

View File

@ -38,6 +38,3 @@ Uses an SVG shape to separate two different blocks to create more a interesting
#### Browser support
- https://caniuse.com/#feat=svg

View File

@ -32,6 +32,3 @@ span {
- https://caniuse.com/#feat=css-sel3
- https://caniuse.com/#feat=css-transitions

View File

@ -32,6 +32,3 @@ Uses the native font of the operating system to get close to a native app feel.
10. `sans-serif` is the fallback sans-serif font if none of the other fonts are supported
#### Browser support

View File

@ -39,6 +39,3 @@ Vertically and horizontally centers a child element within its parent element us
<span class="snippet__support-note">⚠️ Requires prefix for full support.</span>
- https://caniuse.com/#feat=transforms2d

View File

@ -26,6 +26,3 @@ Creates a triangle shape with pure CSS.
- Experiment with the `px` values to change the proportion of the triangle.
#### Browser support

View File

@ -46,6 +46,3 @@ If the text is longer than one line, it will be truncated for `n` lines and end
#### Browser support
- https://caniuse.com/#feat=css-gradients

View File

@ -30,6 +30,3 @@ 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>
- https://caniuse.com/#feat=text-overflow