1

使用以下标记

<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%;
}

请不要介意这只是为了证明问题有多可怕。

您会期望li连续有 4 个,因为没有边距填充或边框来占用它们可用的任何空间,并且每个的大小为 parent 的 25% ul

但是因为我们都喜欢让我们的标记可读,而不是只在一行中,我们添加了额外的中断和制表符/空格来缩进等......但这最终在 DOM 中作为空文本节点这些当然是完全自然的并且应该在那里,但是由于它们占用了 4px 的空间,因此它们破坏了使用 inline-block 的良好流畅布局。

我不喜欢在做流畅的布局时浮动元素,我喜欢使用它,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 = &nbsp)
        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 的开发人员窗口并查看我的 Fiddle 中的代码,然后再使用 javascript 删除它们。

现在我的解决方案到目前为止有效,但我讨厌我需要编辑整个 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 Hack 是执行以下操作

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;
}

这也有效,但是您必须记住在使用它的任何地方都应用和撤消字间距 hack,如果您实际上在一个部分中包含需要此 hack 的其他内联块元素的部分中的文本,那么您将不得不添加a<span></span>或其他包装元素,以便您可以扭转黑客攻击。

4

2 回答 2

2

这是一个相当简单的修复:

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 不支持 box-sizing。

于 2013-05-29T13:09:02.940 回答
1

这里有一个非常好的跨浏览器解决方案,我在下面的代码中进行了调整: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>
于 2013-05-29T13:24:21.983 回答