LESS functions

Arrow functions

Arrow

Arrows are small triangles by default set to 5px base.

#arrow > .left(@arrowWidth: 5px);
#arrow > .right(@arrowWidth: 5px);
#arrow > .above(@arrowWidth: 5px);
#arrow > .below(@arrowWidth: 5px);

Pointer

Pointers are arrows with larger base, and enough margins next to them.

#pointer > .left(@arrowWidth: 6px);
#pointer > .right(@arrowWidth: 6px);
#pointer > .up(@arrowWidth: 6px);
#pointer > .down(@arrowWidth: 6px);
#pointer > .diagonalupleft(@arrowWidth: 8px);
#pointer > .diagonalupright(@arrowWidth: 8px);
#pointer > .diagonaldownleft(@arrowWidth: 8px);
#pointer > .diagonaldownright(@arrowWidth: 8px);

Usage

Arrow functions define as little as possible to generate the triangle, it is best used within containers of inline-block or in pseudo element.

// exampel of arrow above
.arrow-above {
	&:before {
		display: inline-block;
		margin-right: @space; 
		content: '';
		#arrow > .above();
	}	
}

// example of pointer up
.pointer-up {
	&:before {
		display: inline-block;
		content: '';
		#pointer > .up();
	}
}
  • Arrow above
  • Arrow below
  • Arrow left
  • Arrow right
  • Pointer up
  • Pointer down
  • Pointer left
  • Pointer right
  • Pointer up left
  • Pointer up right
  • Pointer down left
  • Pointer down right
  • Example of stand alone arrow
    #arrow > .left(10px);
  • Example of stand alone pointer
    #pointer > .right(10px);

If used with position: absolute basic positioning occurs based on intended context. This is pretty subjective, in order to define your own positioning, you can override the position values, or you can position parent block as fits.

  • Arrow above
  • Arrow below
  • Arrow left
  • Arrow right
  • Pointer up
  • Pointer down
  • Pointer left
  • Pointer right
  • Pointer up left
  • Pointer up right
  • Pointer down left
  • Pointer down right

Examples

.coloredarrow {
	display: flex;
	justify-content: center;
	align-items: center;
	width: 50px;
	height: 50px;
	padding: @halfspace;
	border:1px solid @grey-light;
	border-radius: 1000px;
	&:before {
		border-color: @yellow; 
		content: '';
		display: inline-block;
		#arrow > .right(10px);
	}
}
Some colored arrow to the right

Border radius

Use this function to set radius when @enable-rounded is set to true. Otherwise it is ignored. Default is 2px.

// enable radius in vars
@enable-rounded: true;

// use function 
.border-radius(@radius: 2px);

Or use the following shortcuts to set different borders, independent of @enable-rounded.

// default 2px, if less than zero, it is ignored
#border-radius > .all(@radius: 2px);
#border-radius > .topright(@radius: 2px);
#border-radius > .topleft(@radius: 2px);
#border-radius > .bottomright(@radius: 2px);
#border-radius > .bottomleft(@radius: 2px);

Example

.borderradius {
	#border-radius > .topleft(20px);
	#border-radius > .bottomright(5px);
	padding: @space;
}
Adding radius

Font

Size

Set the size to rem or px, or multiply font by a factor, to control responsive behavior.

// pass a value equal to 1 rem, it will output either 1 rem, or 10 px, 
// depending on @rem-enabled option
#rem > .font-size(@font-size);

// multiple the font passed by a factor of @resFontFactor
// depending on @enable-res-fonts option
#rem > .res-font-size(@font-size);

Usage: this helps in making fonts responsive by a predefined fraction, without fine tuning them.

// set font to 1.5 rem, if @rem-enabled is true, 15px if not
.responsivefont {
	#rem > .font-size(1.5);
}

.media(md, {
	.responsivefont {
		// set font to 1.5rem * @resFontFactor if @rem-enabled and @enable-res-fonts are true
		// or 15px * @resFontFactor if @rem-enabled is false
		// or 1.5rem if @enable-res-fonts is false
		// or 15px if both are false
		#rem > .res-font-size(1.5);
	}
});
1.5 rem on mobile, a bit migger on .md screen

Color contrast

Set the font color in contrast to the background color, using LESS contrast function. This is a shortcut used with the following (still in beta):

// the function uses @text-color, @white, @front-color-contrast variables
color: contrast(@c, @text-color, @white, @front-color-contrast);

// usage
.fcolor (@c);

// also, set background color to @c and front color to contrast
.colorbox(@c)

Example:

.colorcontrast-light {
	.box();

	background-color: @yellow-light;
	.fcolor($background-color);
	// or for short .colorbox(@yellow-light);
}

.colorcontrast-dark {
	.box();

	background-color: @green;
	.fcolor($background-color);
	// or for short .colorbox(@green);
}

Ellipses

.ellipsis();
/* generates the following props
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
*/

.tight-box {
	.ellipses();
}
.tight-box Lorem, ipsum dolor sit amet consectetur adipisicing elit. Harum ipsum ex ratione impedit sint unde nulla molestiae veritatis, facere, praesentium provident blanditiis! Ipsam praesentium voluptas facilis placeat distinctio sapiente voluptate?

Gradient

Two functions are used a lot, the gradient to bottom, and to right. Thus making it simply, two shortcuts are created.

// to bottom, default 0 to 100%
.gradient(@start-color, @end-color, @start-location: 0%,  @end-location: 100%);

// to right, default 0 to 100%
.gradient-h (@start-color, @end-color, @start-location: 0%,  @end-location: 100%);

// usage:
.grdbox {
	.gradient(white, black);
}
Gradient box white to black

Media

Those are quick shortcuts to define different media stops for screen and min-width, and screen and max-width. Note the width cut-offs must be defined in @screen collection in the variables file.

// produces rules inside @media only screen and (min-width: @screen[md])
// where @screen[md] is defined as 720px
.media(md, {
	// add rules here
	.my-font {
		font-size: 140%;
	}
});

// produces rules inside @media only screen and (max-width: @screen[md])
.mediamax(md, {
	.red-md {
		span {
			color: red;
		}
	}
});

// add your own cut-off in variables file:
@screen: {
	xs: 480px; // special cases
	sm: 600px; // mobile interface
	md: 720px; // tablet portrait
	lg: 960px; // the usual desktop and landscape tablets
	xl: 1200px; // more popular small desktop
	ds: 1600px; // up above desktop
	mynewscreen: 1100px;
};

// then use it
.media(mynewscreen, {
	// min-width 1100px rules here
});
.my-font is larger on screens > 720px
.red-md is red on screens < 720px
This is green when width is > 1100px

Scroll

To quickly define the shape of the scrollbar for webkit browsers, and a specific width, use the shortcut: .scroll(). This is very handy when making prototypes, and the definiton is very basic. To use it, define the overflow and height.

// defaults to 9px width
.scroll(@width: 9px);

// example:
.scrollme {
	overflow-x: hidden;
	overflow-y: auto;
	.hm-1(); 
	.scroll();
}

.scrollme-x {
	overflow-x: auto;
	overflow-y: hidden;
	white-space: nowrap;
	.scroll(2px);
}
.scrollme Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugiat nisi maiores laborum asperiores, optio quis. Optio et fugit vitae, saepe dolorum sed illo vel dolore commodi! Optio odit iste accusantium. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Assumenda sit voluptatum quidem alias officiis. Accusamus minima dolore delectus perferendis autem tempora, voluptates sequi iusto ad doloribus amet expedita quaerat cumque?
.scrollme-x Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugiat nisi maiores laborum asperiores, optio quis. Optio et fugit vitae, saepe dolorum sed illo vel dolore commodi! Optio odit iste accusantium. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Assumenda sit voluptatum quidem alias officiis. Accusamus minima dolore delectus perferendis autem tempora, voluptates sequi iusto ad doloribus amet expedita quaerat cumque?

Button

Use the main button template to create new buttons, or redefine the button template, change some properties, or add new properties, by accessing this function:

Note that the button selector is normalized, but the .btntemplate applies only to .btn- classes.
// btn-template inside the box looks like this
.btntemplate(){
	padding: @button-padding-v @button-padding-h;
	display: inline-block;
	transition: background-color .518s;
	line-height: 1;
	.border-radius(@radius);
	text-transform: uppercase;
	font-size: 90%;
	cursor: pointer;
    border: 0;
}	

// buttons have upper-case default definition, let's remove that
.btntemplate() {
	text-transform: none;
}

// create a new button based on the same template
.btn-orange {
	.btntemplate();
	color: @white;
    background-color: orange;
}

Grid

The grid system already has definitions to the major 12 columns, but those classes are not accessed in LESS files, because they are generated. So in order to define widths using the same grid system, for example for a more controled, declarative style of a specific reused component, use the following functions in LESS files.

// define grid in less for a contact card
.contact-card {
	// make a row
	.row();
	> div {
		// ensures 100% width
		.col();
	}
	.name {
		// 4/12 (@wrapper is set to 12 in variables)
		.columns(4);
	}
	.other {
		// 8/12
		.columns(8);
	}
	dl {
		.row();
		dt {
			font-size: 80%;
			color: @text-light;
			.columns(6);
		}
		dd {
			.columns(6);
		}
		dd.signature {
			// margin-left by 6/12 columns
			.offset(6);
		} 
	}
}


.media(md, {
	.contact-card {
		.name {
			.columns(3);
		}
		.other {
			.columns(9);
		}
		dl {
			dt {
				.columns(4);
			}
			dd {
				.columns(8);
			}
			dd.signature {
				.offset(4);
			} 
		}
	}
});

// the following generates width: 37.5% (4.5 / @wrapper * 100)
.myc-4-lookalike {
    .columns(4.5);
}
// the following generates width: calc(37.5% - 10px);
.myc-4-lookalike-off {
    .columns(4.5, 10px);
}
Ayyash
Phone
3045839992
Work phone
234324923993
Signature
.myc-4-lookalike 4.5
.myc-4-lookalike-off 4.5 - 10px;

Layout generation

Also, you can auto generate definitons for columns with different labels, using the following generators. Shut defines grid layout for only three screen cut-offs: plain, min-width: md, and min-width: lg. Use these functions with combinations of media queries to generate more screen cut-offs.

All grid divides by @wrapper as the base of the grid system. By default, it is 12.
// generates basic 
.generate-column(5, bleh); // generates bleh-1, .ubleh-1 > li to .bleh-5, .ubleh-5 > li
.generate-offset(5, bleh); // generates .offset-bleh-1 to .offset-bleh-5
.generate-grid(5, gbleh); // generates .gbleh-1 to .gbleh-5, use inside display: grid

/* generates .bleh-spaced > .bleh-1, .bleh-spaced.ubleh-1 > li 
to .bleh-spaced > .bleh-3,.bleh-spaced.ubleh-3 > li
using @halfspace value as the space between columns */
.bleh-spaced {
	.generate-spaced-column(3, bleh); 
}
bleh-1
bleh-2
bleh-3

.bleh-spaced allows for some gaps between columns. The way to do that is wrap with row-spaced which adds justify-content: space-between;. Then every .bleh-spaced element, has a calculated reduction in width. This allows for gaps between columns without using gap css property (which is not yet supported on Safari), but with the disadvantage that you must fill the 12 columns, otherwise it would like this:

bleh-1
bleh-2
bleh-3

For grid template, the container is .grid (display: grid). Shut only contains the simplest grid, where the first column width is defined, and the second is auto. This pattern is so repetaed in prototyping, it needed its own function.

gbleh-3
auto

The offset- classes add margin-left calculated values relative to the @wrapper value, allowing gaps in grid layout of specific number of columns. Alone, they look like this:

.offset-bleh-1
.offset-bleh-2
.offset-bleh-3

Here is an example of generating grid layout with xl screen cut-offs:

.media(xl, {
	/* generates .offset-xl-c1 to .offset-xl-c11 */
	.generate-offset(11, xl);

	/* generates .xl-1 to .xl-12, 
	and .uxl-1 > li to .uxl-12 > li */
	.generate-column(12, xl);
	
	// generats .gxl-1 to .gxl-11 with grid template
	.generate-grid(11, gxl);
	
	/* generates .row-spaced > .xl-1 to .row-spaced > .xl-12 
	and .row-spaced > .uxl-1 to .row-spaced > .uxl-12
	with slightly smaller percentages to accomodate for spacing */
	.row-spaced {
		.generate-spaced-column(12, xl);
	}
});

Grid height

The following functions produce heights multiplied by factor @grid-column-height. Out of the box, Shut defines min-height and max-height with 1 multiplier to 6. Here is how to add more.

/* generate .h-7 to .h-12, .uh-7 to .uh-12 with min-height */
.generate-min-heights(7, 12);

/* generate .hm-7 to .hm-12, .uhm-7 to .uhm-12 with max-height */
.generate-max-heights(7, 12);

Icon

The symbol definition function defines all icons generated by .getIcon() function.

Icon font definition is included if @enable-icon-font is true.
// .symbolDef inside the box looks like this:
.symbolDef() {
    font-family: @icon-font;
    text-transform: none;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    display: inline-block;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    speak: none;
    font-smooth: always;
    /* enable ligatures ================ */
    letter-spacing: 0;
    -webkit-font-feature-settings: 'liga';
    -moz-font-feature-settings: 'liga=1';
    -moz-font-feature-settings: 'liga';
    -ms-font-feature-settings: 'liga' 1;
    -o-font-feature-settings: 'liga';
    font-feature-settings: 'liga';
    -webkit-font-variant-ligatures: discretionary-ligatures;
    font-variant-ligatures: discretionary-ligatures;
    /* ligatures? */
    content: attr(data-icon);
}

// let's fine tune some properties for the current project
.symbolDef() {
	vertical-align: middle;
	font-size: 150%;
}

// pass name of class, and the character value
.icon(@name, @value);
/* to generate: 
.@{name} {
	&:before {
		content: @value;
	}
}
*/

// adds symbol definiton to :before with "value" as content
.getIcon(@value);

// adds symbol definition to :after with "value" as content
.getIcon(@value, "after");

// adds content prop (only) to :before
.changeIcon(@value);

// adds content prop (only) to :after
.changeIcon(@value, "after");

// generates content and font-family props
.displayIcon(@value);

usage

// save the icon in a variable to re-use
@icon-place: "\e900";
@icon-right: "\e904";
@icon-down: "\e902";
@icon-up: "\e905";

// this produces .icon-place class ready to use, no symbol association with it yet
.icon(icon-place,@icon-place); 

// .getIcon to generate symbol definition and content
.my-new-icon {
	.getIcon(@icon-place);
	color: @red;
}

// pass "after" as a second argument to use :after instead
.next-icon {
	.getIcon(@icon-right, "after");
}

// use .changeIcon(value) to overwrite content only of :before
.expand-icon {
	color: @green;
	.getIcon(@icon-down);

	&.expanded {
		.changeIcon(@icon-up);
	}
}

// pass "after" as a second argument to overwrite content of :after 
.collapse-icon {
	color: @red;
	.getIcon(@icon-up, "after");

	&.collapsed {
		.changeIcon(@icon-down, "after");
	}
}

// and display an icon in a pseudo element
.fancy-icon {
	position: relative;
	text-align: center;
	&:before {
		margin: auto;
		border-radius: 1000px;
		display: flex;
		justify-content: center;
		align-items: center;
		width: 50px;
		height: 50px;
		color: @white;
		background-color: fade(@blue, 50);
		.displayIcon(@icon-place);
	}

}
  • .icon-place.symbol
  • .my-new-icon
  • icon after
  • expand
    ...
    expanded
  • collapse
    ...
  • .fancy-icon