2017-06-01 115 views
2

我正在努力實現一個大的框架RTL支持。對於這一點,我更換了所有的是定向與像混入的規則:CSS規則合併

a { 
    @include padding(0, 1px, 0, 0); 
    @include margin(0, 1px, 0, 0); 
} 

這裏做的事情,就是要根據原稿的方向添加相關的填充/保證金。

每混入創建ltr的情況下和rtl的情況下。

這是從那些混入結果:

[dir="ltr"] a { 
    padding: 0 1px 0 0; 
} 
[dir="rtl"] a { 
    padding: 0 0 0 1px; 
} 
[dir="ltr"] a { 
    margin: 0 1px 0 0; 
} 
[dir="rtl"] a { 
    margin: 0 0 0 1px; 
} 

其中一期工程,而且是很好,但創造了很多重複的選擇(每混入2),所以由100KB的CSS包大小的增加(20% ),其中很大一部分是因爲這種重複。

預期結果:

[dir="ltr"] a { 
    padding: 0 1px 0 0; 
    margin: 0 1px 0 0; 
} 
[dir="rtl"] a { 
    padding: 0 0 0 1px; 
    margin: 0 0 0 1px; 

} 

我能做些什麼,後處理合並相關的重複選擇,不傷害CSS執行的順序?

不希望的情況:

可以說我有這樣的代碼:

b.s1 { 
    padding-left: 1px; 
    margin: 0; 
} 

b.s2 { 
    padding-left: 0; 
    margin: 1px; 
} 

b.s1 { 
    padding-left: 1px; 
} 

如果我合併b.s1向上,那麼S2的填充左可以覆蓋它。 如果我向下合併b.s1,那麼S2的保證金覆蓋。

有沒有解決這個問題的方法?

編輯:原始代碼

// Add property for all sides 
// @param {string} $prop 
// @param {string} $top 
// @param {string} $end 
// @param {string} $bottom 
// @param {string} $start 
// @param {boolean} $content include content or use default 
// ---------------------------------------------------------- 
@mixin property($prop, $top, $end: $top, $bottom: $top, $start: $end, $content: false) { 
    @if $top == $end and $top == $bottom and $top == $start { 
    @include multi-dir() { 
     #{$prop}: $top; 
    } 
    } @else if $top == $bottom and $end == $start and $top != null and $end != null { 
    @include multi-dir() { 
     #{$prop}: $top $end; 
    } 
    } @else if $end == $start and $top != null and $end != null and $bottom != null { 
    @include multi-dir() { 
     #{$prop}: $top $end $bottom; 
    } 
    } @else if $top != null and $end != null and $bottom != null and $start != null { 
    @include ltr() { 
     #{$prop}: $top $end $bottom $start; 
    } 
    @include rtl() { 
     #{$prop}: $top $start $bottom $end; 
    } 
    } @else { 
    @if $content == true { // TODO check if @content exists instead 
     @content; 
    } @else { 
     @include property-horizontal($prop, $start, $end); 
     @include multi-dir() { 
     #{$prop}-top: $top; 
     #{$prop}-bottom: $bottom; 
     } 
    } 
    } 
} 
// Add padding for all sides 
// @param {string} $top 
// @param {string} $end 
// @param {string} $bottom 
// @param {string} $start 
// ---------------------------------------------------------- 
@mixin padding($top, $end: $top, $bottom: $top, $start: $end) { 
    @include property(padding, $top, $end, $bottom, $start); 
} 

// Add margin for all sides 
// @param {string} $top 
// @param {string} $end 
// @param {string} $bottom 
// @param {string} $start 
// ---------------------------------------------------------- 
@mixin margin($top, $end: $top, $bottom: $top, $start: $end) { 
    @include property(margin, $top, $end, $bottom, $start); 
} 
+0

你可以發佈你的mixin代碼嗎?爲什麼你不能將填充和邊距結合到一個mixin中,並通過傳遞正確的參數來選擇合適的? – karthick

+0

看起來好像您正在使用預處理器;請[編輯]你的問題,幷包括該預處理器的標籤。 –

+0

@MikeMcCaughan我使用與一飲而盡預處理標準頂嘴。我在答案中添加了一個吞嚥任務,以有限的方式滿足了我的需求 – Amit

回答

0

我寫了一個特定的修補程序dir,因爲這是我的主要問題,而不是其他重複這是我包的一小部分。

很簡單,並沒有工作0秒。它不會合並或上下,而是刪除代碼,並增加了,並在最後的合併方向的代碼塊。 (對於定向而言並不重要,因爲所有內容都保持其順序和特異性)

function joinDirections(contents) { 
    // This includes multi directional selectors, like `[dir="ltr"] sel, [dir="rtl"] sel`, 
    // Which go into the ltr pile, but it is ok as the rest (`sel, [dir="rtl"] sel`) is still good. 
    const dirExp = /\[dir="(.*?)"\](.*?){\s*([^}]*?)\s*}/gm; 

    let directions = {}; 

    let matches; 
    while (matches = dirExp.exec(contents)) { 
    if (!(matches[1] in directions)) 
     directions[matches[1]] = {}; 
    if (!(matches[2] in directions[matches[1]])) 
     directions[matches[1]][matches[2]] = ''; 
    directions[matches[1]][matches[2]] += matches[3]; 
    } 

    contents = contents.replace(dirExp, ''); 
    let directionalContents = ''; 

    Object.keys(directions).forEach(dir => { 
    Object.keys(directions[dir]).forEach(selector => { 
     directionalContents += `[dir="${dir}"]${selector}{${directions[dir][selector]}}\n`; 
    }); 
    }); 

    return contents + directionalContents; 
}