Skip to content

Instantly share code, notes, and snippets.

@dhaneshkk
Forked from joaocunha/stylus-mixins-mdn.styl
Created November 14, 2015 17:25
Show Gist options
  • Select an option

  • Save dhaneshkk/aa5fd9fb65e65c0461c5 to your computer and use it in GitHub Desktop.

Select an option

Save dhaneshkk/aa5fd9fb65e65c0461c5 to your computer and use it in GitHub Desktop.

Revisions

  1. @joaocunha joaocunha created this gist Dec 11, 2014.
    543 changes: 543 additions & 0 deletions stylus-mixins-mdn.styl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,543 @@
    @require 'vars';
    @require 'prefixes';

    /*
    Provides man mixins for use within the MDN theme.
    */

    /* searches expression for the provided string and replaces with provided value */
    replace($expr, $str, $val) {
    $expr = clone($expr);
    for $e, $i in $expr {
    if ($e == $str) {
    $expr[$i] = $val;
    }
    }
    return $expr;
    }


    set-font-size(value) {
    font-size: value;

    if (value is not inherit) {

    // make sure we're working with px otherwise remify will just spit out what we spat out before */
    u = unit(value);
    if (u is 'px') {
    font-size: remify(value);
    }
    }
    }

    remify(value) {
    u = unit(value);

    if (u is 'px') {
    return unit(value/$base-font-size, 'rem')
    } else {
    return unit(value, u)
    }
    }

    set-smaller-font-size() {
    set-font-size($smaller-font-size);
    }
    set-larger-font-size() {
    set-font-size($base-bump-font-size);
    }

    /* vendor prefixes */


    /* vendorizes a propery based on it's value in the prefixes.styl lookup table */
    vendorize($property, $value) {
    $prefixes = $prefix-properties[''+$property];

    // might be a quoted because it has commas in it, example: transition-property
    if($value is a 'string' or $value is a 'ident') {
    $value = unquote($value);
    }

    if($prefixes == null) {
    // warn if we're prefixing something unrecognized.
    warn('Warning in vendorize(): ' + $property + ' not listed in prefixes.styl')
    // provide unprefixed value as fallback
    $property: $value;
    } else {
    for $prefix in $prefixes {
    {$prefix + $property}: $value;
    }
    // warn if we're vendorizing something unneccisarily
    if($prefixes == '') {
    warn('Warning in vendorize() ' + $property + ' does not need to be vendorized anymore. ')
    }
    }
    }

    /* vendorizes a value indescriminately by adding the prefixes defined by VENDOR-PREFIXES */
    vendorize-value(property, value, more = '') {
    for prefix in VENDOR-PREFIXES {
    {property}: unquote(prefix + value + more);
    }
    {property}: unquote(value + more);
    }

    /* prevents spacing of a given element if it's the last child */
    prevent-last-child-spacing(element = '*', property = 'padding') {
    if (element is '*') {
    element = unquote(element);
    }

    & > {element}:last-child {
    {property}: 0;
    }
    }

    prevent-last-child-bottom-spacing(element = '*') {
    prevent-last-child-spacing(element, margin-bottom);
    prevent-last-child-spacing(element, padding-bottom);
    }

    /* text-decoration none, hover text-decoration underline */
    reverse-link-decoration() {
    a {
    text-decoration: none;
    &:hover, &:active, &:focus {
    text-decoration: underline;
    }
    }
    }

    /* converts an rgba value to hex, blending on white or the provided background hex/rgb (must provide flat colour for background) */
    rgba-to-hex($color, $bg = #fff) {

    if(typeof($color) == 'rgba') {
    $a = alpha($color);
    $fallback = $color * $a + $bg * (1 - $a);

    return $fallback;
    } else {
    error('rgba-to-hex() must be used passed an rgba value');
    }


    }

    /* creates a hex fallback of a property using an rgba value
    will use white as the background matte if no colour is provided
    example input: .test { border: 20px solid rgba-fallback(rgba(255,0,0,0.5), #000);}
    example output: .test { border: 20px solid #800000; border: 20px solid rgba(255,0,0,0.5); }
    */
    rgba-fallback($color, $bg = #fff) {
    // check mixin was called inside a property
    if (current-property) {
    // check mixin was passed an rgba
    if(typeof($color) == 'rgba') {
    // get value of property
    $val = current-property[1];
    // create our fallback hex
    $fallback-hex = rgba-to-hex($color, $bg);
    // replace the rgba with the hex in the value of the property
    $hex-val = replace($val, '__CALL__', $fallback-hex);
    // add a duplicate property with the fallback value
    add-property(current-property[0], $hex-val);
    } else {
    error('rgba-fallback() must be given an rgba value');
    }

    // return the rgba for use in the original property
    $color

    } else {
    error('rgba-fallback() must be used within a property');
    }
    }

    /* generates a background property for header and zones */
    create-gradient-background(color = '', use-gradient = false) {
    if use-gradient {
    background-image: url($media-url-dir + 'header-background.png'), url($media-url-dir + 'mdn-header-gradient.png');
    background-repeat: repeat, repeat-x;
    } else {
    background-image: url($media-url-dir + 'header-background.png');
    background-repeat: repeat;
    }
    background-position: 0 0, 0 0, 0 0;
    if color {
    background-color: color;
    }
    }

    create-home-gradient-background(color) {
    create-gradient-background(color);
    background-image: url($media-url-dir + 'header-background.png'), url($media-url-dir + 'blueprint.png'), url($media-url-dir + 'mdn-header-gradient.png');
    background-repeat: repeat, repeat, repeat-x;
    }

    /* generates a cross-browser gradient */
    create-gradient(start-color, end-color, direction = false) {
    if direction {
    vendorize-value(background, linear-gradient, '(' + direction + ', ' + start-color + ', ' + end-color + ')');
    } else {
    vendorize-value(background, linear-gradient, '(' + start-color + ', ' + end-color + ')');
    }
    filter: unquote("progid:DXImageTransform.Microsoft.gradient(startColorstr='" + start-color + "', endColorstr='" + end-color + "', GradientType=1)"); /* IE6-9 */
    }

    /* generates the essential "before" and "after" code for pseudo-arrows */
    generate-arrow(arrow-width = 10px) {
    &:before, &:after {
    content: ' ';
    height: 0;
    position: absolute;
    width: 0;
    border: arrow-width solid transparent;
    }
    }

    /* used to create sliding animations */
    slider(duration=$default-animation-duration, maximum-height = 10000px) {
    overflow-y: hidden;
    max-height: maximum-height;
    vendorize(transition-property, all);
    vendorize(transition-duration, duration);
    vendorize(transition-timing-function, $slide-timing-function);

    &.closed {
    max-height: 0;
    }
    }

    /* sets the base styles for messages (review, warning, error, notice, etc.) */
    set-message-base(remove-last-spacing = true) {
    border-width: 5px;
    border-style: solid;
    padding: ($grid-spacing / 2);
    margin-bottom: $grid-spacing;
    set-smaller-font-size();

    if(remove-last-spacing) {
    & *:last-child {
    margin-bottom: 0;
    padding-bottom: 0;
    }
    }
    }

    /* removes the implied "<main>" spacing so page is more customizable */
    remove-main-spacing() {
    main > .center {
    width: auto;
    padding: 0;
    margin: 0;
    max-width: none;
    }
    }

    add-center-spacing(spacing = $gutter-width) {
    padding-left: spacing;
    padding-right: spacing;
    }

    remove-center-spacing() {
    padding-left: 0;
    padding-right: 0;
    }

    /* overrides the navigation menu color - zones and homepage */
    override-main-nav-color(hex) {
    #main-nav > ul > li > a,
    .user-state,
    .user-state a,
    .submenu-close {
    color: hex;
    }

    #main-nav > ul > li {
    .search-wrap {
    background-color: rgba-fallback(rgba(255, 255, 255, 0.4));

    input, i, .search-trigger {
    color: hex !important;
    }

    input {
    set-placeholder-style(color, hex);
    }
    }
    }

    }

    /* overrides the size of the navigation search box on certain pages */
    minimize-header-search() {

    .main-nav-search {
    width: 36px;
    @media $media-query-mobile {
    width: auto;
    }
    }

    .search-wrap input {
    width: 22px;

    &:focus {
    width: 500px;
    }
    }
    }

    /* sets an input tag's placeholder styles */
    set-placeholder-style(prop, value) {
    &::-webkit-input-placeholder {
    {prop}: value;
    }
    &::-moz-placeholder {
    {prop}: value;
    }
    }

    /* uses the white logo instead of color logo */
    use-white-logo() {
    #main-header .logo {
    background-position: 0 -41px;
    }
    }

    /* for use */

    /*
    Allows setting of a property for LTR and RTL without having to deal with duplicating and maintaining selectors:
    example: bidi-style(left, 20px, right, auto)
    */
    bidi-style(ltr-prop, value, inverse-prop, inverse-value, make-important = false) {
    make-important = make-important ? unquote('!important') : unquote('');

    {ltr-prop}: value make-important;

    html[dir='rtl'] & {
    if (ltr-prop != inverse-prop) {
    {inverse-prop}: value make-important;
    }
    {ltr-prop}: inverse-value make-important;
    }
    }

    bidi-value(prop, ltr, rtl, make-important = false) {
    bidi-style(prop, ltr, prop, rtl, make-important);
    }

    bidi-value-vendorize(prop, ltr, rtl, make-important = false) {
    make-important = make-important ? unquote('!important') : unquote('');

    vendorize(prop, ltr make-important);

    html[dir='rtl'] & {
    vendorize(prop, rtl make-important);
    }
    }

    /*
    MIXINS LIKE CLASSES
    These are not dynamic but serve as mixins so that styles wont be repeated throughout files
    */
    heading-1() {
    set-font-size(($content-block-margin * 2));
    letter-spacing: -2px;
    }

    heading-2() {
    set-font-size(30px);
    letter-spacing: -1px;
    }

    big-search() {
    background: rgba-fallback(rgba(255, 255, 255, 0.2));
    set-larger-font-size();
    display: block;
    margin: 0 auto;
    border: 0;
    border-radius: 3px;
    font-family: $heading-font-family;
    width: 60%;
    }

    offscreen() {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
    }

    clearfix() {
    clear:both;

    &:after {
    content: ' ';
    clear: both;
    display: table;
    }
    }

    title-header() {
    font-weight: bold;
    text-transform: uppercase;
    color: $text-color;
    text-decoration: none;
    display: block;
    }

    /* submenu generator: used in the main navigation and wiki */
    component-submenu(menu-width, num-columns, background-color, arrow-border-color) {
    position: absolute;
    padding: $grid-spacing;
    background: background-color;
    display: none;
    width: menu-width;
    box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.4);

    component-submenu-close();

    .submenu-column {
    if num-columns is 1 {
    col-width = 100%;
    } else {
    col-width = ((menu-width - (num-columns * $grid-spacing) - 1) / num-columns) + ($grid-spacing / 2);
    }
    vertical-align: text-top;
    width: col-width;
    display: inline-block;

    &:nth-child(even) {
    bidi-style(border-left, 1px dotted #d4dde4, border-right, 0);
    bidi-style(padding-left, $grid-spacing, padding-right, 0);
    }
    }

    a {
    set-smaller-font-size();
    padding: 5px 0;
    display: block;
    }
    reverse-link-decoration();

    generate-arrow();
    &:before {
    border-bottom-color: background-color;
    position: absolute;
    z-index: 2;
    }

    &:after {
    border-bottom-color: arrow-border-color;
    position: absolute;
    z-index: 1;
    }

    @media $media-query-mobile {
    .submenu-column, .submenu-column:nth-child(even) {
    bidi-style(border-left, 0, border-right, 0);
    bidi-style(padding-left, 0, padding-right, 0);
    }
    }

    @media $media-query-small-mobile {
    & {
    width: auto;

    .submenu-column {
    width: auto;
    display: block;
    }
    }
    }
    }

    component-submenu-close() {
    .submenu-close {
    display: none;
    position: absolute;
    top: 20px;
    bidi-style(right, 0, left, auto);

    i {
    margin-left: 0;
    }
    }

    @media $media-query-tablet {
    .submenu-close {
    display: block;
    }
    }

    }


    /* When an element contains a label and a checkbox in order (as on the edit
    profile page and elsewhere) make them appear on the same line, with the
    checkbox to the left of the label. */
    $checkbox-label-container {
    clearfix();

    input[type='checkbox'] {
    bidi-value(float, left, right);
    }

    label {
    position: absolute;
    bidi-style(margin-left, 25px, margin-right, 0);
    }
    }


    /* Dropdown menus that hide advanced feature, such as the "This Page" menu on
    article pages, the "Advanced" menu on profiles, etc. */
    $advanced-menu {
    component-submenu(160px, 1, $button-background, $button-shadow-color);
    bidi-style(right, 0, left, auto);
    top: 40px;
    z-index: 3;
    border-top: 1px solid $button-shadow-color;
    width: 160px !important; /* needs this due to overriding media query rule of component */

    bdi {
    bidi-value(text-align, left, right);
    }

    &:before {
    bidi-style(right, 10px, left, auto);
    top: -18px;
    }

    &:after {
    bidi-style(right, 10px, left, auto);
    top: -20px;
    }
    }

    $right-icons {
    margin-left: 0 !important;
    margin-right: 10px !important;
    }


    /* Styles for code blocks - used for wiki document and WYSIWYG editor */
    $code-block {
    background: $code-block-background-color;
    border-left: 6px solid $code-block-border-color;
    background-image: url($media-url-dir + 'blueprint-dark.png');
    background-position: top center;
    background-repeat: repeat;

    vendorize(tab-size, 4);
    vendorize(hyphens, none);
    }