Skip to content

Instantly share code, notes, and snippets.

@jkz
Last active December 11, 2015 05:49
Show Gist options
  • Save jkz/4555181 to your computer and use it in GitHub Desktop.
Save jkz/4555181 to your computer and use it in GitHub Desktop.
Less mixins for fancy 3D-like effect on text, boxes and icons.
#lego {
.X(@n, @greedy: false) {#raster > .X(@n, @greedy)}
.Y(@n, @greedy: false) {#raster > .Y(@n, @greedy)}
.Z(@n, @start, @var: true) {#shadow-stack > .Z(@n, @start, @var)}
// Walls (push an area up or down)
////////////////////////////////////////////////////////////
.wall(@n, @color, @side-color) when not (@side-color) {
background-color: @color;
#shadow-stack > .box(@n, @color, @side-color);
}
.wall(@n, @color) {
#shadow-stack > .box(@n, @color, darken(@color, 20%));
}
.wall(@n, none, @side-color) {
#shadow-stack > .box(@n, @color, @side-color);
}
// Planes (areas to build lego on with unbound size)
////////////////////////////////////////////////////////////
.plane(@z, @color, @side) when (@side = left), (@side = right) {
background-color: @color;
#raster > .row(@side);
#lego > .wall(@z, @color);
}
.plane(@z, @color, @side-color: true, @side: left) {
background-color: @color;
#raster > .row(@side);
#lego > .wall(@z, @color, @side-color);
}
// Bricks (The lego boxes this module is all about)
////////////////////////////////////////////////////////////
.brick(@color, @x, @y, @z: 0, @greed: none) {
background-color: @color;
#raster > .cell(@x, @y, @greed);
#lego > .wall(@z, @color);
}
.brick(@color, @x, @y, @z: 0, @greed: none, @side-color: true) {
background-color: @color;
#lego > .cell(@x, @y, @greed);
#lego > .Z(@z, @color, @side-color);
}
// A square lego
.tile(@color, @size, @z: 0, @greed: none) {
#lego > .brick(@color, @size, @size, @z, @greed);
}
}
// A grid system based on square cells
@grid: 50px;
@gutter: 5px;
#raster {
// Width
////////////////////////////////////////////////////////////
.width(@n, @greedy: false) when not (@greedy) {
width: (@n * @grid) + ((@n - 1) * @gutter);
}
.width(@n, true) {
width: (@n * @grid) + ((@n + 1) * @gutter);
}
// Height
////////////////////////////////////////////////////////////
.height(@n, @greedy: false) when not (@greedy) {
height: (@n * @grid) + ((@n - 1) * @gutter);
}
.height(@n, true) {
height: (@n * @grid) + ((@n + 1) * @gutter);
}
// Tile
////////////////////////////////////////////////////////////
.tile(@x, @y, none) {
#raster.width(@x);
#raster.height(@y);
}
.tile(@x, @y, horizontal) {
#raster.width(@x, true);
#raster.height(@y);
}
.tile(@x, @y, vertical) {
#raster.width(@x);
#raster.height(@y, true);
}
.tile(@x, @y, both) {
#raster.width(@x, true);
#raster.height(@y, true);
}
.tile(@x, @y) when (isnumber(@y)) {
#raster.tile(@x, @y, none);
}
.tile(@size, @greed: none) when not (isnumber(@greed)) {
#raster.tile(@size, @size, @greed);
}
// Greed
////////////////////////////////////////////////////////////
.greed(true, top) { margin-top: -@gutter }
.greed(false, top) { margin-top: @gutter}
.greed(true, right) { margin-top: -@gutter}
.greed(false, right) { margin-top: 0}
.greed(true, bottom) { margin-top: -@gutter}
.greed(false, bottom) { margin-top: 0}
.greed(true, left) { margin-top: -@gutter }
.greed(false, left) { margin-top: @gutter}
.greed(@greed, vertical) {
.greed(@greed, top);
.greed(@greed, bottom);
}
.greed(@greed, horizontal) {
.greed(@greed, left);
.greed(@greed, right);
}
.greed(@greed, both) {
.greed(@greed, vertical);
.greed(@greed, horizontal);
}
.greed(@greed, none) {
.greed(@greed, vertical);
.greed(@greed, horizontal);
}
.greed(@top, @right, @bottom, @left) {
.greed(@top, top);
.greed(@right, right);
.greed(@bottom, bottom);
.greed(@left, left);
}
// Bars (Vertical grid positioning)
////////////////////////////////////////////////////////////
.bar(@n: 1, @greedy: false) {
#raster.height(@n, @greedy);
}
.bar(@n: 1, true) {
margin-top: -@gutter;
margin-bottom: -@gutter;
}
.bar(@n: 1, false) {
margin-top: @gutter;
margin-bottom: 0;
}
//.gutter
// Row container
////////////////////////////////////////////////////////////
.row(@side: left) {
margin-left: -@gutter;
float: @side;
.clearfix;
}
// Columns (Horizontal grid positioning)
////////////////////////////////////////////////////////////
.col(@n: 1, @greedy: false) {
margin-top: @gutter;
float: inherit;
#raster.width(@n, @greedy);
}
.col(@n: 1, true) {
margin-right: -@gutter;
margin-left: -@gutter;
}
.col(@n: 1, false) {
margin-right: 0;
margin-left: @gutter;
}
// Bars (Vertical grid positioning)
////////////////////////////////////////////////////////////
.bar(@n: 1, @greedy: false) {
#raster.height(@n, @greedy);
}
.bar(@n: 1, true) {
margin-top: -@gutter;
margin-bottom: -@gutter;
}
.bar(@n: 1, false) {
margin-top: @gutter;
margin-bottom: 0;
}
// Cells (Grid areas)
// Third parameter @greed has 4 options:
// - none
// - horizontal
// - vertical
// - both
////////////////////////////////////////////////////////////
.cell(@x, @y, @_) {
}
.cell(@x, @y, none) {
#raster.col(@x);
#raster.bar(@y);
}
.cell(@x, @y, horizontal) {
#raster.col(@x, true);
#raster.bar(@y);
}
.cell(@x, @y, vertical) {
#raster.col(@x);
#raster.bar(@y, true);
}
.cell(@x, @y, both) {
#raster.col(@x, true);
#raster.bar(@y, true);
}
.cell(@x, @y) when (isnumber(@y)) {
#raster.cell(@x, @y, none);
}
.cell(@size, @greed: none) when not (isnumber(@greed)) {
#raster.cell(@size, @size, @greed);
}
// Offset resolvers
////////////////////////////////////////////////////////////
#offset {
.top(@n, @greed: false) when not (@greed) {
margin-top: @n * @grid + (@n - 1) * @gutter;
}
.top(@n, true) {
margin-top: @n * (@grid + @gutter);
}
.bottom(@n, @greed: false) when not (@greed) {
margin-bottom: @n * (@grid + @gutter);
}
.bottom(@n, true) {
margin-bottom: @n * @grid + (@n + 1) * @gutter;
}
.left(@n, @greed: false) when not (@greed) {
margin-left: @n * (@grid + @gutter);
}
.left(@n, true) {
margin-left: @n * @grid + (@n + 1) * @gutter;
}
.right(@n, @greed: false) when not (@greed) {
margin-right: @n * (@grid + @gutter);
}
.right(@n, true) {
margin-right: @n * @grid + (@n - 1) * @gutter;
}
}
// Offset shortcuts
////////////////////////////////////////////////////////////
.offset(@top, @right, @bottom, @left, @greed: false) {
#offset.offset(@top, @right, @bottom, @left, @greed, @greed, @greed, @greed)
}
.offset(@top, @right, @bottom, @right,
@greed-vertical, @greed-horizontal) {
#offset.offset(@top, @right, @bottom, @left, @greed-vertical, @greed-horizontal, @greed-vertical, @greed-horizontal)
}
.offset(@top, @right, @bottom, @right,
@greed-top, @greed-right, @greed-bottom, @greed-left) {
#offset.top(@top, @greed-top);
#offset.right(@right, @greed-top);
#offset.bottom(@bottom, @greed-top);
#offset.left(@left, @greed-top);
}
.offset(@n, @side, @greed: false) when (@side = top) {
#offset.top(@n, @greed);
}
.offset(@n, @side, @greed: false) when (@side = right) {
#offset.right(@n, @greed);
}
.offset(@n, @side, @greed: false) when (@side = bottom) {
#offset.bottom(@n, @greed);
}
.offset(@n, @side: left, @greed: false) when (@side = left) {
#offset.left(@n, @greed);
}
// Indent
.indent(@n: 1, @side: left) {
.padding(@side, @n * @grid + (@n - 1) * @gutter);
.padding(@side, @n * (@grid + @gutter));
}
.text() {
line-height: @grid;
font-size: @grid / 2;
}
.text(half) {
line-height: @grid / 2;
font-size: @grid / 4;
}
}
/********************************************************************\
| ____ / \ / \ |
| / __ \ | | | | |
| | (||\_/ | | __ ___- __| | ___ / \ / \ |
| |\____ \ | ' _ \ / _ | / __ | / _ \ \ \ / \ / / |
| / \|||) || (|||) | / (||) |_ / (||) |_ / (|||) \|\ _ /| |
| \_______/|\_/ |\_/|\____-__/|\____-__/|\_______/||\_/|||\_/| |
| \|||||||/ \|/ \|/ \||||/||/ \||||/||/ \|||||||/ \|/ \|/ |
| ____ / \ / \ |
| / __ \ | | | | /\ |
| | (||\_/ | |,_ ___- __ | |_ / / |
| |\____ \ | __/ / _ | / __| | _ ( |
| / \|||) || (||// (||) |_ / (|||,-| (||) \ |
| \_______/|\____/|\____-__/|\______/\_/| \__| |
| \|||||||/ \||||/ \||||/||/\||||||/\|/ \|/ |
| |
| Less mixins for fancy 3D-like effect on text, boxes and icons. |
| |
| This program is free software: you can redistribute it and/or |
| modify it under the terms of the GNU General Public License as |
| published by the Free Software Foundation, either version 3 of |
| the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. |
|\ /|
|\||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/|
|\||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/|
|\||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||/|
\|||||||||||||||||||||||||||||||* Copyright (C) 2013 Jesse the Game */
#shadow-stack {
////////////////////////////////////////////////////////////////
// Shadow output mixins
////////////////////////////////////////////////////////////
// Text shadow
////////////////////////////////////////////////////////
.shadow(@shadow, text) {
text-shadow: @shadow;
}
///////////////////////////////////////////////////
// Box shadow
///////////////////////////////////////////////
.shadow(@shadow, @type: box) when (@type = box) {
-webkit-box-shadow: @shadow;
-moz-box-shadow: @shadow;
-ms-box-shadow: @shadow;
-o-box-shadow: @shadow;
box-shadow: @shadow;
}
////////////////////////////////////////////////////////////////
// Recursive shadow build mixins
////////////////////////////////////////////////////////////
// Iterator (Solid)
////////////////////////////////////////////////////////
.stack(@height, @start, @end, @type, @prefix, @n, @str) when (@n > 0) {
@factor: @n / @height;
@hue: hue(@start) + (hue(@end) - hue(@start)) * @factor;
@saturation: saturation(@start) + (saturation(@end) - saturation(@start)) * @factor;
@lightness: lightness(@start) + (lightness(@end) - lightness(@start)) * @factor;
@interpolant: hsl(@hue, @saturation, @lightness);
@shadow: ~"0 @{n}px 0 @{interpolant}";
@str_: "@{shadow} @{prefix}, @{str}";
#shadow-stack > .stack(@height, @start, @end, @type, @prefix, @n - 1, @str_);
}
///////////////////////////////////////////////////
// Resolver
///////////////////////////////////////////////
.stack(@height, @start, @end, @type, @prefix, @n, @str) when (@n = 0) {
//TODO, these should be adjustable
//@s1: "@{prefix} 1px 1px 9px rgba(0,0,0,0.1)";
//@s2: "@{prefix} 1px 1px 3px rgba(0,0,0,0.3)";
@height2: @height + 7px;
@s1: ~"@{prefix} 0 @{height}px 5px rgba(0,0,0,0.1)";
@s2: ~"@{prefix} 0 @{height}px 9px rgba(0,0,0,0.3)";
//@s1: "0 0 0 #fff";
//@s2: "0 0 0 #fff";
@shadow: ~"@{str} @{s1}, @{s2}";
#shadow-stack > .shadow(@shadow, @type);
}
////////////////////////////////////////////////////////////////
// Start the recursive shadow builder
////////////////////////////////////////////////////////////
.start(@height, @start, @end, @type, @prefix) {
#shadow-stack > .stack(@height, @start, @end, @type, @prefix, @height, "");
}
////////////////////////////////////////////////////////////////
// Move the stacking element in the appropriate direction
////////////////////////////////////////////////////////////
// Push inset shadows down
////////////////////////////////////////////////////////
.prepare(@height, @start, @end, @type) when (@height < 0) {
#shadow-stack > .start(-@height, @start, @end, @type, "inset ");
}
////////////////////////////////////////////////////////
// Push drop shadows up
////////////////////////////////////////////////////
.prepare(@height, @start, @end, @type) when (@height > 0) {
#shadow-stack > .start(@height, @start, @end, @type, "");
margin-top: -@height * 1px;
margin-bottom: @height * 1px;
}
////////////////////////////////////////////////////////////////
// Pick the end color
////////////////////////////////////////////////////////////
// If end is a color, use it as end color
////////////////////////////////////////////////////////
.plan(@height, @start, @var, @type) when (iscolor(@var)) {
#shadow-stack > .prepare(@height, @start, @var, @type);
}
////////////////////////////////////////////////////
// If end is a percentage, use start darkend by it as end color
////////////////////////////////////////////////
.plan(@height, @start, @var, @type) when (ispercentage(@var)) {
#shadow-stack > .prepare(@height, @start, darken(@start, @var), @type);
}
////////////////////////////////////////////
// If end wasn't specified, use the start color
////////////////////////////////////////
.plan(@height, @start, @var, @type) when (@var) {
#shadow-stack > .prepare(@height, @start, @start, @type);
}
////////////////////////////////////////////////////////////////
// Shadow Stack API
////////////////////////////////////////////////////////////
// Mixins
////////////////////////////////////////////////////////
// .text
// .text-inset (TODO)
// .box
// .box-inset (TODO)
////////////////////////////////////////////////////
// Parameters
////////////////////////////////////////////////
// @height: Height of the stack
// @start: Color at the top of the stack
// @var (optional): Pick the color at the bottom of the stack by either:
// - color: Use it
// - percentage: Darken the start color by it
// - (omitted): Use the start color
////////////////////////////////////////////
// Usage:
////////////////////////////////////////
// #shadow-stack > .box(5, #333, 5%);
////////////////////////////////////
.text(@height, @start, @var: true) {
#shadow-stack > .plan(@height, @start, @var, text);
}
.box(@height, @start, @var: true) {
#shadow-stack > .plan(@height, @start, @var, box);
}
.box(0) {
#shadow-stack.shadow("0 0 0 #fff")
}
}
/*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\
|/||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\|
|/ \|
| 2013 |
| Jesse the Game |
| jesse@jessethegame.net |
| |
| |
\____________________________________________________________________*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment