空文本节点和内联块布局
Empty Text Node & Inline-Block Layout
使用以下标记
<ul>
<li>
<label class="field">
Some Stuff 1
</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 2</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 3</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 4</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 5</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 6</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 7</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 8</label>
<input class="value" type="text" />
</li>
</ul>
使用以下 CSS
html, body {
width: 100%;
}
* {
margin: 0;
padding: 0;
border: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
input {
border: 1px solid;
}
ul {
list-style: none;
width: 100%;
}
ul > li {
display: inline-block;
width: 25%;
padding: 3px 8px;
}
.field,
.value {
display: block;
width: 100%;
}
请不要介意这是多么可怕,只是为了证明问题。
您会期望连续有 4 个li
,因为没有边距填充或边框来占用它们可用的任何空间,并且每个空间的大小都为父ul
的 25%。
但是因为我们都喜欢让我们的标记可读,而不仅仅是把它全部放在一行中,所以我们添加了额外的分隔符和制表符/空格来缩进 ect...但这最终在 DOM 中作为空文本节点,这些当然是完全自然的并且应该存在,但由于它们占用了 4px 的空间,确切地说,它们破坏了利用内联块的良好流畅布局。
我不喜欢在进行流畅布局时浮动元素,我喜欢使用display: inline-block
而是空文本节点存在这个烦人的问题。
现在我对我使用女巫的解决方案有一个摆弄,那就是使用 javascript 删除它们,您可以在此处或 http://jsfiddle.net/Tt9zn/5/
查看$(function() {
function tirmSpecial(str) {
// Trim 'r Carriage Return, 'n Linefeed, 't Tab, 'v Vertical Tab, 'f Form-Feed, 'u0020 Space
// Do Not Trim (u00A0 =  )
return str.replace(/^['r'n't'v'f'u0020]+|['r'n't'v'f'u0020]+$/g, '');
}
function getTextNodesIn(node, includeWhitespaceNodes) {
var textNodes = [], whitespace = /^'s*$/;
function getTextNodes(node) {
if (node.nodeType == 3) {
if (includeWhitespaceNodes || !whitespace.test(node.nodeValue)) {
textNodes.push(node);
}
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
getTextNodes(node.childNodes[i]);
}
}
}
getTextNodes(node);
return textNodes;
}
function removeEmptyTextNodes() {
var el, trimVal, nodeList = getTextNodesIn(document, true);
if(Object.prototype.toString.call(nodeList) !== '[object Array]') { return; }
while (el = nodeList.pop()) {
trimVal = tirmSpecial(el.nodeValue);
if (trimVal.length > 0) {
el.nodeValue = trimVal;
continue;
}
el.parentNode.removeChild(el);
}
}
$("#remEmpty").click(removeEmptyTextNodes);
});
为了演示我所说的空文本节点的含义,请使用IE的开发人员窗口,并在使用javascript删除它们之前查看我的Fiddle中的代码。
现在我的解决方案到目前为止可以工作,我测试了它,但我讨厌我需要编辑整个 DOM 只是为了做到这一点,我还在网上发现了一些其他解决方案,有些甚至可能来自堆栈溢出,我只是不记得在哪里,但这些都是丑陋的黑客,就像我的一样,我将在下面发布它们。
请伙计们帮助我,那里必须有一个更好的解决方案。
有人建议将您的标记更改为此标记
<ul
><li
><label class="field">Some Stuff 1</label
><input class="value" type="text"
/></li
><li
><label class="field">Some Stuff 2</label
><input class="value" type="text"
/></li
><li
><label class="field">Some Stuff 3</label
><input class="value" type="text"
/></li
><li
><label class="field">Some Stuff 4</label
><input class="value" type="text"
/></li
><li
><label class="field">Some Stuff 5</label
><input class="value" type="text"
/></li
><li
><label class="field">Some Stuff 6</label
><input class="value" type="text"
/></li
><li
><label class="field">Some Stuff 7</label
><input class="value" type="text"
/></li
><li
><label class="field">Some Stuff 8</label
><input class="value" type="text"
/></li
></ul>
这有效,一段时间后变得可读,但这有一个缺点,团队中的每个人都记得做这个可怕的黑客,更不用说自动代码缩进完全被破坏意味着每个人的生产力都会降低。
另一个CSS黑客是执行以下操作
ul {
list-style: none;
width: 100%;
/* Hack to keep "Text - Empty Text Node" elements from taking up space. */
letter-spacing: -4px;
word-spacing: -4px;
}
ul > li {
display: inline-block;
width: 25%;
padding: 3px 8px;
/* Reverse the Needed Hack to keep "Text - Empty Text Node" elements from taking up space. */
letter-spacing: normal;
word-spacing: normal;
}
这也有效,但您必须记住在使用它的任何地方应用和撤消字距技巧,如果您实际上在包含需要此技巧的其他内联块元素的部分中有文本,它也会产生一些问题,然后您必须添加一个<span></span>
或其他包装元素,以便您可以逆转黑客。
这是一个相当简单的修复:
ul {
list-style: none;
margin-left: 4px;
width: 100%;
}
ul > li {
display: inline-block;
margin-left: -4px;
padding: 3px 8px;
width: 25%;
}
不需要JavaScript!
编辑:
FWIW,我认为您最好接受这样一个事实,即浮动li
元素是实现您想要的最简单方法:
ul {
clear: both;
list-style: none;
width: 100%;
}
ul > li {
float: left;
padding: 3px 8px;
width: 25%;
}
这适用于Chrome,FF,Safari,Opera和IE 8+。 它在IE 7中失败了,但我相信这是因为IE 7不支持框大小调整。
这里有一个非常好的跨浏览器解决方案,我在下面的代码中进行了改编:http://codepen.io/pageaffairs/pen/LkaIt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
html, body {
width: 100%;
}
* {
margin: 0;
padding: 0;
border: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
input {
border: 1px solid;
}
ul {
list-style: none;
width: 100%;
}
ul > li {
display: inline-block;
width: 25%;
padding: 3px 8px;
}
.field,
.value {
display: block;
width: 100%;
}
ul {
display:table;/* Webkit Fix */
width:100%;/* set width to stop FF from wrapping li's*/
text-align:center; /* center list items*/
word-spacing:-.25em; /* hide whitespace nodes in all modern browsers (not for webkit)*/
margin:0;
padding:.25em 0;
list-style:none;
}
ul li {
display:-moz-inline-box; /* FF2 and K-Meleon */
display:inline-block;
vertical-align:bottom;
word-spacing:0; /* reset from parent ul*/
/*margin:0 .25em; /*now you can set side margins without node conflict */
padding:0 .5em;
}
* html ul li { display:inline;} /*IE6*/
*+html ul li { display:inline;} /*IE7*/
</style>
</head>
<body>
<ul>
<li>
<label class="field">
Some Stuff 1
</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 2</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 3</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 4</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 5</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 6</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 7</label>
<input class="value" type="text" />
</li>
<li>
<label class="field">Some Stuff 8</label>
<input class="value" type="text" />
</li>
</ul>
</body>
</html>
- 如何在D3中获得可缩放Icicle布局中文本标签的旋转
- D3具有矩形和文本换行的水平树布局
- 在不更改布局的情况下替换文本的解决方案(jQuery)
- 将 HTML 文本内容拆分为组,同时保留 HTML 布局
- D3 群集布局中的链接和文本路径
- 无法在 D3 强制布局中的节点上显示文本
- D3 强制布局与文本标签和图标
- 任何关于响应网格的建议,该网格将适应不同浏览器的文本大小和布局
- d3.js径向树布局可变节点长度/文本换行节点描述
- 启动d3强制布局折叠,文本标签重复
- javascript中的自定义文本编辑器布局引擎
- D3树状布局:如何用文本填充矩形,但使其大小一致
- html页面上不寻常的文本布局
- 如何制作预览布局,显示在多个文本字段中输入的文本
- 花哨的数据输入、验证和文本区域内的布局
- 如何在此表格布局中查找文本框值
- 如何将转换后的文本字符串还原为原始HTML布局
- 2列布局"显示/隐藏"函数,文本流到第二列
- EPUB3可回流-固定布局文本到Div的动态大小
- 如何获取随机文本的列宽布局的全局宽度