Bootstrap 3 with LESS:如何处理 Bootstrap 的嵌套规则? [英] Bootstrap 3 with LESS: how to handle bootstrap's nested rules?
问题描述
我正在尽最大努力从我的 HTML 中删除尽可能多的 Bootstrap 的类"标记样式,并在有用的地方使用语义标签,但到目前为止它只适用于简单的情况.
当原始类具有很多嵌套规则时,它就变成了一场噩梦.例如,在文档中的以下示例中(添加了大小规则):
<div class="col-lg-6"><div class="input-group input-group-lg"><span class="input-group-btn"><button class="btn btn-default" type="button">Go!</button></span><input type="text" class="form-control"></div><!--/input-group --></div><!--/.col-lg-6 --><div class="col-lg-6"><div class="input-group input-group-lg"><input type="text" class="form-control"><span class="input-group-btn"><button class="btn btn-default" type="button">Go!</button></span></div><!--/input-group --></div><!--/.col-lg-6 --></div><!--/.row -->像这样的规则很有魅力:
div:first-child {.make-row();&>div {make-lg-column(6);}}
所以这些列类可以从 HTML 中删除.然而,尝试对按钮和表单控件做同样的事情效果不佳,因为有很多嵌套规则来设置这些元素的样式.每次我从 HTML 中删除一个类时,例如使用
输入{.form-control;}
该输入丢失了基于几个 Bootstrap 规则的所有样式,例如
.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child >.btn,.input-group-btn:last-child >.btn-group >.btn,.input-group-btn:last-child >.下拉切换,.input-group-btn:first-child >.btn:not(:first-child),.input-group-btn:first-child >.btn-group:not(:first-child) >.btn
可以做到以下几点,但恕我直言,跟踪 BS 提出的每一个小细节的每一条小规则是徒劳的:
输入{.form-control;输入组 .form-control;输入组 .form-control:last-child;}
LESS' :extend(* all)
有时可以使用,但我只有基本的使用经验,到目前为止我还没有弄清楚如何制作以下逻辑"有效,或者即使可行:
div:first-child {.make-row();&>div {make-lg-column(6);div {&:extend(.input-group all);&:extend(.input-group-lg all);/* ... 等等 */}}
但是所有那些 extend()
仍然无法复制每个嵌套规则.
我在这里使用 LESS 的 extend()
是否遗漏了任何基本逻辑?这甚至是一个有价值的目标吗?到目前为止,我已经限制了我要删除的 Bootstrap 类,但我不确定这是否是正确的方法.在处理 Bootstrap 中的常见页面元素(导航标题、下拉菜单、表单等)时,经常会出现此类问题.
解决方案 首先我同意@seven-phases-max 的评论,但我想我可以用 :extend 解释你的问题
伪类.
如果您查看 Bootstrap 的 less/form-groups.less
文件,您会发现以下代码:
.input-group-lg >.form-control,.input-group-lg >.input-group-addon,.input-group-lg >.input-group-btn >.btn {.input-lg();}
前面的代码意味着.input-group-lg >.input-group-btn >.btn
子组合器也将在您的 CSS 中编译.
现在考虑以下示例 Less 代码,并考虑嵌套时 extend() 将应用于所有父级:
.class1 {颜色:绿色;>.class2 {红色;}}div {>div {&:extend(.class2 all);}}
将编译成以下 CSS 代码:
.class1 {颜色:绿色;}.class1 >.class2,.class1 >div >div {红色;}
在上面的 CSS 中,.class1 >div >div
不是您需要的选择器.
您可以使用以下 Less 代码解决上述问题:
div {>div:extend(.class1 > .class2 all){}}
这些 Less 代码将编译成以下 CSS 代码:
.class1 >.class2,div >div {红色;}
这个例子告诉你,你还必须找到编译到 Bootstrap 的 CSS 中的类关系,并在你的 :extends()
中使用它们;正如@seven-phases-max 已经提到的,这些关系很容易改变.
另请注意,在示例 Less 代码还包含一个未嵌套的 .class2 的情况下,例如:
.class2 {p:4;}
.class2
类会将您的扩展类更改为:
div {>div:extend(.class1 > .class2 all, .class2 all){}}
在您编译的 CSS 中,您将找到以下代码:
.class1 >.class2,div >div,.class1 >div >div {红色;}
其中 .class1 >div >div
由于 .class2 all
没有意义.同样,当 Less 代码包含 .class2
的其他外观时,例如:
.class3 {.class2 {属性:4;}}
:extend()
中的.class2 all
会导致很多不需要的选择器.
I'm doing my best to remove as many Bootstrap' "classes" markup style from my HTML as I can, and use semantic tags where useful, but so far it only works in simple cases.
When the original classes features a lot of nested rules, it becomes a nightmare. For instance, in the following example from the docs (with added sizing rules):
<div class="row">
<div class="col-lg-6">
<div class="input-group input-group-lg">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
<input type="text" class="form-control">
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
<div class="col-lg-6">
<div class="input-group input-group-lg">
<input type="text" class="form-control">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div><!-- /.row -->
Rules like this works like a charm:
div:first-child {
.make-row();
& > div {
make-lg-column(6);
}
}
So these column classes can be removed from HTML. However, trying to do the same to buttons and form-controls doesn't work so well, because there's a lot of nested rules to style those elements. Everytime I remove a class from HTML, for instance with
input {
.form-control;
}
That input loses every styling based on several Bootstrap's rules like
.input-group .form-control:last-child,
.input-group-addon:last-child,
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group > .btn,
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child),
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn
The following can be done, but IMHO it's unproductive to keep track of every little rule to every little detail BS pulls off:
input {
.form-control;
input-group .form-control;
input-group .form-control:last-child;
}
LESS' :extend(* all)
sometimes can be used, but I have only basic experience using it and so far I haven't been able to figure how to make the following "logic" works, or even if it's feasible:
div:first-child {
.make-row();
& > div {
make-lg-column(6);
div {
&:extend(.input-group all);
&:extend(.input-group-lg all);
/* ... and so on */
}
}
But all those extend()
still can't replicate every nested rule.
Am I missing any fundamental logic using LESS' extend()
here? Is this even a worthy goal? So far I've limited what Bootstrap classes I'm removing, but I'm not sure if this is the proper way to go. These kind of problems arise a lot when dealing with common page elements in Bootstrap (nav headers, dropdowns, forms, ...).
解决方案 In the first place i will agree with the comment of @seven-phases-max, but i think i can explain your problem with the :extend
pseudo class.
If you take a look into Bootstrap's less/form-groups.less
file, you will find the following code:
.input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
.input-lg();
}
The preceding code mean that the .input-group-lg > .input-group-btn > .btn
child combinator will be compiled in your CSS too.
Now consider the following example Less code and consider that when nested the extend() will be applied on all parents:
.class1 {
color:green;
> .class2 {
color:red;
}
}
div {
> div {
&:extend(.class2 all);
}
}
Which will compile into the following CSS code:
.class1 {
color: green;
}
.class1 > .class2,
.class1 > div > div {
color: red;
}
In the above CSS the .class1 > div > div
is not the selector you will need.
You can solve the above with the following Less code:
div {
> div:extend(.class1 > .class2 all){}
}
These Less code will compile into the following CSS code:
.class1 > .class2,
div > div {
color: red;
}
This example show you that you also will have to find class relations compiled into Bootstrap's CSS and use them in your :extends()
; these relation can easily change as already mentioned by @seven-phases-max.
Also notice that in the case that the example Less code also contains an .class2 which is not nested such as:
.class2 {
p:4;
}
The .class2
class will change you extended class to:
div {
> div:extend(.class1 > .class2 all, .class2 all){}
}
In your compiled CSS you will find the following code:
.class1 > .class2,
div > div,
.class1 > div > div {
color: red;
}
Where the .class1 > div > div
due to the .class2 all
makes no sense.
Also when the Less code contains other appearances of the .class2
for instance:
.class3 {
.class2 {
property: 4;
}
}
The .class2 all
in the :extend()
will cause a lot of unwanted selectors.
这篇关于Bootstrap 3 with LESS:如何处理 Bootstrap 的嵌套规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文