问题是与此类似:How to use bootstrap-theme.css with bootstrap 3?但不重复。我在.less级别与Bootstrap进行交互,并在每次进行更改时重新编译它。
正如我所说,我正在使用less
开发一个Bootstrap主题。我在这里编辑位,在那里改变变量。切除未使用的组件。将我的大部分新CSS放入/less/theme.less
。最后,我留下了两个css文件:/dist/css/bootstrap.css
和/dist/css/bootstrap-theme
(哦,好的,是的......和他们的.min.css
对应的,你迂腐的知识)
将此输出拆分为两个单独的文件有什么意义?他们都偏离了“库存”设置(只是改变less/variables.less
会这样做)所以不是这是一个重复的努力?这不是额外的请求,我们(认为他们最了解的开发人员)经常告诉大三学生应该不惜一切代价避免吗?
在开发自定义Bootstrap主题时,这些是我的选择:
theme.less
并在主要的Bootstrap构建中包含我的更改theme.less
,我该怎么办?为什么?
在相关的说明中,如果您单击Download Bootstrap,我是否应该从您获得的文件构建Bootstrap?事后看来,这些似乎都是为了构建Bootstrap文档(那里有大量的Jekyll废话,我只是放弃了)。是否有一个“干净”的Bootstrap版本适用于想要在没有文档的情况下自定义Bootstrap的人?
答案 0 :(得分:5)
我在这个问题上遇到了一个错误,得到了this response:
我们没有将文档分成另一个回购,因为它使得更新代码变得更加痛苦/困难。
非常可怜的IMO,但这不是我要管理的项目。经过一个小时的询问,我选择了前两个选项。我将以下内容添加到bootstrap.less
的最后一行:
@import "theme.less";
为了使这项工作成为现实,需要进行一些改动:
但输出符合要求。一个胖bootstrap.css
个文件和一个稍微瘦一点的bootstrap.min.css
文件。
我仍然不觉得黑客整个构建过程是一种使用Bootstrap作为入门主题的非常可持续的方法。对更好的解决方案非常开放。
在另一个项目中,我放弃了最后的导入,我只是在bootstrap.less
完成所有工作。当然,顶部有50行是样板进口的负载,但这意味着我不会在文件之间跳跃几乎同样多。我知道一直包含什么。
我还删除了grunt并使用我自己的现有工作流程中已经使用的结构解决方案。一如既往,您的里程可能会有所不同你不是我。
答案 1 :(得分:4)
Bootstrap 3采取了一种方法,从其所有组件中删除自以为是的风格。这是因为开发人员不得不过度编写样式并添加自己的样式,这导致了臃肿的CSS。最好从平面设计开始,可以作为基础,并根据您的意愿建立在其基础之上。
因此输入theme.less
,这是一个模板。它是创建独特主题的起点。如果你将它包含在你的bootstrap.less
版本中,你将获得我们都习惯看到的默认Bootstrap主题(即略微凸起的按钮,渐变等......)。这与您的variables.less
文件配对,可让您完全控制UI的演示文稿样式。
使用带LESS的Bootstrap的典型工作流程是使用Bower来使用它。 Bower网站将解释如何使用npm
安装凉亭。假设您安装了bower,请使用您选择的命令行应用程序cd into/your/root/path/
。运行以下命令:
bower install bootstrap --save
Bower将所有包安装到bower_components/
目录中。您永远不会改变Bower安装的文件。您应该将Bootstrap LESS文件中的三个文件复制到您自己的style
文件夹中。这些是variables.less
,bootstrap.less
和theme.less
。您可以查看my repo我将其设置为所有这一切的起点。
应该更改您复制的bootstrap.less
文件,以便所有Bootstrap @import
组件的文件路径引用Bower安装的文件路径。然后,您可以@import
将theme.less
和variables.less
的副本bootstrap.less
改为$classRel = ['sect2' => 'section-ref',
'figure' => 'fig-ref'];
libxml_use_internal_errors(true);
$dom = new DOMDocument;
$dom->loadHTML($html); // or $dom->loadHTMLFile($url);
$xp = new DOMXPath($dom);
// make a custom php function available for the XPath query
// (it isn't really necessary, but it is more rigorous than writing
// "contains(@class, 'myClass')" )
$xp->registerNamespace("php", "http://php.net/xpath");
function hasClass($classNode, $className) {
if (!empty($classNode))
return in_array($className, preg_split('~\s+~', $classNode[0]->value, -1, PREG_SPLIT_NO_EMPTY));
return false;
}
$xp->registerPHPFunctions('hasClass');
// The XPath query will find the first ancestor of a text node with '[label*'
// that is a div tag with an id and a class attribute,
// if the class attribute doesn't contain the "metadata" class.
$labelQuery = <<<'EOD'
//text()[contains(., 'label*')]
/ancestor::div
[@id and @class and not(php:function('hasClass', @class, 'metadata'))][1]
EOD;
$idNodeList = $xp->query($labelQuery);
$links = [];
// For each div node, a new link node is created in the associative array $links.
// The keys are labels.
foreach($idNodeList as $divNode) {
// The pattern extract the first text part in group 1 and the label in group 2
if (preg_match('~(\S+) .*? \[label\* ([^]]+) ]~x', $divNode->textContent, $m)) {
$links[$m[2]] = $dom->createElement('a');
$links[$m[2]]->setAttribute('href', $divNode->getAttribute('id'));
$links[$m[2]]->setAttribute('class', $classRel[$divNode->getAttribute('class')]);
$links[$m[2]]->nodeValue = $m[1];
}
}
if ($links) { // if $links is empty no need to do anything
$refNodeList = $xp->query("//text()[contains(., '[ref*')]");
foreach ($refNodeList as $refNode) {
// split the text with square brackets parts, the reference name is preserved in a capture
$parts = preg_split('~\[ref\*([^]]+)]~', $refNode->nodeValue, -1, PREG_SPLIT_DELIM_CAPTURE);
// create a fragment to receive text parts and links
$frag = $dom->createDocumentFragment();
foreach ($parts as $k=>$part) {
if ($k%2 && isset($links[$part])) { // delimiters are always odd items
$clone = $links[$part]->cloneNode(true);
$frag->appendChild($clone);
} elseif ($part !== '') {
$frag->appendChild($dom->createTextNode($part));
}
}
$refNode->parentNode->replaceChild($frag, $refNode);
}
}
$result = '';
$childNodes = $dom->getElementsByTagName('body')->item(0)->childNodes;
foreach ($childNodes as $childNode) {
$result .= $dom->saveXML($childNode);
}
echo $result;
。根据需要进行更改并编译主题。
当您想要将引导程序更新到最新版本时,您只需使用bower即可,并根据需要对复制的文件进行任何调整,以确保它们与新版本中更改的内容相匹配。
我希望能回答你的问题。