Pen Settings

HTML

CSS

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

JavaScript

Babel includes JSX processing.

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

Packages

Add Packages

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.

Behavior

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.

HTML

              
                <!-- 

TO ADD SOMETIME:
- 'remove item' button - maybe with swipe functionality for mobile
- standardize colors + tidy/tighten CSS
- smarter js???
- display currently selected conditions in list view
- refine and improve the list itself - for example I probably won't want to bring my uke if it's raining.
- SVG hikers/bikers/campers/etc hanging out in background as the conditions are set
- bg of custom item field is clipped to show page bg ..?
- add 'copy text' notification to plaintext box

-->


<!-- start page -->
<div id="page-start">

	<header>
		<p>A project for fun and utility</p>
		<p>Concept, development, design, and assets by Erin Knowles</p>
		<p>September 2019</p>

		<h1>Camping packing list generator</h1>
	</header>

	<input type="button" value="Get started" id="button-start" class="button">

</div>




<!-- start page 1: people -->
<div id="page1">

	<header>
		<p>Question 1/4</p>
		<h2>How many people are coming?</h2>
	</header>

	<div id="people-wrap">
		<input type="number" value="1" id="people">
		<div class="number-input">
			<input type="button" value="^" id="people-plus">
			<input type="button" value="^" id="people-minus">
		</div>
	</div>

	<input type="button" value="Next" id="button-page1" class="button button-light">

</div>


<!-- start page 2: nights -->
<div id="page2">

	<header>
		<p>Question 2/4</p>
		<h2>How many nights will you be gone?
			<span>(0 for a day trip)</span>
		</h2>
	</header>

	<div id="nights-wrap">
		<input type="number" value="0" id="nights">
		<div class="number-input">
			<input type="button" value="^" id="nights-plus">
			<input type="button" value="^" id="nights-minus">
		</div>
	</div>

	<input type="button" value="Next" id="button-page2" class="button button-light">

</div>



<!-- start page 3: biking -->
<div id="page3">

	<header>
		<p>Question 3/4</p>
		<h2>Will you be biking there?</h2>
	</header>

	<div id="biking-wrap">
		<input type="checkbox" value="biking" id="biking">
		<label for="biking">
			<div class="toggle-item" id="biking-yes">Yes</div>
			<div class="toggle-item toggle-on" id="biking-no">No</div>			
		</label>
	</div>

	<input type="button" value="Next" id="button-page3" class="button button-light">
</div>

</div>


<!-- start page 4: rain -->
<div id="page4">

	<header>
		<p>Question 4/4</p>
		<h2>Are you expecting rain?
			<span>(Trips longer than a few days should expect rain, regardless of the forecast!)</span>
		</h2>
	</header>

	<div id="rain-wrap">
		<input type="checkbox" value="rain" id="rain">
		<label for="rain">
			<div class="toggle-item" id="rain-yes">Yes</div>
			<div class="toggle-item toggle-on" id="rain-no">No</div>			
		</label>
	</div>

	<input type="button" value="Generate!" id="button-generate" class="button">

</div>




<!-- start to-do list: -->
<section id="page-list">
	<header>
		<p class="button-wrap">
			<input type="button" id="list-print-list" class="button button-light button-startover" value="(get plaintext)">
			<input type="button" id="button-startover" class="button button-light button-startover" value="(start over)">
		</p>
		<h1>My list:</h1>
	</header>



	<div id="custom-items" class="wrap">
		<p class="list-item-label">My custom items</p>
		<p class="value"></p>
	</div>

	<form><div id="custom-item-field-wrap">
		<p>Add custom item:</p>
		<input type="text" id="custom-item-value" autocomplete="off">
		<input type="submit" value="Add" id="custom-item-add">
		</div></form>


	<div id="print-list">
		<p onclick="$('#print-list').hide(200)">Close</p>
		<textarea></textarea>
		<div id="copy-confirm">Text copied!</div>
	</div>

</section>

              
            
!

CSS

              
                @import url('https://fonts.googleapis.com/css?family=Open+Sans:400,600,700&display=swap');

* { box-sizing: border-box;  margin: 0; padding: 0;}

html, body {
	min-height: 100%;
	font-size: 2vw;
}

body {
	font-family: 'open sans', sans-serif;
	background: url("https://i.postimg.cc/BZBDrcNg/bg2-wide-01.png");
	background-position: center;
	background-attachment: fixed;
	-webkit-background-size: cover;
	-moz-background-size: cover;
	-o-background-size: cover;
	background-size: cover;
	padding: 5rem;
}


header {
	margin-top: 5rem;
}

header p {
	font-size: 2rem;
	color: #666c7c;
	opacity: 0.7;
	text-align: center;
	padding: 1rem 0;
}

header h1 {
	text-align: center;
	font-size: 4rem;
	font-weight: bold;
	color: #444C62;
	margin: 3rem 0 6rem 0;
}

header h2 {
	text-align: center;
	font-size: 3rem;
	font-weight: bold;
	color: #444C62;
	margin: 0.5rem 0 3rem 0;
}

header h2 span {
	display: block;
	font-size: 2rem;
	opacity: 0.6;
	font-weight: 500;
	margin-top: 0.5rem;
}



.button {
	display: block;
	margin: 0 auto;
	background: #1111FF;
	border: 0;
	border-radius: 1rem;
	padding: 1.5rem 2.5rem;
	color: white;
	font-family: 'open sans', sans-serif;
	font-size: 2rem;
	font-weight: bold;
	box-shadow: 0 0.5rem 1.5rem rgba(0,0,80,0.4);
}

.button-light {
	background: transparent;
	box-shadow: inset 0 0.5rem 1.5rem rgba(255,255,255,0.2), 0 0.5rem 1.5rem rgba(0,0,80,0.3);
	opacity: 0.7;
	color: #000066;
}

.button-startover {
	font-size: 1.4rem;
	opacity: 0.5;
	padding: 1rem 1.5rem;
	margin: 0 2rem 2rem 2rem;
	border: 0;
}



#page-start {
	display: block;
}

#page1, #page2, #page3, #page4 {
	display: none;
}






#people-wrap, #nights-wrap {
	display: flex;
	width: 100%;
	margin: 5.5rem auto 5rem auto;
	justify-content: center;
}


input[type="number"] {
	-webkit-appearance: textfield;
	-moz-appearance: textfield;
	appearance: textfield;
	width: 40%;
	display: inline-block;
	height: auto;
	font-size: 7.5rem;
	padding: 1rem 1.5rem;
	color: #444C62;
	border: 0;
	background: none;
	background: -moz-linear-gradient(top, rgba(63,90,86,0) 30%, rgba(53,77,77,0.3) 100%);
	background: -webkit-gradient(left top, left bottom, color-stop(30%, rgba(63,90,86,0)), color-stop(100%, rgba(53,77,77,0.3)));
	background: -webkit-linear-gradient(top, rgba(63,90,86,0) 30%, rgba(53,77,77,0.3) 100%);
}

.number-imput {
	display: flex;
	flex-direction: column;
}

.number-input input[type="button"] {
	background: none;
	width: 100%;
	color: #444C62;
	font-size: 7.5rem;
	line-height: 4.75rem;
	border: 0;
}

.number-input input[type="button"]:last-of-type {
	transform: rotate(180deg);
}



label {
	width: 100%;
	display: flex;
	justify-content: center;
	margin: 0 auto;
}

#biking-wrap label, #rain-wrap label {
	-webkit-touch-callout: none; /* iOS Safari */
	-webkit-user-select: none; /* Safari */
	-khtml-user-select: none; /* Konqueror HTML */
	-moz-user-select: none; /* Firefox */
	-ms-user-select: none; /* Internet Explorer/Edge */
	user-select: none; /* Non-prefixed version, currently
	supported by Chrome and Opera */
	margin: 0.5rem 0 5rem 0;
}

label span {
	font-size: 0.6rem;
	color: #666;
}

input[type="checkbox"] {
	display: none;
}

.toggle-item {
	font-size: 7.5rem;
	color: #444C62;
	font-weight: bold;
	padding: 1rem 2rem;
	opacity: 0.5;
}

.toggle-on {
	opacity: 1;
}






#page-list {
	display: none;
	width: 100%;
	box-sizing: border-box;
	padding: 0;
	margin: 0;
	margin-top: -5rem;
	margin-bottom: 7rem;
}

#page-list h1 {
	margin-bottom: 4rem;
	margin-top: 0;
	font-size: 2.5rem;
}

#page-list header p {
	margin-bottom: 2rem;
	display: flex;
	justify-content: center;
}

.wrap {
	padding: 2rem;
	background: white;
	border-radius: 1rem;
	margin-bottom: 2rem;
	font-weight: 600;
	width: 100%;
	cursor: default;
	box-shadow: 0 0.5rem 1rem rgba(30,50,90,0.1);
}


.list-item-label {
	margin-bottom: 0.5rem;
	color: rgba(0,0,0,0.6);
	font-size: 2.3rem;
}

.list-item-label:first-letter {
	text-transform: uppercase;
}

.value {
	font-size: 1.8rem;
}


.subitem {
	font-size: 1.9rem;
	display: grid;
	grid-template-columns: 4rem 7fr;
	width: 100%;
	padding: 1.5rem 0;
	margin: 0;
	cursor: default;
	line-height: 2.5rem;
}

.subitem::before {
	content: '✖';
	color: rgba(0,0,0,0);
	padding: 0.75rem 0.75rem;
	max-height: 3rem;
	max-width: 3rem;
	margin-right: 1rem;
	line-height: 1.5rem;
	font-size: 1.5rem;
	box-sizing: border-box;
	background: #CCC;
	grid-column: 1;
}

.done {
	color: rgba(0,0,0,0.5);
}

.done::before {
	color: rgba(0,0,0,0.5);
	content: '✖';
	text-align: center;
}




#custom-items {
	display: none;
	-webkit-transition: all .3s ease;
	-moz-transition: all .3s ease;
	-ie-transition: all .3s ease;
	-o-transition: all .3s ease;
	transition: all .3s ease;
}


#custom-item-field-wrap {
	position: fixed;
	display: grid;
	grid-template-columns: 4fr 1fr;
	bottom: 0;
	left: 0;
	padding: 0.75rem 1.5rem 1.5rem 1.5rem;
	width: 100%;
	background: white;
	background: -moz-linear-gradient(top,  rgba(255,255,255,1) 0%, rgba(255,255,255,0.5) 100%); /* FF3.6-15 */
	background: -webkit-linear-gradient(top,  rgba(255,255,255,1) 0%,rgba(255,255,255,0.5) 100%); /* Chrome10-25,Safari5.1-6 */
	background: linear-gradient(to bottom,  rgba(255,255,255,1) 0%,rgba(255,255,255,0.5) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#80ffffff',GradientType=0 );
	z-index: 200;
}

#custom-item-field-wrap p {
	font-size: 1.5rem;
	color: #444C62;
	grid-column: span 2;
	margin-bottom: 0.5rem;
}

#custom-item-field-wrap input {
	border: 0;
	padding: 1.5rem;
	font-size: 2.5rem;
	line-height: 2.5rem;
}

#custom-item-field-wrap input[type="text"] {
	background: #DDD;
	border-radius: 1rem 0 0 1rem;
	font-weight: 500;
}

#custom-item-field-wrap input[type="submit"] {
	border-radius: 0 1rem 1rem 0;
	background: #CCC;
	font-weight: 600;
	font-size: 2rem;
}


#print-list {
	display: none;
	position: fixed;
	overflow: auto;
	top: 2rem;
	bottom: 2rem;
	left: 2rem;
	right: 2rem;
	background: white;
	border-radius: 1rem;
	z-index: 500;
	font-size: 3rem;
	padding: 2rem;
}

#print-list textarea {
	height: calc(100% - 12rem);
	width: 100%;
	font-size: 3rem;
	padding: 2rem;
	border: 0;
	border-radius: 1rem;
	box-shadow: inset 0 1rem 1.5rem rgba(0,0,0,0.1);
}

#print-list p {
	font-size: 2rem;
	padding: 2rem;
	margin: 2rem 0rem;
	line-height: 2rem;
	background: rgba(0,0,80,0.4);
	color: white;
	border-radius: 1rem;
	text-align: center;
	font-weight: 600;
	cursor: default;
}


#copy-confirm {
	display: none;
	opacity: 0;
	pointer-events: none;
	transition: all 0.3s;
	z-index: 2000;
	color: #64767b;
	padding: 6rem;
	font-size: 2rem;
	font-weight: 600;
	position: fixed;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 100%;
	text-align: center;
	background: #24363b;
	background: -moz-linear-gradient(bottom, rgba(63,90,86,0.2) 30%, rgba(53,77,77,0.5) 100%);
	background: -webkit-gradient(left bottom, left bottom, color-stop(30%, rgba(63,90,86,0.2)), color-stop(100%, rgba(53,77,77,0.5)));
	background: -webkit-linear-gradient(bottom, rgba(63,90,86,0.2) 30%, rgba(53,77,77,0.5) 100%);
}





@media only screen and (min-width: 600px) {
	/* hover styles for desktop only */

	.button:hover {
		background: rgba(60,90,255,1);
	}

	.button-light:hover {
		background: transparent;
		box-shadow: inset 0 0.5rem 2.5rem rgba(255,255,255,0.5), 0 0.5rem 1.5rem rgba(0,0,80,0.3);
		color: #000022;
	}
	
	.button-startover:hover {
		box-shadow: inset 0 0.5rem 2.5rem rgba(255,255,255,0.8), 0 0.5rem 1.5rem rgba(0,0,80,0.4);
	}

	#custom-item-field-wrap input[type="text"]:hover {
		background: #F0F0F0;
		box-shadow: inset 0 0.5rem 1rem rgba(0,0,0,0.1);
	}

	#custom-item-field-wrap input[type="submit"]:hover {
		background: #78A7AA;
	}

	.subitem:hover {
		background: #eee;
	}


	/* display styles */

	html, body {
		font-size: 12px;
		background-position: 50% 25%;
	}

	#print-list, #page-list {
		max-width: 550px;
		margin-left: auto;
		margin-right: auto;
	}
	
	#custom-item-field-wrap {
		max-width: 750px;
		left: 50%;
		transform: translateX(-50%);
		border-radius: 1rem 1rem 0 0;
	}
	
	
}

              
            
!

JS

              
                $(document).ready(function() {

// EVENT HANDLERS:
	
$("#button-start").click(function() {
	$('#page-start').hide(200);
	$('#page1').show(200);
});

	
// there's got to be a better way to do this
// >:(
// Anyway when people/nights plus/minus are clicked they call inputStep(this), which then sorts depending on whether the string is found, and steps up or steps down the input accordingly.
	
function inputStep(el) {
	var peopleNights = "";
	var plusMinus = "";
	
	if ( el.id.indexOf("people") != -1 ) {
		peopleNights = 'people';
	} else if ( el.id.indexOf("nights") != -1 ) {
		peopleNights = 'nights';
	}
	
	if ( el.id.indexOf("plus") != -1 ) {
		plusMinus = 'plus';
	} else if ( el.id.indexOf("minus") != -1 ) {
		plusMinus = 'minus';
	}
	
	if ( plusMinus === 'plus') {	document.getElementById(peopleNights).stepUp(); }
	else if ( plusMinus === 'minus' ) {
		if ( peopleNights === 'people' ) {
			if (document.getElementById("people").value > 1 ) {
				document.getElementById('people').stepDown();
			}
		} else if ( peopleNights === 'nights' ) {
			if (document.getElementById("nights").value > 0 ) {
				document.getElementById('nights').stepDown();
			}
		}
	}
}
	
	
$("#people-plus, #nights-plus, #people-minus, #nights-minus").click(function() {
	inputStep(this);
});


$("#button-page1").click(function() {
	$('#page1').hide(200);
	$('#page2').show(200);
});
	
$("#button-page2").click(function() {
	$('#page2').hide(200);
	$('#page3').show(200);
});

$("#button-page3").click(function() {
	$('#page3').hide(200);
	$('#page4').show(200);
});
	
$("#button-generate").click(function() {
	$('#page4').hide(200);
	$('#page-list').show(200);
	updateVars();
	refineElements();
});

$("#button-startover").click(function() {
	$('#custom-items .value').children().remove();
	$('#custom-items').hide(200);
	$('#page-list').hide(200);
	$('#page-start').show(200);
});
	
	
	
// CREATING LIST: 
	
var dataObject = {
	"litres water": 3,
	"calories food": 2000,
	"food": [
		"sausages",
		"cheese",
		"veggies",
		"trail mix",
		"granola bars"
	],
	"cooking stuff": [
		"stove",
		"stove fuel",
		"tea",
		"sponge",
		"soap",
		"cutlery",
		"knife",
		"tupperware",
		"spices",
		"lighter",
		"can opener"
	],
	"personal items": [
		"phone",
		"book",
		"journal",
		"ukulele"
	],
	"camping stuff": [
		"tent",
		"sleeping bag",
		"sleeping pad",
		"bug spray",
		"sunscreen",
		"util knife",
		"paracord",
		"sewing kit"
	],
	"rain stuff": [
		"tent fly",
		"tarp",
		"rainjacket",
		"rainpants",
		"dry bags"
	],
	"tire change stuff": [
		"spare tube",
		"patch kit",
		"pump",
		"tire levers",
		"adjustable wrench"
	],
	"other bike tools": [
		"adjustable wrench x2",
		"zipties",
		"multi grease",
		"allen keys",
		"pliers+screwdriver multitool"
	],
	"bike clothes": [
		"sports bra",
		"bike shorts",
		"bike leggings",
		"quick-dry fleece",
		"quick-dry tank"
	],
	"night clothes": [
		"wool sweater",
		"leggings big",
		"leggings small",
		"fuzzy pjs",
		"short-sleeve tee",
		"long-sleeve tee"
	],
	"overnight items": [
		"contact case + solution",
		"earplugs",
		"melatonin",
		"journal",
		"book",
		"tp",
		"headlamp",
		"phone charger",
		"spare batteries",
		"bear spray",
		"mp3 player",
		"toothpaste and brush",
		"hairbrush",
		"shampoo",
		"mini towel"
	]
}



// create an element for each item in the dataObject. This will be refined later based on the value of the variables defined below.
createElements(dataObject);
	
function createElements(data) {
	
	var list = document.getElementById("page-list");
	
	// loop over each key-value pair to create elements to display them
	$.each(data, function(index, value) {
		var ElLabel, ElValue, wrap;
		ElLabel = document.createElement("P");
		ElValue = document.createElement("P");
		wrap = document.createElement("P");
		$(ElLabel).addClass("list-item-label");
		$(ElValue).addClass("value");
		$(wrap).addClass("wrap");
		$(wrap).attr('id', index);
		
		// if the value is an array (ie a group of other items), loop over that array and create subitems for each.
		if ( $.isArray(value) ) {
			ElLabel.innerHTML = index;
			ElValue.innerHTML = "";
			
			value.forEach(function(index) {
				var ElItem = document.createElement("P");
				$(ElItem).addClass("subitem");
				ElItem.innerHTML = index;
				$(ElItem).attr('id', index);
				ElValue.appendChild(ElItem);
			});
			
		} else {
			ElLabel.innerHTML = index;
			ElValue.innerHTML = value;
		}
		
		wrap.appendChild(ElLabel);
		wrap.appendChild(ElValue);
		list.appendChild(wrap);
		
	});
}


	
// set up variables that the list is based upon to be edited as the user gives input:
var biking = false;
var rain = false;
var people = 1;
var nights = 0;
	
$(":input").change(function() {

	// don't let nights = less than 0
	if ( $("#nights").val() < 0 ) {
		$("#nights").val(0);
	}

	// don't let people = less than 1
	if ( $("#people").val() < 1 ) {
		$("#people").val(1);
	}

	// text toggles functionality:
	if ( $(":input[value='biking']").prop("checked") ) {
		$("#biking-yes").addClass("toggle-on");
		$("#biking-no").removeClass("toggle-on");
	} else {
		$("#biking-no").addClass("toggle-on");
		$("#biking-yes").removeClass("toggle-on");
	}

	if ( $(":input[value='rain']").prop("checked") ) {
		$("#rain-yes").addClass("toggle-on");
		$("#rain-no").removeClass("toggle-on");
	} else {
		$("#rain-no").addClass("toggle-on");
		$("#rain-yes").removeClass("toggle-on");
	}

});	
	

// set the variables we defined above to the input given by the user:
function updateVars() {
	biking = $(":input[value='biking']").prop("checked");
	rain = $(":input[value='rain']").prop("checked");
	people = parseInt( $("#people").val() );
	nights = parseInt( $("#nights").val() );
}



// Use the variables to cut down the list of all elements that was generated in createElements
// note that some id's refer to wrapped groups of other items! for example, 'tire change stuff' is a named group of items. 'tire levers' would be an item inside that group. In this way I can toggle on/off groups and add/remove certain elements of that group depending on the variables.
function refineElements() {

	if ( biking && nights === 0 ) {
		$("[id='tire change stuff']").show();
		$("[id='bike clothes']").show();
		$("[id='other bike tools']").hide();
		$("[id='ukulele']").hide();
	} else if ( biking && nights > 0 ) {
		$("[id='tire change stuff']").show();
		$("[id='other bike tools']").show();
		$("[id='bike clothes']").show();
		$("[id='ukulele']").show();
	} else {
		$("[id='bike clothes']").hide();
		$("[id='tire change stuff']").hide();
		$("[id='other bike tools']").hide();
		$("[id='ukulele']").show();
	}

	if ( rain && nights === 0 ) {
		$("[id='rain stuff']").show();
		$("[id='tent fly']").hide();
		$("[id='tarp']").hide();
		$("[id='dry bags']").hide();
	} else if ( rain && nights > 0 ) {
		$("[id='rain stuff']").show();
		$("[id='tent fly']").show();
		$("[id='tarp']").show();
		$("[id='dry bags']").show();
	} else {
		$("[id='rain stuff']").hide();
	}


	if ( nights > 0 ) {
		$("[id='night clothes']").show();
		$("[id='camping stuff']").show();
		$("[id='cooking stuff']").show();
		$("[id='overnight items']").show();
		$("[id='sausages']").show();
		$("[id='cheese']").show();
		$("[id='veggies']").show();
	} else {
		$("[id='night clothes']").hide();
		$("[id='camping stuff']").hide();
		$("[id='cooking stuff']").hide();
		$("[id='overnight items']").hide();
		$("[id='sausages']").hide();
		$("[id='cheese']").hide();
		$("[id='veggies']").hide();
	}

	var nightCalc, nightsMultiplier;
	if ( nights === 0 ) { nightCalc = 1; nightsMultiplier = .5; } else { nightCalc = nights; nightsMultiplier = 1; }
	$("[id='litres water'] .value").text(nightCalc * people * 3 * nightsMultiplier);
	$("[id='calories food'] .value").text(nightCalc * people * 2000 * nightsMultiplier);


	// make the Food list say "Food x [people]":
	$("#food .list-item-label").text("Food x" + people);


}



// get and show list of items in plaintext so it can be printed / copied etc when list-print-list is clicked.
// gets list of all visible subitems, pushes their value to an array, opens the modal with the textarea, prints the array to the textarea on new lines.
$("#list-print-list").click(function() {
	var printableList = [];
	var totalShown = $(".subitem:visible");

	$.each( totalShown, function(index, value) {
		printableList.push( $(value).text() );
	});

	$("#print-list").show(200);
	$("#print-list textarea").text(printableList.join("\n"));
});



$("#print-list textarea").focus( function() {
	this.select();
	document.execCommand("copy");
	$("#copy-confirm").show();
	$("#copy-confirm").css("opacity", "1");
	$("#copy-confirm").delay(1000).queue(function(){
		$(this).css("opacity", "0").dequeue();
		$(this).hide(300).dequeue;
	});
});




// LIST FUNCTIONALITY:
	
	
// 'check off' a subitem when it's clicked.
// just adds or removes the class 'done'. Done uses ::before to show a checkmark over subitem::before's checkbox area.
// Then it calls checkDone to see if that group has been completed.
$('body').on('click', '.subitem', function() {
	$(this).toggleClass("done");
	checkDone( $(this) );
});


// When a subitem is clicked, check to see if all the subitems in that group are checked off, and fade their group if so.
// get number of subitems with class .done - ie number of checked off subitems - in current group
// get number of total VISIBLE items in that group
// if they're the same, then all items in that group are checked off, and the element is faded. Otherwise, it's unfaded.
function checkDone(thisElement) {

	var numDone = thisElement.parent().find( $(".done") ).length;
	var numShown = thisElement.parent().find( ":visible" ).length;

	if ( numDone === numShown ) {
		thisElement.closest( $(".wrap") ).fadeTo("fast", 0.5);
	} else {
		thisElement.closest( $(".wrap") ).fadeTo("fast", 1);
	}

}



// CUSTOM ITEMS:

$("#custom-item-add").click( function() {
	customItemAdd();
	$("body, html").scrollTop( $("#custom-items").offset().top );
}); 

// Add custom item to the list of generated items.
function customItemAdd() {

	// prevent default or the submit button will take us somewhere! But it's needed for submitting form with enter.
	event.preventDefault();

	// Show the custom-items wrap div if it isn't shown already.
	if ( !$("#custom-items").show() && $("#custom-item-value").val() ) {
		$("#custom-items").show(200);
	}

	// make the div glow a bit so you can tell something has happened
	$("#custom-items").css("boxShadow", "0 0 5rem rgba(255,255,0,0.7)");
	$("#custom-items").delay(300).queue(function(){
		$(this).css("boxShadow", "0 0 0rem rgba(255,255,0,0.7)").dequeue();
	});

	// create a new subitem in that div, give it the value from the custom-item-value box. Clear that box. Check to see if custom-items is all checked off (because it isn't, because we JUST added something, so this will reset it)
	if ( $("#custom-item-value").val() ) {
		customEl = document.createElement("p");
		$(customEl).addClass("subitem");
		$(customEl).text( $("#custom-item-value").val() );
		document.querySelector("#custom-items .value").appendChild( customEl );
		$("#custom-item-value").val('');
		
		checkDone( $(customEl) );
	}

}




});
              
            
!
999px

Console