儘管Karol的答案接近完美,但沒有考慮僞元素或僞選擇器。此外,如果使用多個complex selector,代碼將被複制。我想出了一個簡化版本:
@mixin parent {
$parents:();
$parent: '';
@each $selector in & {
$length: length($selector);
$index: 0;
$last-selector: nth($selector, $length);
@if ($length == 1) {
@error "Used parent mixin on a top-level selector";
} @else {
$index: str-index($last-selector, '::');
@if ($index) {
$last-selector: str-slice($last-selector, 1, $index - 1);
} @else {
$last-selector: null;
}
// Inspect allows us to combine two selectors in one block.
$parent: inspect(set-nth($selector, $length, #{$last-selector}));
$parents: join($parents, $parent, comma);
}
}
@at-root #{$parents} {
@content;
}
}
有一個第一循環遍歷selector list(選擇,並在最後逗號)。由於複雜選擇器也被視爲一個列表,我們只需要移除列表的最後一個元素。因爲我們只需要丟棄最後一個,所以沒有循環來遍歷複合或簡單的選擇器。
Sass沒有刪除列表元素的功能,但我們可以使用set-nth
設置元素的值。通過將最後一個元素作爲空字符串並取消引用,我們可以從列表的打印表示(字符串)中刪除最後一個元素。由於選擇器可以是字符串,我們只需使用新字符串作爲選擇器。
當使用下列內容:
.grandmother,
.grandfather {
.parent {
.child {
font-size: 10em;
@include parent {
font-size: 5em;
}
&::after {
font-size: 1px;
@include parent {
font-weight: bold;
}
}
}
}
}
我們得到如下:
.grandmother .parent .child,
.grandfather .parent .child {
font-size: 10em;
}
.grandmother .parent,
.grandfather .parent {
font-size: 5em;
}
.grandmother .parent .child::after,
.grandfather .parent .child::after {
font-size: 1px;
}
.grandmother .parent .child,
.grandfather .parent .child {
font-weight: bold;
}
注:僞元素和僞選擇是不是一個元素的孩子,但都連接因此沒有父母本身。我認爲父母意味着薩斯嵌套意義上的父母。
將font-size設置爲0px是刪除不需要的空間的不可靠方法。如果用戶在他們的瀏覽器中強制使用最小字體大小,則無法對此進行任何操作。 – cimmanon 2013-04-22 15:33:39
我已經看過幾次,以確保在HTML中存在換行符時,內聯塊不會在它們之間獲得額外的空間。那麼什麼是更好的解決方案呢? – MacBryce 2013-04-22 16:43:46
我註釋掉HTML本身的空格。使用CSS的唯一可靠方法是,元素不能內聯(通過float,table-cell,通過Flexbox作爲Flex元素等)。 – cimmanon 2013-04-22 16:53:29