Skip to content
This repository was archived by the owner on Aug 5, 2020. It is now read-only.

Commit

Permalink
Merge pull request #31 from mobify/desktop-override-mixin
Browse files Browse the repository at this point in the history
Add a desktop override mixin
  • Loading branch information
donnielrt committed Sep 29, 2014
2 parents 06376c9 + b330c6c commit e0bba6a
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 1 deletion.
2 changes: 2 additions & 0 deletions dist/_spline.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
@import "functions/cache-buster";
@import "functions/icon-address";
@import "functions/tint-shade";
@import "functions/parent-exists";
@import "functions/rem";
@import "functions/reverse-gradient";

Expand All @@ -56,3 +57,4 @@
@import "utilities/tap-highlight";
@import "utilities/triangle";
@import "utilities/web-font";
@import "utilities/style-override";
12 changes: 12 additions & 0 deletions dist/functions/_parent-exists.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Check if the current selector is nested
//
// @return [Boolean]

@function parent-exists() {
@if & {
@return true;
}
@else {
@return false;
}
}
54 changes: 54 additions & 0 deletions dist/utilities/_style-override.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

// Style override
// ===
//
// Allows overriding existing styles with extreme specificity while keeping
// source code clean and readable. Only use this for overriding 3rd-party CSS
// that cannot be changed. Does not override !important or inline styles; those
// must be dealt with separately.


// Configurable variables
// ---

// The default selector used to build the override. Must select the <head> tag.
// The default value selects <head id="!"> which is short (since it’s prepended
// to every wrapped selector) and obscure (to help guarantee uniqueness). Since
// it’s a special character in CSS, the `!` must be escaped. Since the '\' is a
// special character in SCSS, the '\' for the '!' must be escaped.

$style-override-head-selector: '#\\!' !default;


// Style override
// ---
//
// @param $degree [Number]: The “force” of the override. Effectively the number
// of id-level selectors you need to override.
// @param $head-selector [String]: An id selector that matches the <head> tag.

@mixin style-override($degree: 1, $head-selector: $style-override-head-selector) {
$selector-chain: '';

// Build an id selector by chaining the same id onto itself once more than
// the specified degree. So if degree: 4, we get #id#id#id#id#id.

@for $i from 1 through $degree + 1 {
$selector-chain: $selector-chain + $head-selector;
}

// Since <body> is a following sibling of <head>, we confer nested selectors
// anywhere in the <body> with the extra specificity by wrapping them in
// this:

@if parent-exists() {
@at-root #{$selector-chain} ~ body & {
@content;
}
}
@else {
@at-root #{$selector-chain} ~ body {
@content;
}
}
}
45 changes: 44 additions & 1 deletion test/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<!DOCTYPE html>
<html>
<head>
<head id="!">
<meta charset="utf-8" />
<title>Spline</title>
<link rel="stylesheet" href="test.css" media="screen">
Expand Down Expand Up @@ -155,6 +155,49 @@ <h2>Icon Font Test</h2>
</ul>
</div>

<h2>Style override test</h2>

<div class="example">
<p>The first list item should be red, the last overriden and should be green.</p>

<div id="main-content">
<div id="inner-content">
<div id="content">
<div id="main">
<div class="column">
<div class="form field">
<ul>
<li class="target">This should be red.</li>
<li class="target">This should be green.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

<div class="example parent-test">
<p>The first list item should be red, the last overriden and should be blue.</p>

<div id="main-content">
<div id="inner-content">
<div id="content">
<div id="main">
<div class="column">
<div class="form field">
<ul>
<li class="target">This should be red.</li>
<li class="target">This should be blue.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

</body>

Expand Down
1 change: 1 addition & 0 deletions test/test.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions test/test.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ $should-4: foo bar baz;
@debug if($list-3 == $should-3, 'PASS: `', 'FAIL: `') + $list-3 + '` should equal `' + $should-3 + '`.';
@debug if($list-4 == $should-4, 'PASS: `', 'FAIL: `') + $list-4 + '` should equal `' + $should-4 + '`.';

// Test function `parent-exists`
// -----------------------

@if parent-exists() {
@debug 'FAIL: Parent should not exist';
}
@else {
@debug 'PASS: Parent should not exist';
}

.parent-exists-test-1 {
.parent-exists-child {
@if parent-exists() {
@debug 'PASS: Parent should exist';
}
@else {
@debug 'FAIL: Parent should exist';
}
}
}

// Test function `reverse-gradient`
// --------------------------------
Expand Down Expand Up @@ -210,3 +230,28 @@ $icon-font-path: 'fixtures/fonts/icon';
.icon--replace {
@include icon-font-replace();
}

// Test Style Override mixin
// ---

#main-content #inner-content #content #main .column .form.field ul li.target {
color: red;
}

// Test parent-less declaration

@include style-override(4) {
.target:last-child {
color: green;
}
}

// Test declaration inside of parent

.parent-test {
@include style-override(4) {
.target:last-child {
color: blue;
}
}
}

0 comments on commit e0bba6a

Please sign in to comment.