<header>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/logo-white-badge.png" alt=""> What we built for you in <span>2019</span>
</header>
<div class="slides">
<article class="slide large layout-4 active" id="slide-0">
<h1 class="title panel">We've been <span>building CodePen</span> for 8 years.</h1>
<div class="desc panel">
<p>👋 Hey! Since 2012, we've been trying to make CodePen the most useful and fun social coding platform for front-end developers and designers as we can.</p>
<p>We've built loads of features in that time for both free and <a href="https://codepen.io/pro" target="_blank">PRO</a> users. Let's take a look at some of the features we built for you <strong>just in 2019.</strong></p>
<p>But nothing compares to the incredible things <a href="https://codepen.io/2019/popular/pens/" target="_blank">y'all build</a> each year, of course 😉.</p>
</div>
</article>
<article class="slide layout-1 active" id="slide-1">
<h2 class="title panel">You can <span>restore</span> your deleted Pens in case of an accident.</h2>
<div class="desc panel">
<p>We trashed the place, you might say.</p>
<p>We don't actually call it a trash can, as CodePen is a rather international place and not all countries use that term. There are rubbish bins, waste containers, garbage pails, litter piles...</p>
<p>Ultimately, the tab in your Dashboard is called "Deleted" and it's where you can restore your work from if you accidently delete it.</p>
<p>🎧 <a href="https://blog.codepen.io/2019/05/22/222-trash-can/">Podcast</a></p>
<p>📓 <a href="https://blog.codepen.io/documentation/editor/how-do-i-delete-a-pen/">Documentation</a></p>
</div>
<img class="img panel" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/dashboard_copy.jpg" alt="">
</article>
<article class="slide layout-5" id="slide-2">
<h2 class="title panel">The code for Embedded Pens can live on <span>your own website</span>.</h2>
<div class="desc panel">
<p>We call this "Prefill Embeds".</p>
<p>Say you're building a documentation site. It might be easier for you to keep all your demo code in the Git repo rather than have to maintain the demos directly on CodePen. Now, you can.</p>
<p>📓 <a href="https://blog.codepen.io/documentation/prefill-embeds/">Documentation</a></p>
<p>🎧 <a href="https://blog.codepen.io/2019/01/22/207-prefill-embeds/">Podcast</a></p>
<p>Embeds are now <a href="https://blog.codepen.io/2019/02/08/faster-no-reflow-embeds/">faster and don't cause page-reflow</a> as they load.</p>
</div>
<div class="img panel">
<video src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/Do5A7kP9lsPoHZ6N.mp4" controls style="border: 10px solid white;"></video>
</div>
</article>
<article class="slide layout-3" id="slide-3">
<h2 class="title panel">We overhauled the <span>Job Board</span>.</h2>
<div class="desc panel">
<p><a href="https://codepen.io/jobs/">The Job Board</a> got a fresh coat of paint (gradient people!) but we went deeper than that.</p>
<ul>
<li><a href="https://codepen.io/job/new/">Posting a job</a> got a lot easier. It's a single screen and you're done, whether you have an account or not.</li>
<li>Jobs stay on the board for 60 days instead of 30 at the same price.</li>
<li>Your jobs are still automatically cross-posted to <a href="https://css-tricks.com/jobs/">CSS-Tricks</a> and <a href="https://shoptalkshow.com/jobs/">ShopTalk Show</a>.</li>
</ul>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/job-board.jpg" alt="" class="img panel">
</article>
<article class="slide layout-4" id="slide-4">
<h2 class="title panel">Specific Frameworks, Libraries, and UI patterns got homes in <span>Topics</span>.</h2>
<div class="desc panel">
<p><a href="https://codepen.io/topics/">Topics</a> are templates, examples and resources for common libraries, frameworks and UI patterns.</p>
<p>We've got topics for the big JavaScript UI frameworks like React and Vue. We've got the popular animation libraries like Greensock and anime.js. Our very own Stephen Shaw's Splitting.js is in there. CSS heavy hitters like Sass and Tailwind are there.</p>
<p>Plus, we've got a Topic for all the major UI patterns on websites like Tabs, Accordions, and Dialogs.</p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/topics.png" alt="Topics" class="img panel">
</article>
<article class="slide layout-2" id="slide-5">
<h2 class="title panel">The Pen Editor went entirely <span>responsive</span>.</h2>
<div class="desc panel">
<p>It's not that we didn't have an editor that worked on mobile devices before. We did. But it was an entirely separate world of code that powered it. So in one sense, it's probably us who benefits from this the most since there is now one codebase powering the Pen Editor on any screen.</p>
<p>In another sense, the new mobile editor should be way nicer for you as well. Mostly because it's now full-featured. You can use the console, you can comment, you can analyze and tidy your code... it's a great editing experience on mobile and desktop.</p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/editor-responsive.jpg" alt="" class="img panel">
</article>
<article class="slide layout-4" id="slide-6">
<h2 class="title panel">We created our own <span>high-contrast</span> syntax highlighting themes.</h2>
<div class="desc panel">
<p>Klare Frank put these together (there is both a dark and a light version) and they are, we think, hands down the nicest themes we offer. They are based somewhat on CodePen's own brand colors, which somehow work perfectly.</p>
<p>📝 <a href="https://blog.codepen.io/2019/09/09/new-high-contrast-syntax-highlighting-themes/">Blog Post</a></p>
<p>🎧 <a href="https://blog.codepen.io/2019/09/23/238-high-contrast-syntax-highlight-theme/">Podcast</a></p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/high-contrast-dark.png" alt="" class="img panel">
</article>
<article class="slide layout-4" id="slide-7">
<h2 class="title panel">Managing <span>Collections</span> got a whole lot better.</h2>
<div class="desc panel">
<p>A lot of things related to Collections got better this year. The top improvement is the whole UI/UX around adding Pens to Collections. Rather than a basic dropdown menu, you get an interface designed just for the job with recent Collections up top, searching, creating new Collections, and more. We did a few more things as well:</p>
<ul>
<li>We <a href="https://blog.codepen.io/2019/09/25/collections-clarification-message/">clarified</a> how Private Pens in Collections works.</li>
<li>Collections now offer List View</li>
<li>Collections in the grid show a 4-up preview of the Pens it contains.</li>
</ul>
<p>🎧 <a href="https://blog.codepen.io/2019/10/17/242-collections/">Podcast</a></p>
<p>📓 <a href="https://blog.codepen.io/2019/11/13/better-collections-management/">Blog Post</a></p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-1/collections-improvements.jpg" alt="" class="img panel">
</article>
<article class="slide layout-1" id="slide-8">
<h2 class="title panel">You can now <span>block</span> other users.</h2>
<div class="desc panel">
<p>We have such a positive community that this feature wasn't a result of us scrambling to fix bad behavior, but rather an effort to maintain and affirm that we want to keep this place welcoming and safe.</p>
<p>🎧 <a href="https://blog.codepen.io/2019/09/04/235-blocking/">Podcast</a></p>
<p>📓 <a href="https://blog.codepen.io/documentation/features/blocking/">Documentation</a></p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/blocking.jpg" alt="" class="img panel" style="border-top-left-radius: 10px;">
</article>
<article class="slide layout-3" id="slide-9">
<h2 class="title panel">Exported Pens can come with a <span>Build Process</span></h2>
<div class="desc panel">
<p>You've always been able to export a .zip file of the code you write. But now, PRO users can export that code, <code>npm install</code>, and keep working on it (even offline). The build process will process code just like CodePen does for you.</p>
<p>📓 <a href="https://blog.codepen.io/documentation/pro-features/export-with-build-process/">Documentation</a></p>
<p>🎧 <a href="https://blog.codepen.io/2019/08/08/233-export-2/">Podcast</a></p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/build-process.jpg" alt="" class="img panel">
</article>
<article class="slide layout-2" id="slide-10">
<h2 class="title panel">The <span>Popout Preview</span></h2>
<div class="desc panel">
<p>On any Pen or Project that you see in a grid (like on the homepage, your profile, search results, etc) you can click in the upper-right and expand the Pen into a full-blown preview.</p>
<p>From there, you can resize and interact with the preview. You can see the code. You can comment. You can see the tags and stats. All without leaving your place.</p>
<p>🎧 <a href="https://blog.codepen.io/2019/11/27/246-pop-out-previews/">Podcast</a></p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/popout-preview.jpg" alt="" class="img panel">
</article>
<article class="slide layout-4" id="slide-11">
<h2 class="title panel">So. Much. <span>Infastructure</span>.<br><br> 🛠</h2>
<div class="desc panel">
<ul>
<li>We totally re-wrote our search system, <a href="https://blog.codepen.io/2019/10/02/from-solr-to-elasticsearch/">moving from Solr to Elasticsearch</a>.</li>
<li>The front-end stack we've grown to be pretty happy with is React and Apollo GraphQL and now <em>most</em> of our front end is built that way, although we have plenty to go.</li>
<li>Ruby on Rails is our backend which we've upgraded many versions.</li>
<li>We've gotten both our own codebase and the preprocessor in the Pen Editor on Babel 7.</li>
<li>We moved all our Node code to a single monorepo, which is a big efficiency upgrade.</li>
<li>We changed the domain for all previews to a new more secure location.</li>
<li>We went to war with spam, building new tooling to catch and destroy all who seek to litter their garbage here.</li>
<li>We built internal tools to improve and quicken our dev environments.</li>
</ul>
</div>
<img src="" alt="" class="img panel">
</article>
<article class="slide layout-3" id="slide-12">
<h2 class="title panel">Private by Default.</h2>
<div class="desc panel">
<p>It's just a little toggle switch you turn on in your Settings and then everything you save is, you guessed it, Private by default. You can still toggle it back to public if you wish, but if most of the work you do is private, this will keep you from accidently leaving things public.</p>
<p>📝 <a href="https://blog.codepen.io/2019/09/10/new-pro-feature-private-by-default/">Blog Post</a></p>
<p>🎧 <a href="https://blog.codepen.io/2019/09/11/236-private-by-default/">Podcast</a></p>
</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/private-by-default.png" alt="" class="img panel">
</article>
</div>
<footer>
<nav class="jump-nav">
<a href="#slide-0" class="footer-jump">0</a>
<a href="#slide-1" class="footer-jump">1</a>
<a href="#slide-2" class="footer-jump">2</a>
<a href="#slide-3" class="footer-jump">3</a>
<a href="#slide-4" class="footer-jump">4</a>
<a href="#slide-5" class="footer-jump">5</a>
<a href="#slide-6" class="footer-jump">6</a>
<a href="#slide-7" class="footer-jump">7</a>
<a href="#slide-8" class="footer-jump">8</a>
<a href="#slide-9" class="footer-jump">9</a>
<a href="#slide-10" class="footer-jump">10</a>
<a href="#slide-11" class="footer-jump">11</a>
<a href="#slide-12" class="footer-jump">12</a>
</nav>
<nav class="pagination-nav">
<button class="pagination-button" data-go="-1">Prev</button>
<button class="pagination-button" data-go="1">Next</button>
</nav>
</footer>
$mobile: "max-width: 800px";
:root {
--duration: .3s;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol";
line-height: 1.5;
overflow-y: scroll;
overflow-x: hidden;
display: grid;
grid-template-rows: min-content 1fr min-content;
}
header, footer {
display: flex;
align-items: center;
background: black;
color: white;
padding: 0.5rem 11px 0.5rem 0;
position: fixed;
width: 100%;
}
header {
top: 0;
z-index: 1;
font-weight: 800;
line-height: 1;
text-transform: uppercase;
img {
width: 30px;
height: 30px;
margin-right: 0.5rem;
}
span {
color: #8F5EEC;
margin-left: 0.4rem;
}
}
footer {
bottom: 0;
justify-content: space-between;
a {
text-decoration: none;
}
}
/* ---------------------------------- */
.slides {
animation: fade-in var(--duration) linear var(--duration) both;
@keyframes fade-in {
from { opacity: 0; }
}
&[data-js-initialized] {
display: grid;
grid-template: 1 / 1 / 1 / 1;
> * { grid-area: 1 / 1; }
}
}
.slide {
display: grid;
min-height: 100vh;
grid-template-columns: 1fr 1fr;
grid-template-rows: min-content 1fr;
padding: 46px 0 4px;
@media ($mobile) {
display: block;
.title,
.desc {
margin: 1rem;
}
}
.title,
.desc {
margin: 2rem;
padding: 0;
}
.title {
grid-area: title;
font-weight: 900;
font-size: 3.2rem;
letter-spacing: -2px;
line-height: 1.1;
span {
color: #975BF4;
}
@media ($mobile) {
font-size: 2.5rem;
}
}
.desc {
grid-area: desc;
font-size: 1.4rem;
font-weight: 300;
p {
margin: 0 0 1rem 0;
}
a {
color: #975BF4;
&:hover,
&:focus {
color: #5100b0;
}
}
}
.img {
grid-area: img;
align-self: end;
}
&.large {
.title {
font-size: 5rem;
@media ($mobile) {
font-size: 3rem;
}
}
}
}
.layout-1 {
grid-template-areas:
"desc title"
"desc img";
}
.layout-2 {
grid-template-areas:
"img title"
"img desc";
}
.layout-3 {
grid-template-areas:
"title img"
"desc img";
}
.layout-4 {
grid-template-areas:
"title desc"
"img img";
}
.layout-5 {
grid-template-areas:
"img title"
"desc desc";
}
img, video {
max-width: 100%;
}
p {
max-width: 900px;
}
/* ---------------------------------- */
.pagination-button {
text-decoration: none;
display: inline-block;
padding: 0.4rem .8rem;
color: white;
font-weight: 800;
border: none;
border-radius: 4px;
background: #444857;
text-shadow: 0 1px 2px rgba(black, 0.25);
z-index: 1;
&:hover,
&:focus {
background: #66bb6a;
}
}
.footer-jump {
display: inline-block;
padding: 0.2em 0.25em;
@media ($mobile) {
padding: 0.2rem 0.1rem;
}
@media (max-width: 400px) { display: none; }
color: white;
font-size: 16px;
font-family: monospace;
opacity: 0.6;
transform: scale(0.8);
transition: var(--duration) linear;
&:hover,
&:focus {
opacity: 0.9;
}
&[data-active] {
opacity: 1;
transform: scale(1);
}
}
/* ---------------------------------- */
.slide {
transition: visibility 0s linear;
}
.panel {
transition: all var(--duration) cubic-bezier(.8, 0, .2, 1) var(--duration);
}
.slide[hidden] {
z-index: -1;
display: grid;
@media ($mobile) {
display: block;
}
visibility: hidden;
pointer-events: none;
max-height: 100vh;
overflow: hidden;
transition-delay: var(--duration);
.panel {
opacity: 0;
transition-delay: 0s;
}
.img {
transform: translateY(100px);
}
.title {
transform: translateY(-100px);
}
.desc {
transform: translateX(-100px);
}
}
// Scrollbars
html {
--scrollbarBG: black;
--thumbBG: #90A4AE;
height: 100%;
}
body::-webkit-scrollbar {
width: 11px;
}
body {
border-left: 11px solid black;
min-height: 100%;
scrollbar-width: thin;
scrollbar-color: var(--thumbBG) var(--scrollbarBG);
}
body::-webkit-scrollbar-track {
background: var(--scrollbarBG);
}
body::-webkit-scrollbar-thumb {
background-color: var(--thumbBG) ;
border-radius: 6px;
border: 3px solid var(--scrollbarBG);
}
/* ---------------------------------- */
// One offs
.twitter-tweet {
margin: 0 auto;
}
View Compiled
console.clear();
/* Slide setup */
const elSlidesContainer = document.querySelector('.slides');
const slideEls = [...document.querySelectorAll('.slide')];
const footerJumpButtons = document.querySelectorAll(".footer-jump");
/* ---------------------------------- */
let active = 0;
function hideSlides(){
slideEls.forEach( el => el.setAttribute('hidden', ''));
footerJumpButtons.forEach( el => delete el.dataset.active );
}
function goToSlide(slideIndex){
window.scroll({
top: 0,
left: 0,
behavior: 'smooth'
});
hideSlides();
// Loop around the array.
var len = slideEls.length;
active = ( ( slideIndex % len) + len ) % len;
slideEls[active].removeAttribute('hidden');
footerJumpButtons[active].dataset.active = true;
}
function goToSlideEl(el){
goToSlide(slideEls.indexOf(el));
}
goToSlide(active);
elSlidesContainer.dataset.jsInitialized = true;
/* ---------------------------------- */
footerJumpButtons.forEach(button => {
button.addEventListener(
"click",
()=> goToSlideEl(document.querySelector(button.hash))
);
});
/* ---------------------------------- */
const paginationButtons = document.querySelectorAll('.pagination-button');
paginationButtons.forEach( button => {
let go = Number(button.dataset.go);
button.addEventListener('click', ()=> goToSlide(active + go) );
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.