Skip to content

Instantly share code, notes, and snippets.

@matt-daniel-brown
Created December 12, 2017 23:58
Show Gist options
  • Save matt-daniel-brown/32db55e75e97de5afa34200ef3a6cab0 to your computer and use it in GitHub Desktop.
Save matt-daniel-brown/32db55e75e97de5afa34200ef3a6cab0 to your computer and use it in GitHub Desktop.
Fluid Type Sass - Mixin
<main>
<section>
<h1>Fluid Typography Sass Mixin</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Reprehenderit iusto adipisci, cupiditate animi, itaque qui
aspernatur vel corrupti labore minima, excepturi ab, fuga rem
dolores. Ratione sunt autem iusto aliquid.</p>
</section>
<section>
<h2>Heading 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Reprehenderit iusto adipisci, cupiditate animi, itaque qui
aspernatur vel corrupti labore minima, excepturi ab, fuga
rem dolores. Ratione sunt autem iusto aliquid.</p>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Reprehenderit iusto adipisci, cupiditate animi,
itaque qui aspernatur vel corrupti labore minima, excepturi
ab, fuga rem dolores. Ratione sunt autem iusto aliquid.</p>
<ul class="button-group">
<li><button>Default</button></li>
<li><button class="secondary">Secondary</button></li>
</ul>
</section>
</main>
<footer>
<p>Copyright &copy; 2017.</p>
</footer>
/* window.onload = function() {
// Declare touch variables for older versions of I.E.
var pointerDownName = "pointerdown";
var pointerUpName = "pointerup";
var pointerMoveName = "pointermove";
if (window.navigator.msPointerEnabled) {
pointerDownName = "MSPointerDown";
pointerUpName = "MSPointerUp";
pointerMoveName = "MSPointerMove";
}
// Simple way to check if some form of pointerevents is enabled or not
window.PointerEventsSupport = false;
if (window.PointerEvent || window.navigator.msPointerEnabled) {
window.PointerEventsSupport = true;
}
// Check if pointer events are supported.
if (window.PointerEvent) {
// Add Pointer Event Listener
swipeFrontElement.addEventListener(
"pointerdown",
this.handleGestureStart,
true
);
swipeFrontElement.addEventListener(
"pointermove",
this.handleGestureMove,
true
);
swipeFrontElement.addEventListener("pointerup", this.handleGestureEnd, true);
swipeFrontElement.addEventListener(
"pointercancel",
this.handleGestureEnd,
true
);
} else {
// Add Touch Listener
swipeFrontElement.addEventListener(
"touchstart",
this.handleGestureStart,
true
);
swipeFrontElement.addEventListener("touchmove", this.handleGestureMove, true);
swipeFrontElement.addEventListener("touchend", this.handleGestureEnd, true);
swipeFrontElement.addEventListener(
"touchcancel",
this.handleGestureEnd,
true
);
// Add Mouse Listener
swipeFrontElement.addEventListener(
"mousedown",
this.handleGestureStart,
true
);
}
window.addEventListener("touchstart", func, { passive: true });
if (/iP(hone|ad)/.test(window.navigator.userAgent)) {
var elements = document.querySelectorAll("button");
var emptyFunction = function() {};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener("touchstart", emptyFunction, false);
}
}
}; */
var main = function() {
// Shim for requestAnimationFrame from Paul Irishpaul ir
// http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
'use strict';
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
/* // [START pointereventsupport] */
var pointerDownName = 'pointerdown';
var pointerUpName = 'pointerup';
var pointerMoveName = 'pointermove';
if(window.navigator.msPointerEnabled) {
pointerDownName = 'MSPointerDown';
pointerUpName = 'MSPointerUp';
pointerMoveName = 'MSPointerMove';
}
// Simple way to check if some form of pointerevents is enabled or not
window.PointerEventsSupport = false;
if(window.PointerEvent || window.navigator.msPointerEnabled) {
window.PointerEventsSupport = true;
}
/* // [END pointereventsupport] */
function SwipeRevealItem(element) {
'use strict';
// Gloabl state variables
var STATE_DEFAULT = 1;
var STATE_LEFT_SIDE = 2;
var STATE_RIGHT_SIDE = 3;
var swipeFrontElement = element.querySelector('.swipe-front');
var rafPending = false;
var initialTouchPos = null;
var lastTouchPos = null;
var currentXPosition = 0;
var currentState = STATE_DEFAULT;
var handleSize = 10;
// Perform client width here as this can be expensive and doens't
// change until window.onresize
var itemWidth = swipeFrontElement.clientWidth;
var slopValue = itemWidth * (1/4);
// On resize, change the slop value
this.resize = function() {
itemWidth = swipeFrontElement.clientWidth;
slopValue = itemWidth * (1/4);
};
/* // [START handle-start-gesture] */
// Handle the start of gestures
this.handleGestureStart = function(evt) {
evt.preventDefault();
if(evt.touches && evt.touches.length > 1) {
return;
}
// Add the move and end listeners
if (window.PointerEvent) {
evt.target.setPointerCapture(evt.pointerId);
} else {
// Add Mouse Listeners
document.addEventListener('mousemove', this.handleGestureMove, true);
document.addEventListener('mouseup', this.handleGestureEnd, true);
}
initialTouchPos = getGesturePointFromEvent(evt);
swipeFrontElement.style.transition = 'initial';
}.bind(this);
/* // [END handle-start-gesture] */
// Handle move gestures
//
/* // [START handle-move] */
this.handleGestureMove = function (evt) {
evt.preventDefault();
if(!initialTouchPos) {
return;
}
lastTouchPos = getGesturePointFromEvent(evt);
if(rafPending) {
return;
}
rafPending = true;
window.requestAnimFrame(onAnimFrame);
}.bind(this);
/* // [END handle-move] */
/* // [START handle-end-gesture] */
// Handle end gestures
this.handleGestureEnd = function(evt) {
evt.preventDefault();
if(evt.touches && evt.touches.length > 0) {
return;
}
rafPending = false;
// Remove Event Listeners
if (window.PointerEvent) {
evt.target.releasePointerCapture(evt.pointerId);
} else {
// Remove Mouse Listeners
document.removeEventListener('mousemove', this.handleGestureMove, true);
document.removeEventListener('mouseup', this.handleGestureEnd, true);
}
updateSwipeRestPosition();
initialTouchPos = null;
}.bind(this);
/* // [END handle-end-gesture] */
function updateSwipeRestPosition() {
var differenceInX = initialTouchPos.x - lastTouchPos.x;
currentXPosition = currentXPosition - differenceInX;
// Go to the default state and change
var newState = STATE_DEFAULT;
// Check if we need to change state to left or right based on slop value
if(Math.abs(differenceInX) > slopValue) {
if(currentState === STATE_DEFAULT) {
if(differenceInX > 0) {
newState = STATE_LEFT_SIDE;
} else {
newState = STATE_RIGHT_SIDE;
}
} else {
if(currentState === STATE_LEFT_SIDE && differenceInX > 0) {
newState = STATE_DEFAULT;
} else if(currentState === STATE_RIGHT_SIDE && differenceInX < 0) {
newState = STATE_DEFAULT;
}
}
} else {
newState = currentState;
}
changeState(newState);
swipeFrontElement.style.transition = 'all 150ms ease-out';
}
function changeState(newState) {
var transformStyle;
switch(newState) {
case STATE_DEFAULT:
currentXPosition = 0;
break;
case STATE_LEFT_SIDE:
currentXPosition = -(itemWidth - handleSize);
break;
case STATE_RIGHT_SIDE:
currentXPosition = itemWidth - handleSize;
break;
}
transformStyle = 'translateX('+currentXPosition+'px)';
swipeFrontElement.style.msTransform = transformStyle;
swipeFrontElement.style.MozTransform = transformStyle;
swipeFrontElement.style.webkitTransform = transformStyle;
swipeFrontElement.style.transform = transformStyle;
currentState = newState;
}
function getGesturePointFromEvent(evt) {
var point = {};
if(evt.targetTouches) {
point.x = evt.targetTouches[0].clientX;
point.y = evt.targetTouches[0].clientY;
} else {
// Either Mouse event or Pointer Event
point.x = evt.clientX;
point.y = evt.clientY;
}
return point;
}
/* // [START on-anim-frame] */
function onAnimFrame() {
if(!rafPending) {
return;
}
var differenceInX = initialTouchPos.x - lastTouchPos.x;
var newXTransform = (currentXPosition - differenceInX)+'px';
var transformStyle = 'translateX('+newXTransform+')';
swipeFrontElement.style.webkitTransform = transformStyle;
swipeFrontElement.style.MozTransform = transformStyle;
swipeFrontElement.style.msTransform = transformStyle;
swipeFrontElement.style.transform = transformStyle;
rafPending = false;
}
/* // [END on-anim-frame] */
/* // [START addlisteners] */
// Check if pointer events are supported.
if (window.PointerEvent) {
// Add Pointer Event Listener
swipeFrontElement.addEventListener('pointerdown', this.handleGestureStart, true);
swipeFrontElement.addEventListener('pointermove', this.handleGestureMove, true);
swipeFrontElement.addEventListener('pointerup', this.handleGestureEnd, true);
swipeFrontElement.addEventListener('pointercancel', this.handleGestureEnd, true);
} else {
// Add Touch Listener
swipeFrontElement.addEventListener('touchstart', this.handleGestureStart, true);
swipeFrontElement.addEventListener('touchmove', this.handleGestureMove, true);
swipeFrontElement.addEventListener('touchend', this.handleGestureEnd, true);
swipeFrontElement.addEventListener('touchcancel', this.handleGestureEnd, true);
// Add Mouse Listener
swipeFrontElement.addEventListener('mousedown', this.handleGestureStart, true);
}
/* // [END addlisteners] */
}
var swipeRevealItems = [];
window.onload = function () {
'use strict';
var swipeRevealItemElements = document.querySelectorAll('.swipe-element');
for(var i = 0; i < swipeRevealItemElements.length; i++) {
swipeRevealItems.push(new SwipeRevealItem(swipeRevealItemElements[i]));
}
// We do this so :active pseudo classes are applied.
window.onload = function() {
if(/iP(hone|ad)/.test(window.navigator.userAgent)) {
document.body.addEventListener('touchstart', function() {}, false);
}
};
};
window.onresize = function () {
'use strict';
for(var i = 0; i < swipeRevealItems.length; i++) {
swipeRevealItems[i].resize();
}
};
var registerInteraction = function () {
'use strict';
window.sampleCompleted('touch-demo-1.html-SwipeFrontTouch');
};
var swipeFronts = document.querySelectorAll('.swipe-front');
for(var i = 0; i < swipeFronts.length; i++) {
swipeFronts[i].addEventListener('touchstart', registerInteraction);
}
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
ga('create','UA-52746336-1');ga('send','pageview');
var isCompleted = {};
function sampleCompleted(sampleName){
if (ga && !isCompleted.hasOwnProperty(sampleName)) {
ga('send', 'event', 'WebCentralSample', sampleName, 'completed');
isCompleted[sampleName] = true;
}
}
};
window.onload = function() {
main;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
@import "bourbon@5.*";
$font-family-sans-serif: -apple-system, system-ui, BlinkMacSystemFont,
"Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif !default;
$heading-selectors: (h1, h2, h3, h4, h5);
// Requires the calc-interpolation function which can also be used independently
@function calc-interpolation($min-screen, $min-value, $max-screen, $max-value) {
$a: ($max-value - $min-value) / ($max-screen - $min-screen);
$b: $min-value - $a * $min-screen;
$sign: "+";
@if ($b < 0) {
$sign: "-";
$b: abs($b);
}
@return calc(#{$a*100}vw #{$sign} #{$b});
}
// I'm now recommending this technique:
@mixin interpolate($properties, $min-screen, $max-screen, $min-value, $max-value) {
& {
@each $property in $properties {
#{$property}: $min-value;
}
@media screen and (min-width: $min-screen) {
@each $property in $properties {
#{$property}: calc-interpolation(
$min-screen,
$min-value,
$max-screen,
$max-value
);
}
}
@media screen and (min-width: $max-screen) {
@each $property in $properties {
#{$property}: $max-value;
}
}
}
}
// Indrek Pass also has a fantastic mixin here: http://sassmeister.com/gist/7f22e44ace49b5124eec
* {
box-sizing: border-box !important;
text-rendering: optimizeLegibility !important;
-webkit-font-smoothing: antialiased !important;
-moz-osx-font-smoothing: grayscale !important;
font-family: $font-family-sans-serif !important;
}
html {
background: #eaeaea;
color: #333;
@include interpolate(font-size, 320px, 1366px, 14px, 20px);
min-width: 300px;
padding: 0 !important;
margin: 0 !important;
touch-action: manipulation;
}
body {
padding: 0 !important;
margin: 0 !important;
font-weight: 500;
line-height: 1.5;
}
#{$heading-selectors} {
@include interpolate((padding-top, padding-bottom), 20rem, 70rem, 0rem, 0.5rem);
}
main {
max-width: 700px;
margin: 2rem auto;
width: 90%;
@media screen and (min-width: 400px) {
width: 80%;
}
}
header,
footer {
padding: 0;
width: 100%;
margin: 0;
height: 6rem;
}
footer {
height: 4rem;
display: flex;
flex-direction: column;
align-items: center;
align-content: center;
justify-content: center;
p {
color: white;
padding: 0 !important;
line-height: 1 !important;
margin: 0 !important;
font-size: 0.75rem;
letter-spacing: 1px;
color: shade(white, 40%);
}
}
%unstyled-list {
list-style: none !important;
padding: 0;
margin: 0;
li {
list-style: none !important;
padding: 0;
margin: 0;
}
}
@mixin horizontal-list {
li {
display: inline-block;
margin-right: 2rem;
}
}
@mixin block-button {
width: 100%;
margin: 0 !important;
}
@mixin inline-button {
width: 8rem;
height: 3rem;
display: inline-block;
}
@mixin button($_baseColor) {
appearance: none !important;
background: $_baseColor;
user-select: none;
text-align: center;
vertical-align: middle;
border-radius: 3px;
font-weight: 700;
letter-spacing: 1px;
cursor: pointer;
color: white;
line-height: 1 !important;
border: 0;
width: 100%;
display: block;
@media screen and (min-width: 450px) {
width: 136px;
display: inline-block;
}
height: 48px;
font-size: 1rem;
transition: all 150ms;
vertical-align: center;
backface-visibility: hidden;
-webkit-tap-highlight-color: 0;
-webkit-tap-highlight-color: rgba(#000, 0);
-webkit-tap-highlight-color: transparent;
background-image: none;
-ms-touch-action: none;
/* // [START touch-action-example] */
/* Pass all touches to javascript */
touch-action: none;
/* // [END touch-action-example] */
&::-moz-focus-inner {
border: 0;
}
&:hover,
&:focus {
background: shade($_baseColor, 10%);
outline: 0;
}
&:active {
background: shade($_baseColor, 20%);
outline: 0;
transform: translatey(4px);
}
}
button {
@include button($_baseColor: shade(#4e7bff, 10%));
&.secondary {
@include button($_baseColor: #363b59);
}
}
ul.button-group {
@extend %unstyled-list;
@include block-button;
width: 100%;
li {
display: block;
margin-bottom: 1rem;
@media screen and (min-width: 450px) {
// width: 136px;
display: inline-block;
margin-bottom: 0;
margin-right: 2rem;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment