<header>
	<h1>Calculate Tip!</h1>
</header>

<main id='vue-context'>

	<form class='price' action='javascript:void()'>
		<h2 class='display-total'>bill: ${{subTotal}}</h2> <br />

		<div class='min'>$5</div>
		<input type='range' v-model='subTotal' min='5' max='300' />
		<div class='max'>$300</div>
	</form>

	<figure class='big-face'>
		<div>{{face}}</div>
	</figure>

	<form class='feel' action='javascript:void()'>
		<span>๐Ÿ˜ง</span>
		<input
			type='range'
			min='5' max='25' step='2'
			v-model='tipPercentage'
		/>
		<span>๐Ÿ˜ƒ</span>
	</form>

	<output class='outcome' v-if='subTotal'>
		<div class='tip'>TIP = ${{tip}}</div>
	</output>
	
	<output class='details' v-if='subTotal'>
		<div class='sub-total'>${{subTotal}}</div>
		<div class='tip'>${{tip}}</div>
		<div class='to'>TOTAL: ${{totalWithTip}}</div>
		<div>{{tipPercentage}}%</div>
	</output>

</main>


















<div class='thing'>
	<!-- just saving these here -->
	๐Ÿ˜กโ˜น๐Ÿ™๐Ÿ˜•๐Ÿ˜ถ๐Ÿ˜๐Ÿค”๐Ÿ™‚๐Ÿ˜„๐Ÿค—

	๐Ÿ˜๐Ÿ˜‹๐Ÿค—๐Ÿคญ๐Ÿค”๐Ÿคจ๐Ÿ˜
๐Ÿ˜‘๐Ÿ˜ถ๐Ÿ™„๐Ÿ˜ฌ๐Ÿ˜”๐Ÿคข๐Ÿ˜•๐Ÿ˜Ÿ
๐Ÿ™โ˜น๐Ÿ˜ฆ๐Ÿ˜ง๐Ÿ˜–๐Ÿ˜ ๐Ÿ˜ก๐Ÿ˜ž
๐Ÿคฎ๐Ÿ˜ƒ๐Ÿ˜€๐Ÿ˜„๐Ÿ™‚๐Ÿ˜Š
๐Ÿ˜ก๐Ÿ™๐Ÿ˜•๐Ÿ˜ฌ๐Ÿคญ๐Ÿ˜๐Ÿค”๐Ÿ™‚๐Ÿ˜„๐Ÿค—
</div>

html
	font-family: Sans-serif

body
	overflow: hidden
	min-height: 100vh
	background-color: lightblue
	background-image: linear-gradient(30deg, hsl(180, 100, 50%), hsl(3200, 100, 50%) )
	padding: 10px

header
	text-align: center
	font-size: 40px
	padding: 20px
	color: white

.field
	display: block
	margin-top: 1rem
	input
		padding: .5rem
		font-size: 18px
	&.tip
		opacity: .2

form
	margin-top: 1rem
	*
		display: inline-block
		vertical-align: middle
	span
		font-size: 40px

.price
	text-align: center
	width: 100%
	input
		width: 65vw
		max-width: 400px
	.display-total
		font-size: 30px
		
.feel
	text-align: center
	width: 100%
	input
		width: 45vw
		
output
	display: block
	margin-top: 1rem
	span
		font-weight: bold		

.outcome
	border: 1px solid gray
	padding: .5rem
	font-size: 24px
	text-align: right
	max-width: 200px
	margin: 0 auto
	margin-top: 1rem
	text-align: center
	.tip
		color: white

.details
	font-family: monospace
	font-size: 15px
	opacity: .6

.thing
	font-size: 50px
	display: none
	
.big-face
	font-size: clamp(150px, 20vw, 300px)
	display: flex
	flex-direction: row
	justify-content: center
	align-items: center
	margin-top: 2rem


View Compiled

const options = ['๐Ÿ˜ก','๐Ÿ˜ฆ','๐Ÿ™','๐Ÿ˜','๐Ÿ˜ฌ','๐Ÿ™‚','๐Ÿ˜Š','๐Ÿ˜€','๐Ÿ˜ƒ','๐Ÿค—', '๐Ÿ˜'];
																// ๐Ÿ˜ƒ๐Ÿ˜€๐Ÿ˜„๐Ÿ™‚๐Ÿ˜Š// just some other options... 
new Vue({
	el: '#vue-context',
	data: function() {
		return {
			excerciseNumber: 0,
			subTotal: '40',
			tipPercentage: '15',
			optionsData: options,
		};
	},
	computed: {
		tip() {
			let tipInDecimal = this.tipPercentage / 100;
			let rawTip = this.subTotal * tipInDecimal;
			return rawTip.toFixed(2);
		},
		totalWithTip() {
			let tip = Number(this.tip);
			let subTotal = Number(this.subTotal);
			return (subTotal + tip).toFixed(2);
		},
		face() {
			let successNumber = (this.tipPercentage - 5)/2;
			return this.optionsData[successNumber];
		},
	},
});
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js