HTML preprocessors can make writing HTML more powerful or convenient. For instance, Markdown is designed to be easier to write and read for text documents and you could write a loop in Pug.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. So you don't have access to higher-up elements like the <html>
tag. If you want to add classes there that can affect the whole document, this is the place to do it.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. If you need things in the <head>
of the document, put that code here.
The resource you are linking to is using the 'http' protocol, which may not work when the browser is using https.
CSS preprocessors help make authoring CSS easier. All of them offer things like variables and mixins to provide convenient abstractions.
It's a common practice to apply CSS to a page that styles elements such that they are consistent across all browsers. We offer two of the most popular choices: normalize.css and a reset. Or, choose Neither and nothing will be applied.
To get the best cross-browser support, it is a common practice to apply vendor prefixes to CSS properties and values that require them to work. For instance -webkit-
or -moz-
.
We offer two popular choices: Autoprefixer (which processes your CSS server-side) and -prefix-free (which applies prefixes via a script, client-side).
Any URLs added here will be added as <link>
s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.
You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.
You can also link to another Pen here (use the .css
URL Extension) and we'll pull the CSS from that Pen and include it. If it's using a matching preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
JavaScript preprocessors can help make authoring JavaScript easier and more convenient.
Babel includes JSX processing.
Any URL's added here will be added as <script>
s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.
You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.
If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.
You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
Search for and use JavaScript packages from npm here. By selecting a package, an import
statement will be added to the top of the JavaScript editor for this package.
Using packages here is powered by esm.sh, which makes packages from npm not only available on a CDN, but prepares them for native JavaScript ESM usage.
All packages are different, so refer to their docs for how they work.
If you're using React / ReactDOM, make sure to turn on Babel for the JSX processing.
If active, Pens will autosave every 30 seconds after being saved once.
If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.
If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.
Visit your global Editor Settings.
<section class="btn-Group btn-Group-circle">
<h1 class="btn-Group_Header">'Material design' inspired</h1>
<button class="btn-Btn btn-Btn_Small" >
<span class="btn-Btn_B">Hello</span>
</button>
<button class="btn-Btn btn-Btn_Small" aria-selected="false" >
<span class="btn-Btn_Name">Sub</span>
<span class="btn-Btn_B">Hello</span>
</button>
<button class="btn-Btn btn-Btn_Large" >
<span class="btn-Btn_Name">Bigger text</span>
<span class="btn-Btn_B">To fill this button</span>
</button>
</section>
/*
App reset by Ben Frain @benfrain / benfrain.com
Latest: https://github.com/benfrain/app-reset
An opinionated set of resets suitable for building web applications.
## Accessibility Notes
These resets target HTML elements that typically receive styling defaults by User Agents that I always need to 'undo'.
Be aware that some of these resets have a negative impact on the default usability and accessibility of a web page. Therefore, ensure you add an equivalent accessible style back that matches your project aesthetic.
## You'll want to run this through Autoprefixer You'll typically need to run this through (https://github.com/postcss/autoprefixer) for production. Only essential prefixes are added here (e.g. proprietary property value/pairs) and you'll need to set prefixing relative to your desired browser support matrix.
*/
/*Hat tip to @thierrykoblentz for this approach: https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */
html {
box-sizing: border-box;
/* Nicer looking fonts for OS X and iOS */
-webkit-font-smoothing: antialiased;
}
/*Yes, the universal selector. No, it isn't slow: https://benfrain.com/css-performance-revisited-selectors-bloat-expensive-styles/*/
* {
/* Later browsers can be more easily reset with `all: unset`. It's commented out by default here as it's pretty heavy handed. However, further declarations on these elements follow for older browsers. If you uncomment this property/value REMEMBER accessibility for outlines etc. This undoes a LOT of default UA styling, use with EXTREME caution!! */
/* all: unset; */
/*This prevents users being able to select text. Stops long presses in iOS bringing up copy/paste UI for example. Note below we specifically switch user-select on for inputs for the sake of Safari. Bug here: https://bugs.webkit.org/show_bug.cgi?id=82692*/
user-select: none;
/*This gets -webkit specific prefix as it is a non W3C property*/
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
/*Older Androids need this instead*/
-webkit-tap-highlight-color: transparent;
/* Most devs find border-box easier to reason about. However by inheriting we can mix box-sizing approaches.*/
box-sizing: inherit;
}
*:before,
*:after {
box-sizing: inherit;
}
/* Switching user-select on for inputs and contenteditable specifically for Safari (see bug link above)*/
input[type],
[contenteditable] {
user-select: text;
}
body,
h1,
h2,
h3,
h4,
h5,
h6,
p {
/*We will be adding our own margin to these elements as needed.*/
margin: 0;
/*You'll want to set font-size as needed.*/
font-size: 1rem;
/*No bold for h tags unless you want it*/
font-weight: 400;
}
/*
Thanks to L. David Baron for this:
https://twitter.com/davidbaron/status/794138427952222210 */
base,
basefont,
datalist,
head,
meta,
script,
style,
title,
noembed,
param,
template {
display: none;
}
a {
text-decoration: none;
color: inherit;
}
/*No bold for b tags by default*/
b {
font-weight: 400;
}
/*Prevent these elements having italics by default*/
em,
i {
font-style: normal;
}
/*IMPORTANT: This removes the focus outline for most browsers. Be aware this is a backwards accessibilty step! Mozilla (i.e. Firefox) also adds a dotted outline around a tags and buttons when they receive tab focus which I haven't found an unhacky way of removing.*/
a:focus,
button:focus {
outline: 0;
}
/* The button element tends to get a lot of default styles which we largely undo here. We set text-alignment (usually set to center by UA style sheet) and the font-family to inherit from your own styles instead. */
button {
appearance: none;
background-color: transparent;
border: 0;
padding: 0;
text-align: inherit;
font-family: inherit;
}
input,
fieldset {
appearance: none;
border: 0;
padding: 0;
margin: 0;
/*inputs and fieldset defaults to having a min-width equal to its content in Chrome and Firefox (https://code.google.com/p/chromium/issues/detail?id=560762), we may not want that*/
min-width: 0;
/*Reset the font size and family*/
font-size: 1rem;
font-family: inherit;
}
/* For IE, we want to remove the default cross ('X') that appears in input fields when a user starts typing - Make sure you add your own! */
input::-ms-clear {
display: none;
}
/*This switches the default outline off when an input receives focus (really important for users tabbing through with a keyboard) so ensure you put something decent in for your input focus instead!!*/
input:focus {
outline: 0;
}
input[type="number"] {
/*Mozilla shows the spinner UI on number inputs unless we use this:*/
-moz-appearance: textfield;
}
/*Removes the little spinner controls for number type inputs (WebKit browsers/forks only)*/
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
appearance: none;
}
/*SVG defaults to display: inline which I dislike. Inline-block or inline-flex will render white space on SVG elements in HTML (where you would have defs and symbols) if the container isn't a flex box or the font-size set to 0 to crush the whitespace */
svg {
display: block;
}
img {
/*Make images behave responsively. Here they will scale up to 100% of their natural size*/
max-width: 100%;
/*Make images display as a block (UA default is usually inline)*/
display: block;
}
/*Removes the default focusring that Mozilla places on select items. From: http://stackoverflow.com/a/18853002/1147859
Ensure you set `#000` to the colour you want your text to appear */
select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #000;
}
/* Switching on box-sizing: border-box by default; toggle this off if you want more granular control */
body {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
body {
margin: 50vh 0;
background-color: #494949;
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Segoe UI", Tahoma, Roboto, Oxygen, Ubuntu,
Cantarell, "Fira Sans", "Open Sans", sans-serif;
}
/* Styles relevant to this technique */
.btn-Group {
max-width: 500px;
margin: 20vh auto;
font-size: 0;
display: flex;
flex-direction: column;
background-color: #454545;
}
.btn-Group_Header {
font-size: 1.3rem;
color: #ddd;
background-color: #444;
padding: 10px;
}
.btn-Btn {
display: inline-flex;
padding: 0 10px;
min-height: 80px;
align-items: center;
justify-content: start;
position: relative;
z-index: 1;
margin: 0;
overflow: hidden;
transition: all 0.1s;
background-color: #505050;
}
.btn-Btn:nth-of-type(1) {
width: 25%;
}
.btn-Btn:nth-of-type(2) {
width: 50%;
}
.btn-Btn:nth-of-type(3) {
width: 100%;
}
.btn-Btn:before {
content: "";
position: absolute;
top: calc(var(--y) - var(--width) / 2);
left: calc(var(--x) - var(--width) / 2);
transform-origin: 50% 50%;
background-color: #d2d2d2;
height: var(--width);
width: var(--width);
border-radius: 50%;
z-index: -1;
transform: scale(0);
opacity: 0;
transition: transform 0.2s ease, opacity 0.2s ease;
}
.btn-Group-circle .btn-Btn[aria-selected="true"]:before {
transform: none;
opacity: 1;
transition: transform 0.2s ease, opacity 0.1s ease;
}
.btn-Btn_Name {
font-size: 1.1rem;
color: #d2d2d2;
margin: 0 5px;
transition: color 0.1s;
}
[aria-selected="true"] .btn-Btn_Name {
color: #555;
}
.btn-Btn_B {
font-size: 1.1rem;
color: #f90;
transition: color 0.1s;
}
[aria-selected="true"] .btn-Btn_B {
color: #5948db;
}
document.body.addEventListener("pointerdown", e => {
// Ignore anything that isn't the button or a child of it
if (e.target.tagName !== "BUTTON" && e.target.parentNode.tagName !== "BUTTON") {
return;
}
const theBtn = e.target.closest("button");
const neededLeft = e.x - theBtn.getBoundingClientRect().left;
const neededTop = e.y - theBtn.getBoundingClientRect().top;
const biggestA = Math.max(neededLeft, theBtn.getBoundingClientRect().width - neededLeft);
const biggestB = Math.max(neededTop, theBtn.getBoundingClientRect().height - neededTop);
//const neededWidth = biggest * 2 + 25;
//length of diagonal through rectangle is a2 + b2 = c2.
const neededWidth = Math.sqrt(biggestA * biggestA + biggestB * biggestB) * 2;
theBtn.style.setProperty("--x", `${neededLeft}px`);
theBtn.style.setProperty("--y", `${neededTop}px`);
theBtn.style.setProperty("--width", `${neededWidth}px`);
theBtn.setAttribute("aria-selected", theBtn.getAttribute("aria-selected") === "true" ? "false" : "true");
});
Also see: Tab Triggers