<!-- People are visual learners and after teaching the CSS Box Model to a class @GA, I thought I'd put together an interactive demo to show how all the various properties work together under different box-sizing conditions and how CSS shorthand properties margin, padding and border-width work... -->

<header>
			<h1>Interactive box-model&nbsp;demo</h1>
			<p>Adjust the sliders to see how the box changes and generates the necessary code.</p>

		</header>

		<div class="box"></div>

		<div class="box-code">
			<h2>Box CSS:</h2>
<pre><code id="boxCode"></code>


<small>/* Lovingly created by Guy Routledge <a href="https://www.guyroutledge.co.uk">https://www.guyroutledge.co.uk</a> */</small>
</pre>

			<aside class="box-dimensions">
				<h3>Generated dimensions</h3>
				<p>
					width: <span id="generatedWidth">200</span>px,<br>
					height: <span id="generatedHeight">200</span>px
				</p>
			</aside>

		</div>

		<aside class="box-controls">
			<form>
				<fieldset class="box-link-properties">
					<legend>Box-sizing</legend>
					<label for="contentBox">content-box</label>
					<input type="radio" name="boxSizing[]" id="contentBox" checked>
					<label for="borderBox">border-box</label>
					<input type="radio" name="boxSizing[]" id="borderBox">
				</fieldset>
				<fieldset>
					<legend>Dimensions</legend>
					<label for="boxWidth">Width:</label>
					<input type="range" min="0" max="500" name="boxWidth" id="boxWidth" value="200" step="5">
					<label for="boxWidth">Height:</label>
					<input type="range" min="0" max="500" name="boxHeight" id="boxHeight" value="200" step="5">
				</fieldset>
				<fieldset>
					<legend>Padding</legend>

					<fieldset class="box-link-properties">
						<label for="linkPaddingNone">Link None</label>
						<input type="radio" name="linkPadding[]" id="linkPaddingNone" checked>
						<label for="linkPaddingTopBottom">Link T/B</label>
						<input type="radio" name="linkPadding[]" id="linkPaddingTopBottom">
						<label for="linkPaddingRightLeft">Link R/L</label>
						<input type="radio" name="linkPadding[]" id="linkPaddingRightLeft">
						<label for="linkPaddingAll">All</label>
						<input type="radio" name="linkPadding[]" id="linkPaddingAll">
					</fieldset>

					<label for="boxPaddingTop">Padding Top:</label>
					<input type="range" min="0" max="100" name="boxPaddingTop" id="boxPaddingTop" value="20" step="5">
					<label for="boxPaddingRight">Padding Right:</label>
					<input type="range" min="0" max="100" name="boxPaddingRight" id="boxPaddingRight" value="20" step="5">
					<label for="boxPaddingBottom">Padding Bottom:</label>
					<input type="range" min="0" max="100" name="boxPaddingBottom" id="boxPaddingBottom" value="20" step="5">
					<label for="boxPaddingLeft">Padding Left:</label>
					<input type="range" min="0" max="100" name="boxPaddingLeft" id="boxPaddingLeft" value="20" step="5">
				</fieldset>
				<fieldset>
					<legend>Margin</legend>

					<fieldset class="box-link-properties">
						<label for="linkMarginNone">Link None</label>
						<input type="radio" name="linkMargin[]" id="linkMarginNone" checked>
						<label for="linkMarginTopBottom">Link T/B</label>
						<input type="radio" name="linkMargin[]" id="linkMarginTopBottom">
						<label for="linkMarginRightLeft">Link R/L</label>
						<input type="radio" name="linkMargin[]" id="linkMarginRightLeft">
						<label for="linkMarginAll">All</label>
						<input type="radio" name="linkMargin[]" id="linkMarginAll">
					</fieldset>

					<label for="boxMarginTop">Margin Top:</label>
					<input type="range" min="0" max="100" name="boxMarginTop" id="boxMarginTop" value="20" step="5">
					<label for="boxMarginRight">Margin Right:</label>
					<input type="range" min="0" max="100" name="boxMarginRight" id="boxMarginRight" value="20" step="5">
					<label for="boxMarginBottom">Margin Bottom:</label>
					<input type="range" min="0" max="100" name="boxMarginBottom" id="boxMarginBottom" value="20" step="5">
					<label for="boxMarginLeft">Margin Left:</label>
					<input type="range" min="0" max="100" name="boxMarginLeft" id="boxMarginLeft" value="20" step="5">
				</fieldset>
				<fieldset>
					<legend>Border</legend>

					<fieldset class="box-link-properties">
						<label for="linkBorderNone">Link None</label>
						<input type="radio" name="linkBorder[]" id="linkBorderNone" checked>
						<label for="linkBorderTopBottom">Link T/B</label>
						<input type="radio" name="linkBorder[]" id="linkBorderTopBottom">
						<label for="linkBorderRightLeft">Link R/L</label>
						<input type="radio" name="linkBorder[]" id="linkBorderRightLeft">
						<label for="linkBorderAll">All</label>
						<input type="radio" name="linkBorder[]" id="linkBorderAll">
					</fieldset>

					<label for="boxBorderTop">Border Top:</label>
					<input type="range" min="0" max="50" name="boxBorderTop" id="boxBorderTop" value="10" step="5">
					<label for="boxBorderRight">Border Right:</label>
					<input type="range" min="0" max="50" name="boxBorderRight" id="boxBorderRight" value="10" step="5">
					<label for="boxBorderBottom">Border Bottom:</label>
					<input type="range" min="0" max="50" name="boxBorderBottom" id="boxBorderBottom" value="10" step="5">
					<label for="boxBorderLeft">Border Left:</label>
					<input type="range" min="0" max="50" name="boxBorderLeft" id="boxBorderLeft" value="10" step="5">
				</fieldset>
			</form>
		</aside>
* {
	margin:0;
	padding:0;
}
body {
	padding:1em 24em 3em 3em;
	color:#333;
	font-family:'Open Sans', sans-serif;
}
h1 {
	margin:0 0 0.25em;
}
p {
	margin:0 0 1em;
}
a {
	color:#333;
	-webkit-transition:0.3s;
	        transition:0.3s;
}
a:hover {
	color:#999;
}
.box {
	position:relative;
	margin-top:30px;
}
.box-property {
	position:absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
}
.box,
.box-property {
	-webkit-transition:0.3s;
	        transition:0.3s;
}

/* Property values in model via pseudo elements */
.box-property-vertical,
.box-property-horizontal {
	position:absolute;
	top:0;
	left:0;
	z-index:2000;
}
.box-property-horizontal {
	width:100%;
	border-top:1px solid #eee;
	border-top:1px solid rgba(0, 0, 0, 0.1);
}
.box-property-vertical {
	height:100%;
	border-left:1px solid #eee;
	border-left:1px solid rgba(0, 0, 0, 0.1);
}
.box-property-vertical:before,
.box-property-vertical:after {
	position:absolute;
	left:-0.7em;
	width:100%;

	color:#999;
	color:rgba(0,0,0,0.6);
	font-size:0.75em;
}
.box-property-vertical:before {
	content:attr(data-top);
	top:-0.75em;
}
.box-property-vertical:after {
	content:attr(data-bottom);
	bottom:-0.75em;
}
.box-property-horizontal:before,
.box-property-horizontal:after {
	position:absolute;
	margin-top:-0.75em;
	width:2em;
	height:100%;

	color:#999;
	color:rgba(0,0,0,0.6);
	font-size:0.75em;
	text-align:center;
}
.box-property-horizontal:before {
	content:attr(data-left);
	left:-1em;
}
.box-property-horizontal:after {
	content:attr(data-right);
	right:-1em;
}
.box-padding .box-property-vertical {
	left:40%;
}
.box-border .box-property-vertical {
	left:50%;
}
.box-margin .box-property-vertical {
	left:60%;
}
.box-padding .box-property-horizontal {
	top:40%;
}
.box-border .box-property-horizontal {
	top:50%;
}
.box-margin .box-property-horizontal {
	top:60%;
}
.box:hover .box-property {
	background:#fff;
}
.box:hover .box-property-vertical,
.box:hover .box-property-horizontal {
	opacity:0;
}
.box-inner {
	background:#9fc4e7;
	border:1px solid #666;

	font-family:'Ubuntu Mono', 'Courier New', monospace;
	text-align:center;
	line-height:1em;
}
.box-inner:hover {
	background:#9fc4e7!important;
}
.box-inner:before {
	content:attr(data-width) ' x ' attr(data-height);

	position:absolute;
	left:0;
	top:50%;
	margin-top:-0.5em;

	width:100%;
}
.box:hover .box-inner:before {
	content:attr(data-hover-property);
}
.box-padding {
	-moz-box-sizing:border-box;
	box-sizing:border-box;

	background-color:#c2ddb6;
	border:1px dashed #666;
}
.box-padding:hover {
	background-color:#c2ddb6!important;
}
.box-padding:hover .box-property-vertical,
.box-padding:hover .box-property-horizontal {
	opacity:1;
}
.box-margin {
	background:#f8cb9c;
	border:1px dashed #666;
}
.box-margin:hover {
	background:#f8cb9c!important;
}
.box-margin:hover .box-property-vertical,
.box-margin:hover .box-property-horizontal {
	opacity:1;
}
.box-border {
	background:#feedbb;
	border:1px solid #666;
}
.box-border:hover {
	background:#feedbb!important;
}
.box-border:hover .box-property-vertical,
.box-border:hover .box-property-horizontal {
	opacity:1;
}


/* Generated Dimensions */

.box-dimensions {
	position:absolute;
	bottom:100%;
	right:23em;

	padding:1em;
	background:#fff;
	background:rgba(255,255,255,0.8);
	border:1px solid rgba(240, 240, 240, 0.8);
	border-right:0;
	border-bottom:0;

	text-align:right;
}
.box-dimensions p {
	margin:0;
	font-size:0.8em;
}
.box-dimensions h3 {
	margin-bottom:0.25em;
	font-size:0.9em;
}

/* Controls */

.box-controls {
	-moz-box-sizing:border-box;
	box-sizing:border-box;
	position:absolute;
	top:0;
	right:0;

	width:23em;
	height:100%;
	padding:1.5em;
	background:#eee;
	background:rgba(240, 240, 240, 0.8);

	z-index:100;
}
fieldset {
	margin:0 0 1em;
	padding:1em;
}
label, input {
	display:inline-block;
	margin:0 0 0.25em;
	vertical-align:middle;
}
label {
	width:40%;
	font-size:0.8em;
}
input[type="range"] {
	width:55%;
}
.box-link-properties {
	margin-bottom:0.5em;
	padding:0;
	border:0;
}
.box-link-properties label {
	width:auto;
}
.box-link-properties input {
	margin-right:0.5em;
}

/* Code */
.box-code {
	-moz-box-sizing:border-box;
	     box-sizing:border-box;
	position:fixed;
	bottom:0;
	left:0;

	width:100%;
	padding:1em 3em 1.5em;

	background:#eee;
	background:rgba(240, 240, 240, 0.8);

	z-index:100;
}
.box-code h2 {
	margin-bottom:1em;
}

/* Twitter Buttons */
#twitter-widget-0,
#twitter-widget-1 {
	display:inline-block;
	vertical-align:middle;
}
#twitter-widget-1 {
	margin-left:0.5em;
}
#twitter-widget-0 {
	width:90px!important;
}
$(function(){
	var boxModel = {

		$box: $('.box'),
		$boxInner: $('<div class="box-inner box-property" data-property="content"></div>'),
		$boxMargin: $('<div class="box-margin box-property" data-property="margin"></div>'),
		$boxPadding: $('<div class="box-padding box-property" data-property="padding"></div>'),
		$boxBorder: $('<div class="box-border box-property" data-property="border"></div>'),

		boxSizing: 'content-box',

		prependElements: function(){
			boxModel.$box.prepend(
				boxModel.$boxMargin,
				boxModel.$boxBorder,
				boxModel.$boxPadding,
				boxModel.$boxInner
			);
			$('.box-property').append('<span class="box-property-vertical"></span><span class="box-property-horizontal"></span>');
			$('.box-controls input').change(boxModel.getBoxProperties);
			$('body').height($('.box-controls').height());
			boxModel.getBoxProperties();
			boxModel.showPropertyOnHover();
		},
		getBoxProperties: function(){
			var propertiesToLink = ['Margin', 'Padding', 'Border'];

			boxModel.boxSizing = $('#borderBox').is(':checked') ? 'border-box' : 'content-box';

			boxModel.boxWidth         = parseInt($('#boxWidth').val(), 10);
			boxModel.boxHeight        = parseInt($('#boxHeight').val(), 10);
			boxModel.boxMarginTop     = parseInt($('#boxMarginTop').val(), 10);
			boxModel.boxMarginRight   = parseInt($('#boxMarginRight').val(), 10);
			boxModel.boxMarginBottom  = parseInt($('#boxMarginBottom').val(), 10);
			boxModel.boxMarginLeft    = parseInt($('#boxMarginLeft').val(), 10);
			boxModel.boxPaddingTop    = parseInt($('#boxPaddingTop').val(), 10);
			boxModel.boxPaddingRight  = parseInt($('#boxPaddingRight').val(), 10);
			boxModel.boxPaddingBottom = parseInt($('#boxPaddingBottom').val(), 10);
			boxModel.boxPaddingLeft   = parseInt($('#boxPaddingLeft').val(), 10);
			boxModel.boxBorderTop     = parseInt($('#boxBorderTop').val(), 10);
			boxModel.boxBorderRight   = parseInt($('#boxBorderRight').val(), 10);
			boxModel.boxBorderBottom  = parseInt($('#boxBorderBottom').val(), 10);
			boxModel.boxBorderLeft    = parseInt($('#boxBorderLeft').val(), 10);

			boxModel.linkProperties(propertiesToLink);
			boxModel.positionBoxProperties();
		},
		linkProperties: function(properties) {
			var i, linkTB, linkRL, linkAll;

			for ( i = 0; i < properties.length; i++ ) {

				linkTB = $('#link' + properties[i] + 'TopBottom').is(':checked');
				linkRL = $('#link' + properties[i] + 'RightLeft').is(':checked');
				linkAll = $('#link' + properties[i] + 'All').is(':checked');

				if ( linkTB ) {
					boxModel['linked' + properties[i] + 'TB'] = true;
					boxModel['box' + properties[i] + 'Top'] = boxModel['box' + properties[i] + 'Top'];
					boxModel['box' + properties[i] + 'Bottom'] = boxModel['box' + properties[i] + 'Top'];
					$('#box' + properties[i] + 'Bottom').val(boxModel['box' + properties[i] + 'Top']);
				}
				if ( linkRL ) {
					boxModel['linked' + properties[i] + 'RL'] = true;
					boxModel['box' + properties[i] + 'Left'] = boxModel['box' + properties[i] + 'Right'];
					boxModel['box' + properties[i] + 'Left'] = boxModel['box' + properties[i] + 'Left'];
					$('#box' + properties[i] + 'Left').val(boxModel['box' + properties[i] + 'Left']);
				}
				if ( linkAll ) {
					boxModel['linked' + properties[i] + 'All'] = true;
					boxModel['box' + properties[i] + 'Top'] = boxModel['box' + properties[i] + 'Top'];
					boxModel['box' + properties[i] + 'Right'] = boxModel['box' + properties[i] + 'Top'];
					boxModel['box' + properties[i] + 'Bottom'] = boxModel['box' + properties[i] + 'Top'];
					boxModel['box' + properties[i] + 'Left'] = boxModel['box' + properties[i] + 'Top'];
					$('#box' + properties[i] + 'Right').val(boxModel['box' + properties[i] + 'Top']);
					$('#box' + properties[i] + 'Bottom').val(boxModel['box' + properties[i] + 'Top']);
					$('#box' + properties[i] + 'Left').val(boxModel['box' + properties[i] + 'Top']);
				}

			}
		},
		addDimensionsToModel: function(){
			var properties = ['Padding', 'Margin', 'Border'];
			var i;

			for ( i = 0; i < properties.length; i++ ) {

				boxModel['$box' + properties[i]].find('.box-property-vertical').attr({
					'data-top': boxModel['box' + properties[i] + 'Top'],
					'data-bottom' : boxModel['box' + properties[i] + 'Bottom']
				}).next('.box-property-horizontal').attr({
					'data-left': boxModel['box' + properties[i] + 'Left'],
					'data-right': boxModel['box' + properties[i] + 'Right']
				});

			}

		},
		generateShorthand: function(property) {
			var topAndBottomMatch = boxModel['box' + property + 'Top'] === boxModel['box' + property + 'Bottom'];
			var topAndBottomNoMatch = boxModel['box' + property + 'Top'] !== boxModel['box' + property + 'Bottom'];
			var leftAndRightMatch = boxModel['box' + property + 'Left'] === boxModel['box' + property + 'Right'];
			var allMatch = (boxModel['box' + property + 'Top'] + boxModel['box' + property + 'Bottom'] === boxModel['box' + property + 'Left'] + boxModel['box' + property + 'Right']) && (leftAndRightMatch && topAndBottomMatch);

			if ( allMatch ) {
				return boxModel['box' + property + 'Top'] + 'px;\n';
			} else if ( topAndBottomMatch && leftAndRightMatch ) {
				return boxModel['box' + property + 'Top'] + 'px ' + boxModel['box' + property + 'Left'] + 'px;\n';
			} else if ( topAndBottomNoMatch && leftAndRightMatch ) {
				return boxModel['box' + property + 'Top'] + 'px ' + boxModel['box' + property + 'Left'] + 'px ' + boxModel['box' + property + 'Bottom'] + 'px;\n';
			} else {
				return boxModel['box' + property + 'Top'] + 'px ' + boxModel['box' + property + 'Right'] + 'px ' + boxModel['box' + property + 'Bottom'] + 'px ' + boxModel['box' + property + 'Left'] + 'px;\n';
			}
		},
		generateCode: function(){
			var boxCode;

			boxCode  = '.box {\n';

			if ( boxModel.boxSizing === 'border-box' ) {
				boxCode += '    -moz-box-sizing: border-box;\n';
				boxCode += '         box-sizing: border-box;\n';
				boxCode += '\n';
			}

			boxCode += '    width: <span contenteditable type="number" pattern="[0-9]{1,3}">' + boxModel.boxWidth + '</span>px;\n';
			boxCode += '    height: ' + boxModel.boxHeight + 'px;\n';

			boxCode += '    margin: ' + boxModel.generateShorthand('Margin');
			boxCode += '    padding: ' + boxModel.generateShorthand('Padding');
			boxCode += '    border-width: ' + boxModel.generateShorthand('Border');

			boxCode += '\n';
			boxCode += '    /* border-style and border-color must\n';
			boxCode += '       be set for border-width to apply */\n';
			boxCode += '}';

			$('#boxCode').html(boxCode);
		},
		showPropertyOnHover: function(){
			$('.box-property').hover(function(){
				$('.box-inner').attr('data-hover-property', $(this).attr('data-property'));
			});
		},
		positionBoxProperties: function(){
			// Margin
			var boxMarginTop = boxModel.boxMarginTop;
			var boxMarginLeft = boxModel.boxMarginLeft;
			var boxMarginLeftRight = boxModel.boxMarginLeft + boxModel.boxMarginRight;
			var boxMarginTopBottom = boxModel.boxMarginTop + boxModel.boxMarginBottom;

			// Padding
			var boxPaddingTop = boxModel.boxPaddingTop;
			var boxPaddingLeft = boxModel.boxPaddingLeft;
			var boxPaddingLeftRight = boxModel.boxPaddingLeft + boxModel.boxPaddingRight;
			var boxPaddingTopBottom = boxModel.boxPaddingTop + boxModel.boxPaddingBottom;

			// Border
			var boxBorderTop = boxModel.boxBorderTop;
			var boxBorderLeft = boxModel.boxBorderLeft;
			var boxBorderLeftRight = boxModel.boxBorderLeft + boxModel.boxBorderRight;
			var boxBorderTopBottom = boxModel.boxBorderTop + boxModel.boxBorderBottom;

			// Box
			// reposition to avoid overlap of page elements
			var boxTop = boxMarginTop + boxBorderTop + boxPaddingTop + 6;
			var boxLeft = boxMarginLeft + boxBorderLeft + boxPaddingLeft;

			var boxWidth = boxModel.boxSizing === 'border-box' ? boxModel.boxWidth - boxPaddingLeftRight - boxBorderLeftRight : boxModel.boxWidth;
			var boxHeight = boxModel.boxSizing === 'border-box' ? boxModel.boxHeight - boxPaddingTopBottom - boxBorderTopBottom : boxModel.boxHeight;

			// Margin Box
			var boxMarginWidth = boxWidth + boxMarginLeftRight + boxPaddingLeftRight + boxBorderLeftRight;
			var boxMarginHeight = boxHeight + boxMarginTopBottom + boxPaddingTopBottom + boxBorderTopBottom;

			// Border Box
			var boxBorderWidth = boxWidth + boxPaddingLeftRight + boxBorderLeftRight;
			var boxBorderHeight = boxHeight + boxPaddingTopBottom + boxBorderTopBottom;

			// Padding Box
			var boxPaddingWidth = boxWidth + boxPaddingLeftRight + 2;
			var boxPaddingHeight = boxHeight + boxPaddingTopBottom + 2;

			if ( boxMarginTop >= 0 ) {
				boxMarginTop = (boxMarginTop * -1) - boxPaddingTop - boxBorderTop;
			}
			if ( boxMarginLeft >= 0 ) {
				boxMarginLeft = boxMarginLeft * -1 - boxPaddingLeft - boxBorderLeft;
			}
			if ( boxBorderTop >= 0 ) {
				boxBorderTop = (boxBorderTop * -1) - boxPaddingTop;
			}
			if ( boxBorderLeft >= 0 ) {
				boxBorderLeft = (boxBorderLeft * -1) - boxPaddingLeft;
			}
			if ( boxPaddingTop >= 0 ) {
				boxPaddingTop = boxPaddingTop * -1;
			}
			if ( boxPaddingLeft >= 0 ) {
				boxPaddingLeft = boxPaddingLeft * -1;
			}

			boxModel.$box.css({
				top: boxTop,
				left: boxLeft,
				width: boxWidth + 'px',
				height: boxHeight + 'px'
			});
			boxModel.$boxInner.css({
				width: boxWidth + 'px',
				height: boxHeight + 'px'
			}).attr({
				'data-width': $('#boxWidth').val(),
				'data-height': $('#boxHeight').val()
			});

			boxModel.$boxPadding.css({
				width: boxPaddingWidth + 'px',
				height: boxPaddingHeight + 'px',
				top: boxPaddingTop + 'px',
				left: boxPaddingLeft + 'px'
			});
			boxModel.$boxBorder.css({
				width: boxBorderWidth + 'px',
				height: boxBorderHeight + 'px',
				top: boxBorderTop + 'px',
				left: boxBorderLeft + 'px'
			});

			boxModel.$boxMargin.css({
				width: boxMarginWidth + 'px',
				height: boxMarginHeight + 'px',
				top: boxMarginTop + 'px',
				left: boxMarginLeft + 'px'
			});

			$('#generatedWidth').text(boxBorderWidth);
			$('#generatedHeight').text(boxBorderHeight);

			boxModel.generateCode();
			boxModel.addDimensionsToModel();
		}
	};

	boxModel.prependElements();

});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js