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 Skypack, which makes packages from npm not only available on a CDN, but prepares them for native JavaScript ES6 import
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.
#cart
%h2 Your Shopping Cart
%ul.cart-items
.total
.subtotalTotal
Subtotal
%span $0.00
.taxes
Tax
%span $0.00
.shipping
Shipping
%span $0.00
.finalTotal
Total
%span $0.00
%a.checkout
Check Out
%p.error
.wrap#wrap
%header
%a.logo{:href=>"#"}
Octocat <span class="brandico-github"></span> Outfitters
%a.cart-link{:href=>"#menu"}
%span.cart-text.fontawesome-shopping-cart
%span Cart
%span.returnToShop ← Back
%span.cart-quantity.empty 0
%section.shop
%footer
%p Crafted for the Pattern Rodeo (rodeo-007). Images belong to Github.
// Product Templates for Shop & Cart
%script#productTemplate{ type: 'text/template' }
<div class="product">
<h1></h1>
<p></p>
<div class="button">
<div class="price"></div>
<a class="addtocart">
<div class="add">Add to Cart</div>
<div class="added">Added!</div>
</a>
</div>
</div>
%script#cartItem{ type: 'text/template' }
<li><div class="cart-product">
<input class="quantity" value="1">
</div><div class="cart-description">
<h3></h3>
<span class="subtotal"></span>
</div></li>
@import compass
@import url(https://fonts.googleapis.com/css?family=Lato:400,700)
/* Iconfonts
============================ */
@import "http://weloveiconfonts.com/api/?family=fontawesome"
@import "http://weloveiconfonts.com/api/?family=brandico"
[class*="fontawesome-"]:before
font-family: 'FontAwesome', sans-serif
[class*="brandico-"]:before
font-family: 'brandico', sans-serif
/* Variables
============================ */
$white: #fff
$black: #111
$gray: lighten($black, 25%)
$lightblue: #9cdaf0
$blue: #7cbae6
$darkblue: darken($blue, 25%)
/* Body
============================ */
body
position: relative
font-family: 'Lato', sans-serif
font-weight: 300
font-size: 1em
color: darken($white, 20%)
/* Header
============================ */
header
width: 100%
border-bottom: 1px solid $blue
background: lighten($black, 5%)
/* Logo */
a.logo
margin-left: 1em
text-transform: uppercase
text-decoration: none
color: $blue
line-height: 4em
span
margin: 0 3px 0 3px
color: $lightblue
/* Cart link */
a.cart-link
float: right
padding-left: 1em
margin-right: 1em
border-left: 1px dotted $gray
line-height: 4em
text-decoration: none
color: $white
transition: color 150ms ease-out
&:hover
color: $blue
&:active, .active
color: $lightblue
span.cart-text:before
margin: 5px
> span
display: block
/* Quantity Notification */
span.cart-quantity
position: relative
top: -2px
left: 5px
display: inline-block
width: 22px
height: 22px
border-radius: 50%
background: #f63
font-size: .6em
line-height: 20px
text-align: center
color: $white
/* Quantity Notification hidden when no items*/
.cart-quantity.empty
display: none
/* Back button hidden by default */
.returnToShop
display: none
/* State changes when cart is active */
a.cart-link.active
border: 0
/* Cart link gets hidden*/
span.cart-text
display: none
span.cart-quantity
display: none
/* Back button is displayed */
span.returnToShop
position: absolute
right: -75px
display: block
padding: 0 10px
background: lighten($black, 5%)
border-right: 1px dotted lighten($black, 20%)
/* Sliding Cart
============================ */
.wrap
position: relative
right: 0
box-shadow: 10px -10px 20px -10px rgba(0,0,0,.8)
transition: all 200ms ease-out
.wrap.active
right: 18em
#cart
clear: both
overflow: hidden
.js #cart
position: absolute
top: 0
right: 0
width: 18em
height: 100%
/* Footer
============================ */
footer
clear:both
background: $black
font-size: .85em
color: #fff
p
margin: 0 1em
line-height: 3em
color: $gray
/* Shop & Product Items
============================ */
section.shop
.product
position: relative
z-index: 1
float: left
width: 50%
height: 300px
overflow: hidden
background-position: center center
background-size: cover
/* Hide product descriptions */
> *
margin: 20px 25px
opacity: 0
transition: opacity 200ms ease-out
/* On hover, adds overlay on top of product image */
&:hover:before
position: absolute
z-index: -1
top: 0
display: inline-block
width: 100%
height: 300px
background: rgba(0,0,0,.8)
content: ''
/* On hover, fade in product descriptions */
> *
margin: 20px 25px
opacity: 0
transition: opacity 200ms ease-out
&:hover > *, .active
opacity: 1
/* Styles for each shop item */
h1
padding: 15px 0
border-bottom: 1px dotted darken($white, 50%)
font-weight: normal
font-size: 1.6em
color: $blue
p
margin-bottom: 30px
line-height: 1.5em
/* "Add to Cart" Buttom with 3D transforms and keyframe animation (Works best in Chrome) */
.button
position: relative
display: block
width: 150px
height: 50px
text-align: center
perspective: 1000px
.price
position: absolute
z-index: 1
top: 2px
display: block
width: 50px
height: 46px
border-right: 1px solid $lightblue
border-radius: 2px 0 0 2px
background: $white
line-height: 45px
color: $gray
transform: rotateY(0deg) translateZ(25px)
/* Button magic */
.addtocart
position: absolute
left: 48px
width: 100%
height: 100%
transform-style: preserve-3d
transform: translateZ( -100px )
transition: transform 300ms
cursor: pointer
> div
position: absolute
display: block
width: 150px
height: 50px
border-radius: 0 2px 2px 0
line-height: 50px
> .add
background: $white
color: $blue
transform: rotateY(0deg) translateZ(25px)
transition: background 150ms ease-out
&:hover
background: $blue
color: $white
> .added
background: #f63
color: $white
transform: rotateX(90deg) translateZ(25px)
&.active
animation-name: rotate
animation-duration: 1s
/* Cart & Cart Items
============================ */
#cart
background: #222
#cart>h2
height: 64px
padding-right: 1em
border-left: 1px dotted $gray
border-bottom: 1px solid $blue
margin: 0
background: #2d2d2d
font-weight: normal
font-size: 1.2em
text-align: right
line-height: 64px
/* Styles for each cart item */
.cart-items
padding: 0
.cart-items > li
margin: 30px 20px 30px
border: 1px solid #333
background: #202020
list-style: none
.cart-product
position: relative
display: inline-block
height: 75px
width: 75px
background-image: url('https://cdn.shopify.com/s/files/1/0051/4802/products/MG_1785_1024x1024.jpg')
background-size: cover
vertical-align: top
input.quantity
width: 75px
height: 75px
padding: 0
border: 0
border-right: 1px solid #333
background: rgba(0,0,0,.5)
font-size: 2.5em
line-height: 75px
text-align: center
color: $white
.cart-description
display: inline-block
height: 75px
width: 160px
margin-left: 10px
text-align: right
vertical-align: top
h3
margin: 8px
font-size: 1em
color: $blue
.subtotal
position: relative
display: inline-block
margin: 8px
font-size: .8em
/* Styling for Total Costs */
.total
margin-top: 50px
.total > *
display: block
padding-bottom: 10px
margin: 0 20px 10px 20px
font-size: .8em
text-align: left
.total span
float: right
text-align: right
.subtotalTotal
border-bottom: 1px dotted $gray
.shipping
border-bottom: 1px dotted $gray
.finalTotal
font-size: 1em
color: $blue
a.checkout
height: 35px
padding: 0
margin-top: 30px
border-radius: 3px
background: $darkblue
font-size: 1em
text-align: center
text-transform: uppercase
line-height: 35px
transition: background 150ms ease-out
cursor: pointer
&:hover
background: darken($blue, 15%)
&.active
animation-name: shake
animation-duration: 800ms
.error
display: none
text-align: center
.error:after
display: block
font-size: .9em
text-transform: none
content: "Sorry, the Octocat is busy!"
/* Media Queries
============================ */
@media (max-width: 720px)
.product
width: 100%
@media (max-width: 420px)
/* Hide text in the cart link to save room */
.cart-text>span
display: none
/* Keyframe Animations
============================ */
@keyframes rotate
35%
transform: translateZ(-100px) rotateX(-90deg)
72%
transform: translateZ(-100px) rotateX(-90deg)
100%
transform: translateZ(-100px)
@keyframes shake
0%, 100%
transform: translateX(0)
10%, 30%, 50%, 70%, 90%
transform: translateX(-5px)
20%, 40%, 60%, 80%
transform: translateX(5px)
$(document).ready(function() {
// Product data to be used in shop and in cart
var products = {
'Octocat Mug' : ['Octocat Mug', "The mug you've been dreaming about. One sip from this ceramic 16oz fluid delivery system and you'll never go back to red cups.", 14, 'https://cdn.shopify.com/s/files/1/0051/4802/products/white-mug-1_1024x1024.jpg', 1],
'Leather Coasters' : ['Leather Coasters', "These coasters roll all of the greatest qualities into one: class, leather, and octocats. They also happen to protect surfaces from cold drinks.", 18, 'https://cdn.shopify.com/s/files/1/0051/4802/products/MG_1934_1024x1024.jpg', 2],
'Octopint (Set of 2)' : ['Octopint (Set of 2)', "Set of two heavyweight 16 oz. Octopint glasses for your favorite malty beverage.", 16, 'https://cdn.shopify.com/s/files/1/0051/4802/products/pint_1024x1024.jpg', 3],
'Blacktocat 2.0 Tee' : ['Blacktocat 2.0 Tee', "Check it. Blacktocat is back with a whole new direction. He's exited stealth mode and is ready for primetime, now with a stylish logo.", 25, 'https://cdn.shopify.com/s/files/1/0051/4802/products/blacktocat-3_1024x1024.jpg', 4],
'Die Cut Stickers' : ['Die Cut Stickers', "Need a huge Octocat sticker for your laptop, fridge, snowboard, or ceiling fan? Look no further!", 2, 'https://cdn.shopify.com/s/files/1/0051/4802/products/sticker-large_1024x1024.jpg', 5],
'Pixelcat Shirt' : ['Pixelcat Shirt', "Pixels are your friends. Show your bits in this super-comfy blue American Apparel tri-blend shirt with a pixelated version of your favorite aquatic feline", 25, 'https://cdn.shopify.com/s/files/1/0051/4802/products/8bit-1_1024x1024.jpg?145', 6]
};
// Populates shop with items based on template and data in var products
var $shop = $('.shop');
var $cart = $('.cart-items');
for(var item in products) {
var itemName = products[item][0],
itemDescription = products[item][1],
itemPrice = products[item][2],
itemImg = products[item][3],
itemId = products[item][4],
$template = $($('#productTemplate').html());
$template.find('h1').text(itemName);
$template.find('p').text(itemDescription);
$template.find('.price').text('$' + itemPrice);
$template.css('background-image', 'url(' + itemImg + ')');
$template.data('id', itemId);
$template.data('name', itemName);
$template.data('price', itemPrice);
$template.data('image', itemImg);
$shop.append($template);
}
// Checks quantity of a cart item on input blur and updates total
// If quantity is zero, item is removed
$('body').on('blur', '.cart-items input', function() {
var $this = $(this),
$item = $this.parents('li');
if (+$this.val() === 0) {
$item.remove();
} else {
calculateSubtotal($item);
}
updateCartQuantity();
calculateAndUpdate();
});
// Add item from the shop to the cart
// If item is already in the cart, +1 to quantity
// If not, creates the cart item based on template
$('body').on('click', '.product .add', function() {
var items = $cart.children(),
$item = $(this).parents('.product'),
$template = $($('#cartItem').html()),
$matched = null,
quantity = 0;
$matched = items.filter(function(index) {
var $this = $(this);
return $this.data('id') === $item.data('id');
});
if ($matched.length) {
quantity = +$matched.find('.quantity').val() + 1;
$matched.find('.quantity').val(quantity);
calculateSubtotal($matched);
} else {
$template.find('.cart-product').css('background-image', 'url(' + $item.data('image') + ')');
$template.find('h3').text($item.data('name'));
$template.find('.subtotal').text('$' + $item.data('price'));
$template.data('id', $item.data('id'));
$template.data('price', $item.data('price'));
$template.data('subtotal', $item.data('price'));
$cart.append($template);
}
updateCartQuantity();
calculateAndUpdate();
});
// Calculates subtotal for an item
function calculateSubtotal($item) {
var quantity = $item.find('.quantity').val(),
price = $item.data('price'),
subtotal = quantity * price;
$item.find('.subtotal').text('$' + subtotal);
$item.data('subtotal', subtotal);
}
// Clicking on the cart link opens up the shopping cart
var $cartlink = $('.cart-link'), $wrap = $('#wrap');
$cartlink.on('click', function() {
$cartlink.toggleClass('active');
$wrap.toggleClass('active');
return false;
});
// Clicking outside the cart closes the cart, unless target is the "Add to Cart" button
$wrap.on('click', function(e){
if (!$(e.target).is('.add')) {
$wrap.removeClass('active');
$cartlink.removeClass('active');
}
});
// Calculates and updates totals, taxes, shipping
function calculateAndUpdate() {
var subtotal = 0,
items = $cart.children(),
// shipping not applied if there are no items
shipping = items.length > 0 ? 5 : 0,
tax = 0;
items.each(function(index, item) {
var $item = $(item),
price = $item.data('subtotal');
subtotal += price;
});
$('.subtotalTotal span').text(formatDollar(subtotal));
tax = subtotal * .05;
$('.taxes span').text(formatDollar(tax));
$('.shipping span').text(formatDollar(shipping));
$('.finalTotal span').text(formatDollar(subtotal + tax + shipping));
}
// Update the total quantity of items in notification, hides if zero
function updateCartQuantity() {
var quantities = 0,
$cartQuantity = $('span.cart-quantity'),
items = $cart.children();
items.each(function(index, item) {
var $item = $(item),
quantity = +$item.find('.quantity').val();
quantities += quantity;
});
if(quantities > 0){
$cartQuantity.removeClass('empty');
} else {
$cartQuantity.addClass('empty');
}
$cartQuantity.text(quantities);
}
// Formats number into dollar format
function formatDollar(amount) {
return '$' + parseFloat(Math.round(amount * 100) / 100).toFixed(2);
}
// Restrict the quantity input field to numbers only
$('body').on('keypress', '.cart-items input', function (ev) {
var keyCode = window.event ? ev.keyCode : ev.which;
if (keyCode < 48 || keyCode > 57) {
if (keyCode != 0 && keyCode != 8 && keyCode != 13 && !ev.ctrlKey) {
ev.preventDefault();
}
}
});
// Trigger animation on Add to Cart button click
$('.addtocart').on('click', function () {
$(this).addClass('active');
setTimeout(function () {
$('.addtocart').removeClass('active');
}, 1000);
});
// Trigger error animation on Checkout button
$('.checkout').on('click', function () {
$(this).addClass('active');
$('.error').css('display', 'block');
setTimeout(function () {
$('.checkout').removeClass('active');
$('.error').css('display', 'none');
}, 1000);
});
});
Also see: Tab Triggers