Pen Settings



CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource


Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

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.

+ add another resource


Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.


                <!--There are probably better ways to do this than hard-code everything in the HTML, but ¯\_(ツ)_/¯ -->
<div id="text">
	<div id="enteredText">Click here, then start typing!</div>
<div class="container">
	<div id="keyboard">
		<div id="firstrow" class="keyboard-row">
			<kbd class="shifter" id="192">`</kbd>
			<kbd class="shifter" id="49">1</kbd>
			<kbd class="shifter" id="50">2</kbd>
			<kbd class="shifter" id="51">3</kbd>
			<kbd class="shifter" id="52">4</kbd>
			<kbd class="shifter" id="53">5</kbd>
			<kbd class="shifter" id="54">6</kbd>
			<kbd class="shifter" id="55">7</kbd>
			<kbd class="shifter" id="56">8</kbd>
			<kbd class="shifter" id="57">9</kbd>
			<kbd class="shifter" id="48">0</kbd>
			<kbd class="shifter" id="189">-</kbd>
			<kbd class="shifter" id="187">=</kbd>
			<kbd class="long operationKey" id="8">del</kbd>
		<div id="secondrow" class="keyboard-row">
			<kbd class="long operationKey" id="9">tab</kbd>
			<kbd id="81">q</kbd>
			<kbd id="87">w</kbd>
			<kbd id="69">e</kbd>
			<kbd id="82">r</kbd>
			<kbd id="84">t</kbd>
			<kbd id="89">y</kbd>
			<kbd id="85">u</kbd>
			<kbd id="73">i</kbd>
			<kbd id="79">o</kbd>
			<kbd id="80">p</kbd>
			<kbd class="shifter" id="219">[</kbd>
			<kbd class="shifter" id="221">]</kbd>
			<kbd class="shifter" id="220">\</kbd>
		<div id="thirdrow" class="keyboard-row">
			<kbd class="long operationKey" id="20">caps</kbd>
			<kbd id="65">a</kbd>
			<kbd id="83">s</kbd>
			<kbd id="68">d</kbd>
			<kbd id="70">f</kbd>
			<kbd id="71">g</kbd>
			<kbd id="72">h</kbd>
			<kbd id="74">j</kbd>
			<kbd id="75">k</kbd>
			<kbd id="76">l</kbd>
			<kbd class="shifter" id="186">;</kbd>
			<kbd class="shifter" id="222">'</kbd>
			<kbd class="long operationKey" id="13">return</kbd>
		<div id="fourthrow" class="keyboard-row">
			<kbd class="longer operationKey" id="16">shift</kbd>
			<kbd id="90">z</kbd>
			<kbd id="88">x</kbd>
			<kbd id="67">c</kbd>
			<kbd id="86">v</kbd>
			<kbd id="66">b</kbd>
			<kbd id="78">n</kbd>
			<kbd id="77">m</kbd>
			<kbd class="shifter" id="188">,</kbd>
			<kbd class="shifter" id="190">.</kbd>
			<kbd class="shifter" id="191">/</kbd>
			<kbd class="longer operationKey" id="16">shift</kbd>
		<div id="fifthrow" class="keyboard-row">
			<kbd class="operationKey" id="188">fn</kbd>
			<kbd class="operationKey" id="17">ctrl</kbd>
			<kbd class="operationKey" id="18">opt</kbd>
			<kbd class="long operationKey" id="91">⌘</kbd>
			<kbd class="spacebar operationKey" id="32">&nbsp;</kbd>
			<kbd class="long operationKey" id="91">⌘</kbd>
			<kbd class="operationKey" id="18">opt</kbd>
			<kbd class="operationKey" id="17">ctrl</kbd>
			<kbd class="operationKey" id="188">fn</kbd>
<br><pre style="width: 100%; text-align: center;">Click the screen or type shift + delete to clear all text.</pre>


                //Set up some color variables
$darkgray: #53565a;
$midgray: #888b8d;
$lightgray: #a7a8aa;
$yellow: #ffd100;

//Lots of stuff be flexin'
@mixin flexy {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-pack: center;
	-ms-flex-pack: center;
	        justify-content: center;
	-webkit-box-align: center;
	-ms-flex-align: center;
	        align-items: center;
	-ms-flex-line-pack: center;
	    align-content: center;
	-ms-flex-wrap: wrap;
	    flex-wrap: wrap;

* {
	box-sizing: border-box;

body {
	//Change this font-size value to resize the keyboard!
	font-size: 8px;
	@include flexy;
	width: 100%;
	margin: 0;
	box-sizing: border-box;
	font-family: Quicksand;
	height: 100vh;
	max-height: 100vh;
	overflow: hidden;
	//The keyboard containing div and all key elements
	#keyboard, kbd {
		@include flexy;
		box-sizing: border-box;
		border-radius: 4px;
		background: #ccc;
		border: .2em solid $midgray;
		text-align: center;
		font-family: Quicksand;
	kbd {
		flex: 1;
	.keyboard-row {
		@include flexy;
		width: 100%;
	//The box the typed text appears in
	div#text {
		@include flexy;
		align-items: flex-end;
		width: 20em;
		height: 44vh;
		max-height: 44vh;
		font-size: 3em;
		margin-bottom: 4vh;
		text-align: center;
		overflow: auto;
		align-self: flex-end;
		position: relative;
	//The div containing the keys
	#keyboard {
		width: 56em;
		padding: .4em .4em .8em;
		box-shadow: 0 .4em 0 $midgray;
		//The elements that make up the keys themselves
		kbd {
			line-height: 3.2em;
			height: 3.2em;
			width: 3.2em;
			margin: .25em;
			text-align: center;
			color: #fff;
			background-color: $darkgray;
			transition: background, position, top, box-shadow .1s;
			box-shadow: 0px 2px 0px $midgray;

		//For slightly wider keys
		kbd.long {
			flex-grow: 1;
			flex: 2;

		//For much wider keys
		kbd.longer {
			flex-grow: 2;
			flex: 3;
		//For the widest key
		kbd.spacebar {
			flex-grow: 14;
			flex: 6;
		//Keep the keys that aren't letters, numbers and punctuation from going to uppercase when shift or capslock is pressed
		.operationKey {
			text-transform: none!important;

		//Styles applied to a currently-pressed key
		.pressed {
			background: $yellow;
			position: relative;
			top: 2px;
			box-shadow: none;
	//Applied to the whole keyboard when shift or capslock is pressed
	pre {
		height: 3vh;
		line-height: 3vh;
	.uppercase kbd {
		text-transform: uppercase;

//Make keyboard responsive, kinda
@media (min-width: 768px) {
	body {
		font-size: 10px;

@media (min-width: 960px) {
	body {
		font-size: 12px;

@media (min-width: 1080px) {
	body {
		font-size: 14px;


 * There are probably better ways of doing a lot of this,
 * but I'm just starting to wade into the deep end of
 * of vanilla JavaScript, so ¯\_(ツ)_/¯
 * Inspired by day 1 of Wes Bos's 30 Day JavaScript Challenge
var x = 'x';
let theTextBox = document.getElementById('enteredText'); 
let allTheKeys = document.getElementById('keyboard'); 
let changeKeys = document.getElementsByClassName('shifter'); 
let capsLockKey = document.getElementById('20');
let shiftKey = document.getElementById('16');

//Store all the original values of the non-alphabetical keys
var originalShifterArray = []; 
for (i = 0; i<changeKeys.length; i++){

//Set up an array for the replacement values of the non-alphabetical keys that get subbed in when Shift is pressed
var shifterArray = ['~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}', '|', ':', '"', '<', '>', '?'];

//Function that clears the text box
function clearText(){
	theTextBox.innerHTML = '<br>';

//Function that detects keypresses and does the appropriate things
function highlightAndType(e){
	var keyPressed = e.keyCode;
	var charPressed = e.key;
	const keys = document.getElementById(keyPressed);
		theTextBox.innerHTML = "Sorry, this pen doesn't work in your browser. :( <br> Try Chrome, Firefox or Opera.";
	//If the user presses CapsLock or Shift, make the alphabetical keys uppercase
	if (charPressed == 'CapsLock' || charPressed == 'Shift') {
	//If the user presses Shift, also replace all non-alphabetical keys with their shifted values
	if (charPressed == 'Shift') {
		for(i = 0; i<changeKeys.length; i++){
			changeKeys[i].innerHTML = shifterArray[i];
	//Make sure the key that was typed was a character
	if (e.key.length <= 1){
			var newText = theTextBox.innerHTML.slice(0, -4);
			theTextBox.innerHTML = newText;
		theTextBox.innerHTML += e.key;
	//If a backspace was typed, delete the last character in the text box. If shift was also held, delete all text.
	} else if (e.key == 'Backspace'){
		} else {
			var newText = theTextBox.innerHTML.slice(0, -1);
			theTextBox.innerHTML = newText;
	//If the Enter key was typed, remove all text from the text box
	} else if (e.key == 'Enter'){
		theTextBox.innerHTML += '<br><br>';
	//if Tab is pressed, don't tab out of the window. Add extra space to the text box instead
	if(keyPressed == 9){
		theTextBox.innerHTML += '&emsp;&emsp;';

//Function that detects when the user lets off a key and does the appropriate things
function removeKeypress(e){
	var keyDepressed = e.keyCode;	
	const keys = document.getElementById(keyDepressed);
	//If CapsLock or Shift was just let off, and if the other isn't still on, return keys to lowercase
	if(keyDepressed == 20 && !shiftKey.classList.contains('pressed') || keyDepressed == 16 && !capsLockKey.classList.contains('pressed')) {
	//If Shift was just let off, replace all non-alphabetical keys with their original values rather than their shifted values
	if(keyDepressed == 16 ) {
		for(i = 0; i<changeKeys.length; i++){
			changeKeys[i].innerHTML = originalShifterArray[i];

//Whenever the user presses a key down, run the proper function
window.addEventListener('keydown', highlightAndType );

//Whenever the user lets a key up, run the proper function
window.addEventListener('keyup', removeKeypress );

//Whenever the window is clicked, run the function to clear out the text box
window.addEventListener('click', clearText );