CSS预处理器和父选择器

编辑推荐: 掘金是一个高质量的技术社区,从 CSS 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货。 点击链接查看最新前端内容,或到各大应用市场搜索「 掘金」下载APP,技术干货尽在掌握中。

本文由张小可根据的《CSS Preprocessors and Parent Selectors》所译,整个译文带有我们自己的理解与思想,如果译得不好或不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://davidwalsh.name/stylus-parent-selectors,以及作者相关信息

——作者:

——译者:张小可

Web网站和web app开发对 RTL(right-to-left,从右向左的阅读顺序)是非常头疼的,因为我们没有相应的CSS属性或者是现有的CSS属性在各个浏览器兼容性太差,导致不能够让网站和网页应用正确地展示”RTL”。虽然现有一些属性比如”text-align:start;”和”-moz-margin-star”都支持”RTL”,但是他们都不能兼容所有的浏览器.然而大家都知道多国语言版的网站对于”RTL”的支持也是重要的工作之一。

难道我们最终只能这样做?给选择器添加一个支持RTL的样式,有的时候还需要添加少许偏移.

/* ltr / default */
.some {
    .thing {
        > .is {
            .here {
                margin-left: 20px;
            }
        }
    }
}

/* rtl */
html[dir=rtl] {
    .some {
        .thing {
            > .is {
                .here {
                    margin-right: 20px;
                    margin-left: 0;
                }
            }
        }
    }
}

我认为这样写生不如死,有下面这些理由:

  • 如果你需要更改默认嵌套的CSS结构,你也必须记得将这些单独RTL模块分开.
  • 如果你需要去改变原来的规则,你也必须记得去改变以前的”RTL模块”,然后再设置一个新的规则.

在Stylus中,我发现了一个很好的解决方案,用一个简单的mixin一解决这结问题。

/* mixin definition ; sets LTR and RTL within the same style call*/
bidi-style(prop, value, inverse-prop, default-value) {
    {prop}: value;

    html[dir=rtl] & {
        {inverse-prop}: value;
        {prop}: default-value;
    }
}

/* usage */
.some {
    .thing {
        > .is {
            .here {
                bidi-style(margin-left, 20px, margin-right, 0); /* setting LRT and RTL! */
            }
        }
    }
}

上面这个mixin十分简单,但是让我为之兴奋. 相比于机械地复制和频繁地重写内嵌结构,这种混合类能让我设置”RTL”的属性和值在代码中相同的位置,从而避免去创建单独的”RTL”模块. 在这个方案中,根据文字方向可以简单的置换出相关属性,基本上覆盖了95%的情景.

我也知道LESS也包含了这种模式,但是我不确定SASS也能这样做.不错的是,RTL并不是唯一一个能完美应用这个方案的例子.同时,你也可以用这种方法写一些基本特征的元素像”Modernizr CSS”的类一样:

.gradient-background {
    background-image: linear-gradient(top, #555, #333);

    .no-cssgradients & {
        background: url("background.png")
    }
}

欧耶! 这个简单的结构让写CSS和组织不同状态时容易了1百万倍.在理想的情况下,”start”的属性和值会被增加,但是在这之前没有,用这种写法会让你的生活更轻松。

补充说明

以下部分内容来自于自我整理的。

文中主要介绍了的如何在CSS预处理器语言中使用父选择器。其实在Sass中,同样具有这样的功能,我们来看一个简单的例子,即将文中Stylus的代码转换成Sass的处理方式,具体代码如下所示:

@mixin bidi-style($prop,$value,$inverse-prop,$default-value){
    #{$prop}: $value;
    html[dir=rtl] & {
        #{$inverse-prop}: $value;
        #{$prop}: $default-value;
    }
}

.some {
    .thing {
        > .is {
            .here {
                @include bidi-style(margin-left,20px,margin-right,0);
            }
        }
    }
}

经过命令编译出来以后的CSS代码如下:

.some .thing > .is .here {
  margin-left: 20px; }
  html[dir=rtl] .some .thing > .is .here {
    margin-right: 20px;
    margin-left: 0; }

不过在Sass中需要特别注意&的运用,我们来看一个简单的案例:

.children {
    .parent & {
        color:green;
    }

    &.parent {
        color:blue;
    }

    & .parent {
        color: yellow;
    }
}

编译出来的CSS:

.parent .children {
  color: green; }
.children.parent {
  color: blue; }
.children .parent {
  color: yellow; }

我想从上面这个简单的案例中,在Sass中如何运用&符实现父选择器嵌套,你已有一个更形象的理解。如果您对这方面还有更好的建议,不仿在下面的评论中与我们分享。

译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!

关于张小可

原名张奇,常用昵称“张小可”,90后文艺小青年,美工&前端攻城师,师从993,现居上海。目前不断学习UI设计,HTML5,WEB APP开发,现已参与开源项目大军中。"我热爱这个有爱的组织,这片学习的净土!寻找属于我们自己的小时代"。在这条前端荆棘之路上希望大家一起共勉,一同努力!个人博客,新浪微薄

如需转载,烦请注明出处:

英文原文:http://davidwalsh.name/stylus-parent-selectors

中文译文:http://www.w3cplus.com/preprocessor/CSS-preprocessors-and-parent-selectors.html

返回顶部