index.styl 12.3 KB
////////////////////////////////////////////////////////////////
//
// Responsive Pixels mixins for Stylus.
//
// ‘Because web design should not require a calculator.’
//
// Copyright © 2012-2015 Aral Balkan.
//
// Released with ♥ by Ind.ie under the MIT License.
//
// Think in pixels; have them automatically translated to rems.
//
///////////////////////////////////////////////////////////////


/************************************************************
 *															*
 * Mixins: Helpers											*
 *															*
 ************************************************************/

/* Convert unit to REMs if unit is in pixels. */

remify(value)

	if value == 'inherit' || value == 'auto' || value == 'none' || value == 'cover' || value == 'contain' || value == 'smaller' || value == '!important' || value == 0 || value == null
		value
	else if value == 'hairline'
		'1px'
	else if unit(value) == 'px'
		unit(value/16, 'rem')
	else
		unit(value, unit(value))

/* Abstract shorthand for attributes that can have 1-4 arguments
	(top, right, left, bottom) */

abstract-shorthand(attr, args)

	t = null
	r = null
	b = null
	l = null

	numOriginalArguments = length(args)

	if length(args) >= 1
		t = shift(args)
	if length(args) >= 1
		r = shift(args)
	if length(args) >= 1
		b = shift(args)
	if length(args) >= 1
		l = shift(args)

	rT = remify(t)
	rR = remify(r)
	rB = remify(b)
	rL = remify(l)

	if t == 'hairline'
		t = 1px
	if r == 'hairline'
		r = 1px
	if b == 'hairline'
		b = 1px
	if l == 'hairline'
		l = 1px

	if numOriginalArguments == 4
		{attr} t r b l
		/* Make sure that the rule is written out only once in case there is no rem substitution */
		if !(t == rT && r == rR && b == rB && l == rL)
			{attr} rT rR rB rL
	else if numOriginalArguments == 3
		{attr} t r b
		if !(t == rT && r == rR && b == rB)
			{attr} rT rR rB
	else if numOriginalArguments == 2
		{attr} t r
		if !(t == rT && r == rR)
			{attr} rT rR
	else if numOriginalArguments == 1
		{attr} t
		if !(t == rT)
			{attr} rT

/* Abstract longhand for attributes that take a single value */

abstract-longhand(attr, args)
	value = shift(args)
	remifiedValue = remify(value)

	if value == 'hairline'
		{attr} 1px args
	else
		{attr} value args

	if value != remifiedValue
		{attr} remify(value) args


/************************************************************
 *															*
 * Mixins: CSS overrides									*
 *															*
 ************************************************************/


/* Line height */

line-height(args...)
	abstract-longhand('line-height', args)

/* Margin */

margin(args...)
	abstract-shorthand('margin', args)

margin-top(args...)
	abstract-longhand('margin-top', args)

margin-right(args...)
	abstract-longhand('margin-right', args)

margin-bottom(args...)
	abstract-longhand('margin-bottom', args)

margin-left(args...)
	abstract-longhand('margin-left', args)

/* Padding */

padding(args...)
	abstract-shorthand('padding', args)

padding-top(args...)
	abstract-longhand('padding-top', args)

padding-right(args...)
	abstract-longhand('padding-right', args)

padding-bottom(args...)
	abstract-longhand('padding-bottom', args)

padding-left(args...)
	abstract-longhand('padding-left', args)

/* Font size */

font-size(args...)
	abstract-longhand('font-size', args)

/* Background size */
background-size(args...)
	abstract-shorthand('background-size', args)

/* Max width */

max-width(args...)
	abstract-longhand('max-width', args)

max-height(args...)
	abstract-longhand('max-height', args)

/* Border */

abstract-border(borderType, borderArgs, originalArguments)
	value = borderArgs[0];
	style = borderArgs[1];
	color = borderArgs[2];

	// Only 'none'
	if typeof(value) is 'unit'
		if unit(value) == 'px'
			{borderType} unit(value, 'px') style color
			{borderType} unit(value/16, 'rem') style color
		else
			{borderType} value style color
	else if value is 'hairline'
		// Since we lose the ability to create 1px borders, a little extension.
		{borderType} unit(1, 'px') style color
	else
		{borderType} originalArguments

border(args...)
	abstract-border('border', args, arguments)

border-top(args...)
	abstract-border('border-top', args, arguments)

border-right(args...)
	abstract-border('border-right', args, arguments)

border-bottom(args...)
	abstract-border('border-bottom', args, arguments)

border-left(args...)
	abstract-border('border-left', args, arguments)

border-radius()
	abstract-longhand('border-radius', args)

/* Width */

width(args...)
	abstract-longhand('width', args)

height(args...)
	abstract-longhand('height', args)

/* Relative and absolute positioning */

top(args...)
	abstract-longhand('top', args)

bottom(args...)
	abstract-longhand('bottom', args)

left(args...)
	abstract-longhand('left', args)

right(args...)
	abstract-longhand('right', args)


/************************************************************
 *															*
 * Typography												*
 *															*
 ************************************************************/

useJustifiedText()
	text-align justify
	hyphens(auto)

hyphens(value)
	-webkit-hyphens value
	-moz-hyphens value
	-o-hyphens value
	hyphens value

//
// Helpers (using line height as your unit of scale for vertical/horizontal rhythm.)
//

// This is the default root line height
baseLineHeight = 24

QuarterLineHeight = baseLineHeight/4 px
HalfLineHeight = baseLineHeight/2 px
ThreeQuartersLineHeight = baseLineHeight*3/4 px
OneLineHeight = baseLineHeight px
OneAndAHalfLineHeights = baseLineHeight*1.5 px
OneAndAQuarterLineHeights = baseLineHeight*1.25 px
OneAndThreeQuartersLineHeights = baseLineHeight*1.75 px
TwoLineHeights = baseLineHeight*2 px
TwoAndAQuarterLineHeights = baseLineHeight*2.25 px
TwoAndAHalfLineHeights = baseLineHeight*2.5 px
TwoAndThreeQuartersLineHeights = baseLineHeight*2.75 px
ThreeLineHeights = baseLineHeight*3 px
ThreeAndAQuarterLineHeights = baseLineHeight*3.25 px
ThreeAndAHalfLineHeights = baseLineHeight*3.5 px
ThreeAndThreeQuartersLineHeights = baseLineHeight*3.75 px
FourLineHeights = baseLineHeight*4 px
FiveLineHeights = baseLineHeight*5 px

calculateLineHeightConstants()
	QuarterLineHeight = baseLineHeight/4 px
	HalfLineHeight = baseLineHeight/2 px
	ThreeQuartersLineHeight = baseLineHeight*3/4 px
	OneLineHeight = baseLineHeight px
	OneAndAHalfLineHeights = baseLineHeight*1.5 px
	OneAndAQuarterLineHeights = baseLineHeight*1.25 px
	OneAndThreeQuartersLineHeights = baseLineHeight*1.75 px
	TwoLineHeights = baseLineHeight*2 px
	TwoAndAQuarterLineHeights = baseLineHeight*2.25 px
	TwoAndAHalfLineHeights = baseLineHeight*2.5 px
	TwoAndThreeQuartersLineHeights = baseLineHeight*2.75 px
	ThreeLineHeights = baseLineHeight*3 px
	ThreeAndAQuarterLineHeights = baseLineHeight*3.25 px
	ThreeAndAHalfLineHeights = baseLineHeight*3.5 px
	ThreeAndThreeQuartersLineHeights = baseLineHeight*3.75 px
	FourLineHeights = baseLineHeight*4 px
	FiveLineHeights = baseLineHeight*5 px


//
// Displays a baseline grid (optionally with a horizontal grid also set to the base line height)
// Issue: Not all grid lines appear to draw correctly in Firefox or Opera (they work in Safari).
//
showBaselineGrid(show = yes, baseFontSize = 16, showQuarterLineHeightMarks=no, showHorizontalGrid=no, majorLineColor=hsl(220, 50%, 70%), minorLineColor=hsl(220, 25%, 85%), quarterMarkLineColor=hsl(220, 5%, 95%), horizontalGridColor=hsl(360, 25%, 85%))

	if show == yes

		if showHorizontalGrid == no
			//
			// Just show the vertical baseline grid.
			//
			if showQuarterLineHeightMarks == no
				//
				// Show line-height and half-line-height marks.
				//
				background-image -webkit-linear-gradient(majorLineColor 1px, transparent 1px), -webkit-linear-gradient(minorLineColor 1px, transparent 1px)
				background-image -moz-linear-gradient(majorLineColor 1px, transparent 1px), -moz-linear-gradient(minorLineColor 1px, transparent 1px)
				background-image -o-linear-gradient(majorLineColor 1px, transparent 1px), -o-linear-gradient(minorLineColor 1px, transparent 1px)
				background-image linear-gradient(majorLineColor 1px, transparent 1px), linear-gradient(minorLineColor 1px, transparent 1px)

				// Also allow for a different baseFontSize to be passed in (mostly used to
				// demonstrate that vertical rhythm is maintained when scaling).
				baseLineHeightInPixels = (baseLineHeight*baseFontSize/16);

				background-size 100% unit(baseLineHeightInPixels, px), 100% unit(baseLineHeightInPixels/2, px)
			else
				//
				// Show line-height, half-line-height, and quarter-line-height marks.
				//
				background-image -webkit-linear-gradient(majorLineColor 1px, transparent 1px), -webkit-linear-gradient(minorLineColor 1px, transparent 1px), -webkit-linear-gradient(quarterMarkLineColor 1px, transparent 1px)
				background-image -moz-linear-gradient(majorLineColor 1px, transparent 1px), -moz-linear-gradient(minorLineColor 1px, transparent 1px), -moz-linear-gradient(quarterMarkLineColor 1px, transparent 1px)
				background-image -o-linear-gradient(majorLineColor 1px, transparent 1px), -o-linear-gradient(minorLineColor 1px, transparent 1px), -o-linear-gradient(quarterMarkLineColor 1px, transparent 1px)
				background-image linear-gradient(majorLineColor 1px, transparent 1px), linear-gradient(minorLineColor 1px, transparent 1px), linear-gradient(quarterMarkLineColor 1px, transparent 1px)

				// Also allow for a different baseFontSize to be passed in (mostly used to
				// demonstrate that vertical rhythm is maintained when scaling).
				baseLineHeightInPixels = (baseLineHeight*baseFontSize/16);

				background-size 100% unit(baseLineHeightInPixels, px), 100% unit(baseLineHeightInPixels/2, px), 100% unit(baseLineHeightInPixels/4, px)
		else
			//
			// Show horizontal grid lines too.
			//
			if showQuarterLineHeightMarks == 'no'
				//
				// Show horizontal grid, line-height, half-line-height marks.
				//
				background-image -webkit-linear-gradient(majorLineColor 1px, transparent 1px), -webkit-linear-gradient(minorLineColor 1px, transparent 1px)
				background-image -moz-linear-gradient(majorLineColor 1px, transparent 1px), -moz-linear-gradient(minorLineColor 1px, transparent 1px)
				background-image -o-linear-gradient(majorLineColor 1px, transparent 1px), -o-linear-gradient(minorLineColor 1px, transparent 1px)
				background-image linear-gradient(majorLineColor 1px, transparent 1px), linear-gradient(minorLineColor 1px, transparent 1px)

				// Also allow for a different baseFontSize to be passed in (mostly used to
				// demonstrate that vertical rhythm is maintained when scaling).
				baseLineHeightInPixels = (baseLineHeight*baseFontSize/16);

				background-size 100% unit(baseLineHeightInPixels, px), 100% unit(baseLineHeightInPixels/2, px)
			else
				//
				// Show horizontal-grid, line-height, half-line-height, and quarter-line-height marks.
				//
				background-image -webkit-linear-gradient(left, horizontalGridColor 1px, transparent 1px), -webkit-linear-gradient(majorLineColor 1px, transparent 1px), -webkit-linear-gradient(minorLineColor 1px, transparent 1px), -webkit-linear-gradient(quarterMarkLineColor 1px, transparent 1px)
				background-image -moz-linear-gradient(majorLineColor 1px, transparent 1px), -moz-linear-gradient(minorLineColor 1px, transparent 1px), -moz-linear-gradient(quarterMarkLineColor 1px, transparent 1px)
				background-image -o-linear-gradient(majorLineColor 1px, transparent 1px), -o-linear-gradient(minorLineColor 1px, transparent 1px), -o-linear-gradient(quarterMarkLineColor 1px, transparent 1px)
				background-image linear-gradient(majorLineColor 1px, transparent 1px), linear-gradient(minorLineColor 1px, transparent 1px), linear-gradient(quarterMarkLineColor 1px, transparent 1px)

				// Also allow for a different baseFontSize to be passed in (mostly used to
				// demonstrate that vertical rhythm is maintained when scaling).
				baseLineHeightInPixels = (baseLineHeight*baseFontSize/16);

				background-size unit(baseLineHeightInPixels, px) 100%, 100% unit(baseLineHeightInPixels, px), 100% unit(baseLineHeightInPixels/2, px), 100% unit(baseLineHeightInPixels/4, px)

		// In all cases, turn on background repeat in case developer turned it off in HTML
		// for her own custom background.
		background-repeat repeat


//
// Requires a variable called rootLineHeight to be set in your styles. If
// there isn’t one, defaults to 24px. The return value is in pixel‐parity rems
// (so divided by the default root font size of 16).
//
relative-line-height(h)
	if unit(h) == 'rlh'
		relativeLineHeight = baseLineHeight * h / 16;
		line-height unit(relativeLineHeight, 'rem')