<div class="codepen">
<header class="pen">
<svg
viewbox="0 0 100 100"
class="icon icon-codepen-box"
aria-role="presentation"
>
<path
d="M100 34.2c-.4-2.6-3.3-4-5.3-5.3-3.6-2.4-7.1-4.7-10.7-7.1-8.5-5.7-17.1-11.4-25.6-17.1-2-1.3-4-2.7-6-4-1.4-1-3.3-1-4.8 0-5.7 3.8-11.5 7.7-17.2 11.5L5.2 29C3 30.4.1 31.8 0 34.8c-.1 3.3 0 6.7 0 10v16c0 2.9-.6 6.3 2.1 8.1 6.4 4.4 12.9 8.6 19.4 12.9 8 5.3 16 10.7 24 16 2.2 1.5 4.4 3.1 7.1 1.3 2.3-1.5 4.5-3 6.8-4.5 8.9-5.9 17.8-11.9 26.7-17.8l9.9-6.6c.6-.4 1.3-.8 1.9-1.3 1.4-1 2-2.4 2-4.1V37.3c.1-1.1.2-2.1.1-3.1 0-.1 0 .2 0 0zM54.3 12.3L88 34.8 73 44.9 54.3 32.4V12.3zm-8.6 0v20L27.1 44.8 12 34.8l33.7-22.5zM8.6 42.8L19.3 50 8.6 57.2V42.8zm37.1 44.9L12 65.2l15-10.1 18.6 12.5v20.1zM50 60.2L34.8 50 50 39.8 65.2 50 50 60.2zm4.3 27.5v-20l18.6-12.5 15 10.1-33.6 22.4zm37.1-30.5L80.7 50l10.8-7.2-.1 14.4z"
></path>
</svg>
<div class="pen__details">
<h1>
Yo dawg! I hear you like codepen, so I..<i
class="fa fa-pencil"
aria-hidden="true"
></i>
</h1>
<p class="pen__author">Xzibit</p>
</div>
<button class="button button--outline">
<i class="fa fa-heart"></i>
</button>
<button class="button--dirty button--outline save-button">
️️ <i class="fa fa-cloud"></i><span class="text">Save</span>
</button>
<button class="button settings-button">
<i class="fa fa-cog"></i><span class="text">Settings</span>
</button>
<button class="button">
<i class="fa fa-window-maximize"></i><span class="text">Change View</span>
</button>
<button class="button button--outline">
<i class="fa fa-thumb-tack"></i>
</button>
<button class="button menu-button"><i class="fa fa-bars"></i></button>
<img
class="avatar"
src="https://cdn.imgpaste.net/2020/04/10/pMXuE.jpg"
alt="Xzibit"
/>
</header>
<section class="code">
<div class="editor">
<div class="editor__divider"></div>
<header class="editor__header">
<button class="button button--small editor__settings">
<i class="fa fa-cog"></i>
</button>
<h3 class="editor__heading">HTML</h3>
<button class="button button--small editor__settings">
<i class="fa fa-arrow-down"></i>
</button>
</header>
<div class="editor__code">
<div class="editor__gutter">
<span class="editor__number">1</span>
<span class="editor__number">2</span>
<span class="editor__number">3</span>
<span class="editor__number">4</span>
<span class="editor__number">5</span>
<span class="editor__number">6</span>
</div>
<code contenteditable="true" class="editor__input">
<div class="view-line">
<span>
<span class="mtk10"><</span><span class="mtk14">html</span
><span class="mtk1"> </span><span class="mtk4">lang</span
><span class="mtk1">=</span><span class="mtk6">"en"</span
><span class="mtk10">></span></span
>
</div>
<div class="view-line">
<span
><span class="mtk10"><</span><span class="mtk14">head</span
><span class="mtk10">></span></span
>
</div>
<div class="view-line">
<span
><span class="mtk10"><</span><span class="mtk14">meta</span
><span class="mtk1"> </span><span class="mtk4">charset</span
><span class="mtk1">=</span><span class="mtk6">"UTF-8"</span
><span class="mtk10">></span></span
>
</div>
<div class="view-line">
<span
><span class="mtk10"><</span><span class="mtk14">title</span
><span class="mtk10">></span
><span class="mtk1">Yo dawg! I hear you like grids, so I..</span
><span class="mtk10"></</span><span class="mtk14">title</span
><span class="mtk10">></span></span
>
</div>
<div class="view-line">
<span
><span class="mtk10"><</span><span class="mtk14">meta</span
><span class="mtk1"> </span><span class="mtk4">name</span
><span class="mtk1">=</span
><span class="mtk6">"twitter:card"</span
><span class="mtk1"> </span><span class="mtk4">content</span
><span class="mtk1">=</span
><span class="mtk6">"summary_large_image"</span
><span class="mtk10">></span></span
>
</div>
<div class="view-line">
<span
><span class="mtk10"><</span><span class="mtk14">meta</span
><span class="mtk1"> </span><span class="mtk4">name</span
><span class="mtk1">=</span
><span class="mtk6">"twitter:site"</span
><span class="mtk1"> </span><span class="mtk4">content</span
><span class="mtk1">=</span><span class="mtk6">"@CodePen"</span
><span class="mtk10">></span></span
>
</div>
</code>
</div>
</div>
<div class="editor">
<div class="editor__divider resizable"></div>
<header class="editor__header">
<button class="button button--small editor__settings">
<i class="fa fa-cog"></i>
</button>
<h3 class="editor__heading">CSS</h3>
<button class="button button--small editor__settings">
<i class="fa fa-arrow-down"></i>
</button>
</header>
<div class="editor__code">
<div class="editor__gutter">
<span class="editor__number">1</span>
<span class="editor__number">2</span>
<span class="editor__number">3</span>
<span class="editor__number">4</span>
<span class="editor__number">5</span>
<span class="editor__number">6</span>
</div>
<code contenteditable="true" class="editor__input editor__input_css">
<div class="view-line">
<span
><span class="mtk14">*</span
><span class="mtk14"> {</span></span
>
</div>
<div class="view-line">
<span
><span class="mtk1"> </span><span class="mtk4">margin:</span
><span class="mtk7">0</span><span class="mtk14">;</span></span
>
</div>
<div class="view-line">
<span
><span class="mtk1"> </span><span class="mtk4">padding:</span
><span class="mtk7">0</span><span class="mtk14">;</span></span
>
</div>
<div class="view-line">
<span
><span class="mtk1"> </span
><span class="mtk4">-webkit-box-sizing:</span
><span class="mtk5">border-box</span
><span class="mtk14">;</span></span
>
</div>
<div class="view-line">
<span
><span class="mtk4"> box-sizing:</span
><span class="mtk5">border-box</span
><span class="mtk14">;</span></span
>
</div>
<div class="view-line">
<span><span class="mtk14">}</span></span>
</div>
</code>
</div>
</div>
<div class="editor">
<div class="editor__divider resizable"></div>
<header class="editor__header">
<button class="button editor__settings">
<i class="fa fa-cog"></i>
</button>
<h3 class="editor__heading">JS</h3>
<button class="button button--small editor__settings">
<i class="fa fa-arrow-down"></i>
</button>
</header>
<div class="editor__code">
<div class="editor__gutter">
<span class="editor__number">1</span>
</div>
<code contenteditable="true" class="editor__input"
><span class="mkt11">/* ^^ Save me! 😛 */</span></code
>
</div>
</div>
<div class="code__divider"></div>
</section>
<section class="preview">
<iframe
src="https://i.kym-cdn.com/photos/images/original/000/280/163/f92.jpg"
frameborder="0"
></iframe>
</section>
<footer class="settings">
<button class="button footer-button menu-button">
<i class="fa fa-arrow-up"></i>
</button>
<button class="button console-button footer-button">Console</button>
<button class="button footer-button">Assets</button>
<button class="button footer-button">Comments</button>
<button class="button shortcuts-button footer-button">Shortcuts</button>
<p class="settings__save">Last saved 9 MONTHS ago</p>
<button class="button footer-button">
<i class="fa fa-external-link"></i>
</button>
<button class="button footer-button">Delete</button>
<button class="button footer-button">Add to Collection</button>
<button class="button footer-button">Fork</button>
<button class="button footer-button">Embed</button>
<button class="button footer-button">Export</button>
<button class="button footer-button">Share</button>
</footer>
</div>
:root {
--bright-grey: #9b9dad;
--light-grey: #444857;
--faded-button-grey: #adafbc;
--hover-grey: #929292c4;
--grey-header: #aaaebc;
--grey: #343436;
--dirty-yellow:#ffdd40;
--bg-footer: #2c303a;
--bg-black:#1e1f26;
--bg-dark-black:rgb(29, 29, 29);
--divider-black: #333642
}
html {
font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", Tahoma,
Sans-Serif;
font-weight: 400;
color: white;
text-shadow: 0 2px 0 rgba(0, 0, 0, 0.07);
font-size:15px;
}
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
min-height: 100vh;
}
h1, h2, h3, h4, h5,h6 {
font-weight: normal;
}
h1{
line-height: 1.1;
}
/* buttons */
button {
background: var(--light-grey);
border-radius: 4px;
cursor: pointer;
color:white;
font-size:1em;
line-height:1.2em;
padding: 10px 8px;
border: 3px solid var(--light-grey);
white-space: nowrap;
overflow: hidden;
}
/* for media queries */
header button:not(.menu-button), footer button:not(.menu-button){
display:none;
}
.menu-button{
display:inline-block;
}
/* END: for media queries */
button i{
margin-right:3px;
}
button .text{
display:none;
}
.save-button{
padding:10px 6px 10px 4px;
}
.button:hover, .button--dirty:hover{
background:var(--hover-grey);
}
.button--outline {
border: 3px solid var(--light-grey);
background: none;
}
.button--small {
font-size: 12px;
}
.button--dirty{
position:relative;
}
.button--dirty:before {
background: var(--dirty-yellow);
display: block;
content: '';
height: 3px;
width: calc(100% - 6px);
position: absolute;
left: 3px;
top: 1px;
}
.settings-button{
display:none;
}
.footer-button {
font-size: 0.75rem;
background: none;
border: 0;
color: #b7bbc8;
padding: 8px;
border-radius: 0;
margin: 0;
border-left: 1px solid var(--light-grey);
}
.console-button{
border:none;
}
.shortcuts-button{
border-right: 1px solid var(--light-grey);
}
/* App */
.codepen {
display: grid;
grid-template-rows: 65px 350px 1fr auto;
height: 100vh;
}
/* Header */
.pen {
background: var(--bg-black);
display: grid;
grid-template-columns: 30px 1fr;
grid-auto-flow: column;
align-items: center;
gap: 10px;
}
.pen .icon{
fill:white;
height:30px;
width:30px;
margin-left:5px;
}
.pen h1{
font-weight: 700;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
display: inline-block;
vertical-align: middle;
font-size:1.2rem;
}
.pen h1 i{
margin-left:5px;
}
.pen__author {
color:var(--bright-grey);
font-size: .8rem;
letter-spacing:0;
}
.pen button i{
color: var(--faded-button-grey);
}
.pen .avatar{
border-radius: 4px;
height:45px;
margin-right:5px;
}
/* Editor*/
.code {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 1fr auto;
background: #1b2b34;
}
.code__divider{
height:17px;
background: var(--divider-black);
border-bottom: 1px solid black;
-webkit-box-shadow: 0 0 1px black;
box-shadow: 0 0 1px black;
grid-column: 1 / -1;
cursor: row-resize;
}
.editor {
display: grid;
grid-template-rows: auto 1fr;
grid-template-columns: auto 1fr;
overflow: auto;
}
.editor__divider{
width: 18px;
border-left: 1px solid rgba(255,255,255,0.05);
border-right: 1px solid rgba(0,0,0,0.4);
background: var(--divider-black);
grid-row: 1 / -1;
}
.resizable{
cursor: col-resize;
}
.editor__header {
background: var(--bg-dark-black);
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
padding: 0 5px;
grid-gap: 5px;
border-bottom: 1px solid rgba(255,255,255,0.05);
grid-column:2 / 3;
}
.editor__heading {
color: var(--grey-heading);
font-weight: bold;
padding-top:5px;
}
.editor__code {
display: grid;
grid-template-columns: auto 1fr;
background:var(--bg-black);
grid-column: 2 / 3;
}
.editor__header button {
font-size: 0.8rem;
padding: 2px 7px;
margin: 0 1px 0 0;
border-width: 1px;
border-radius: 2px;
}
.editor__number {
display: block;
padding: 0 10px;
font-family: Monaco, MonoSpace;
color:var(--grey);
}
.editor__input {
resize: none;
background: none;
border: 0;
color:white;
font-family: Monaco, MonoSpace;
font-size:15px;
outline:none;
overflow:hidden;
}
/* code styles */
/*html*/
.mtk1 {
color: white;
}
.mtk4 {
color: #ddca7e;
}
.mtk6 {
color: #96b38a;
}
.mtk10, .mtk14 {
color: #a7925a;
}
.mkt11{
color:var(--bright-grey);
}
/*css*/
.editor__input_css .mtk1{
color: #ddca7e;
}
.editor__input_css .mtk4 {
color: #9a8297;
}
.editor__input_css .mtk5 {
color: #ddca7e;
}
.editor__input_css .mtk7{
color: #d0782a
}
.editor__input_css .mtk10, .editor__input_css .mtk14 {
color: white;
}
/* Preview */
.preview iframe {
height: 100%;
width: 100%;
}
/* Footer */
footer {
display:grid;
grid-template-columns: repeat(4, auto) 1fr;
grid-auto-flow: column;
align-items: center;
line-height: 1;
padding: 0 5px;
white-space: nowrap;
color: var(--bright-grey);
background: var(--bg-footer);
border-top: 1px solid var(--light-grey);
font-size: 1rem;
}
.settings__save{
display:none;
justify-self: end;
padding-right:5px;
letter-spacing: 0.5px;
font-size: 80%;
}
@media screen and (min-width:1000px){
button{
padding: 10px 16px;
}
.settings-button{
display:inline;
}
button .text{
display:inline;
}
}
@media screen and (min-width:750px) {
.menu-button{
display:none;
}
header button:not(.menu-button), footer button:not(.menu-button){
display:inline-block;
}
.settings__save{
display:inline;
}
}
const saveBtn = document.querySelector(".save-button");
saveBtn.addEventListener("click", save);
function save() {
window.alert(
"Yo Dawg! Dont be confused. This is a recreation of the codepen UI."
);
}
A recreation of the codepen user interface using CSS Grid.
Optimized for tablet and desktop viewports. I did not bother creating the more involved view for a phone viewport where the editor panes are stacked in a tabbed pane.