如何在不同浏览器中对齐复选框和标签

1882

这是困扰我许久的CSS小问题之一。

如何在不同浏览器中一致地垂直对齐复选框及其标签,Stack Overflow 的用户有什么好的解决方案?

每当我在 Safari 正确地对齐它们(通常使用input上的vertical-align: baseline),它们在 Firefox 和 IE 中完全偏移。

在 Firefox 中修复它,在 Safari 和 IE 中也必然会出现问题。每次编写表单时,我都会因此浪费时间。

以下是我使用的标准代码:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

我通常使用Eric Meyer的重置样式表,因此表单元素相对没有被覆盖。期待您能提供的任何提示或技巧!


9
将每个复选框和标签放置在一个<li>元素中。为<li>添加overflow:hidden属性,并将标签和复选框左浮动。这样它们就能够完美地对齐了。显然不要把复选框放在标签元素内部。 - volume one
6
我用 heightline-height 属性来实现了它,请查看 http://jsfiddle.net/wepw5o57/3/。 - TheGr8_Nik
通过对 positiontop 进行操作,可以解决这个问题。 示例:https://jsfiddle.net/ynkjc22s/ - Profesor08
2019年,问题仍然存在。仍需要一些技巧才能使其正常工作 :( - dieter
@dieter 请看我的回答,我已经解释了为什么需要黑客技巧以及什么方法不是黑客技巧:https://dev59.com/GnVC5IYBdhLWcg3wZwTj#56558431 - YakovL
40个回答

1040

注意!此答案过于陈旧,且在现代浏览器上不起作用。

我不是这个答案的发布者,但在撰写本文时,该答案是积极和消极投票中最多的答案(+1035 -17),并且仍标记为接受的答案(可能是因为问题的原始发布者是编写此答案的人)。

正如评论中多次指出的那样,此答案在大多数浏览器上不再起作用(似乎从2013年开始就无法使用了)。


经过一个多小时的调整、测试和尝试不同类型的标记,我认为我可能有一个不错的解决方案。这个特定项目的要求是:

  1. 输入必须单独一行。
  2. 复选框输入需要与标签文本垂直对齐,类似(如果不是完全相同)于所有浏览器。
  3. 如果标签文本换行,它需要缩进(因此不会在复选框下面换行)。

在我解释任何内容之前,我将只给您代码:

label {
  display: block;
  padding-left: 15px;
  text-indent: -15px;
}
input {
  width: 13px;
  height: 13px;
  padding: 0;
  margin:0;
  vertical-align: bottom;
  position: relative;
  top: -1px;
  *overflow: hidden;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

以下是在JSFiddle中的工作示例。

这段代码假设您正在使用像Eric Meyer的重置但不覆盖表单输入边距和填充(因此将重置margin和padding放在输入CSS中)的重置。显然,在实际环境中,您可能会嵌套/覆盖其他输入元素以支持其他输入元素,但我希望保持简单。

需要注意的事项:

  • *overflow声明是内联IE hack(星号属性hack)。 IE 6和7都会注意到它,但Safari和Firefox会正确地忽略它。 我认为它可能是有效的CSS,但是最好还是用条件注释; 只是为了简单起见而使用它。
  • 据我所知,唯一在所有浏览器中都一致的vertical-align语句是vertical-align: bottom。设置此然后相对定位向上行为在Safari、Firefox和IE中几乎完全相同,只有1或2个像素的差异。
  • 处理对齐的主要问题在于IE会围绕输入元素放置一堆神秘的空间。 它不是padding或margin,并且它非常持久。 在复选框上设置宽度和高度,然后overflow: hidden由于某种原因截断了额外的空间,并使IE的定位与Safari和Firefox非常相似。
  • 根据您的文本大小,您无疑需要调整相对定位、宽度、高度等等以使一切看起来正确。

我没有在除了今天早晨正在工作的项目之外的任何项目上尝试过此特定技术,因此如果您发现更加一致的解决方案,请务必提出意见。


警告!这个答案过时了,并且在现代浏览器上不起作用


由于答案已过时,而且问题本身是社区维基,所以让我推广我的答案,其中我考虑了问题的来源,而不是试图提供仅在某些浏览器中有效的CSS:https://dev59.com/questions/GnVC5IYBdhLWcg3wZwTj#56558431 - YakovL

281
有时候,垂直对齐需要两个内联元素(例如span、label、input等)彼此紧挨着才能正常工作。下面的复选框在IE、Safari、FF和Chrome中都能正确地垂直居中,即使文本大小非常小或非常大。 它们都浮动在同一行上,但nowrap意味着整个标签文本始终保持在复选框旁边。 缺点是额外的无意义SPAN标记。

.checkboxes label {
  display: inline-block;
  padding-right: 10px;
  white-space: nowrap;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label><input type="checkbox"> <span>Label text x</span></label>
    <label><input type="checkbox"> <span>Label text y</span></label>
    <label><input type="checkbox"> <span>Label text z</span></label>
  </div>
</form>

如果你有一个非常长的标签文本需要在复选框下面换行但不要紧贴着复选框,你可以对标签元素使用padding和负文本缩进:

.checkboxes label {
  display: block;
  padding-right: 10px;
  padding-left: 22px;
  text-indent: -22px;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label><input type="checkbox"> <span>Label text x so long that it will probably wrap so let's see how it goes with the proposed CSS (expected: two lines are aligned nicely)</span></label>
    <label><input type="checkbox"> <span>Label text y</span></label>
    <label><input type="checkbox"> <span>Label text z</span></label>
  </div>
</form>


26
谢谢!在输入框和文字的“vertical-align: middle”样式对我很有帮助。 - William Gross

207

One Crayon的解决方案的基础上,我有一个适合我的、更简单的方法:

.font2 {font-family:Arial; font-size:32px} /* Sample font */

input[type=checkbox], input[type=radio] {
  vertical-align: middle;
  position: relative;
  bottom: 1px;
}

input[type=radio] { 
  bottom: 2px; 
} 
<label><input type="checkbox" /> Label text</label>
<p class="font2">
  <label><input type="checkbox"/> Label text</label>
</p>

在Safari中,以像素为单位呈现的效果与我的基准相同,并且Firefox和IE7的效果也很好。 它还适用于各种标签字体大小,无论是大号还是小号。 现在,为了修复IE上选择和输入的基线...


更新:(第三方编辑)

正确的底部位置取决于字体家族和字体大小!我发现对于复选框和单选按钮元素,使用bottom: .08em;是一个不错的通用值。我在Windows中使用Arial和Calibri字体测试了几个小/中/大字号,在Chrome / Firefox / IE11中都表现良好。

.font2, .font2 input {font-family:Arial; font-size:32px} /* Sample font */

input[type=checkbox], input[type=radio] {
  vertical-align: middle; 
  position: relative;
  bottom: .08em; /* this is a better value for different fonts! */
}
<label><input type="checkbox" /> Label text</label> 

<p class="font2">
  <label><input type="checkbox"/> Label text</label>
</p>


11
提醒其他人:这个在IE6中不会起作用,因为它不支持[type=checkbox]的CSS定位。 - One Crayon

164

一种看起来很简单且有效的方式是使用vertical-align调整复选框的垂直位置。虽然在不同的浏览器上结果可能会有所不同,但解决方案非常简单。

input {
    vertical-align: -2px;
}

参考资料


非常简单。其他的居中对齐方式对我没有起作用。 - JesseBoyd

96

尝试使用 vertical-align: middle

also your code seems like it should be:

<form>
    <div>
        <input id="blah" type="checkbox"><label for="blah">Label text</label>
    </div>
</form>


14
不完全正确:Label-for 属性允许用户点击标签以选中复选框,而不仅仅是点击复选框本身。这对于将两个元素绑定在一起非常方便。 - EndangeredMassa
32
如果一个输入框被嵌套在一个标签内,那么点击标签会激活/聚焦到该输入框;而"for"属性仅用于当输入框没有被嵌套时。 - One Crayon

42

尝试我的解决方案,我在 IE 6、FF2 和 Chrome 中都试过了,它在这三个浏览器中的呈现效果都是精确的。

* {
  padding: 0px;
  margin: 0px;
}
#wb {
  width: 15px;
  height: 15px;
  float: left;
}
#somelabel {
  float: left;
  padding-left: 3px;
}
<div>
  <input id="wb" type="checkbox" />
  <label for="wb" id="somelabel">Web Browser</label>
</div>


32

对我来说,唯一完全可行的解决方案是:

input[type=checkbox], input[type=radio] {
    vertical-align: -2px;
    margin: 0;
    padding: 0;
}

今天在Chrome、Firefox、Opera、IE 7和8中测试。 示例:Fiddle


28

我还没有完全测试我的解决方案,但它似乎运行良好。

我的HTML非常简单:

<label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label>

然后我将所有复选框的高度和宽度都设置为24px。为了使文本对齐,我将标签的line-height也设为24px,并像这样分配vertical-align: top;

编辑:在 IE 测试后,我向输入框添加了 vertical-align: bottom; 并更改了标签的 CSS。您可能需要一个有条件的 IE css 来解决填充问题 - 但文本和框是内联的。

input[type="checkbox"] {
    width: 24px;
    height: 24px;
    vertical-align: bottom;
}
label.checkbox {
    vertical-align: top;
    line-height: 24px;
    margin: 2px 0;
    display: block;
    height: 24px;
}
<label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label>
<label class="checkbox"><input type="checkbox" value="0100">0100 - 0200</label>
<label class="checkbox"><input type="checkbox" value="0200">0200 - 0300</label>
<label class="checkbox"><input type="checkbox" value="0300">0300 - 0400</label>

如果有人发现这个不起作用,请友好地让我知道。这是在 Chrome 和 IE 中的实际效果(抱歉,屏幕截图是在视网膜显示器上进行的,并且在使用 Parallels 运行 IE):

复选框的 Chrome 截图 复选框的 IE 截图


硬像素值 = :( - Kalnode

23

通常我使用行高来调整静态文本的垂直位置:

label {
  line-height: 18px;
}
input {
  width: 13px;
  height: 18px;
  font-size: 12px;
  line-height: 12px;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

希望有所帮助。

20

让我们最终看一下问题的源头

复选框使用图像呈现(可以通过CSS设置自定义图像)。这是在FireFox中未被选中的复选框,使用DOM检查器突出显示:

it's just a square

这是 Chrome 中相同未经样式处理的复选框:

it's an uncentered square with "margins" on the right and on the bottom

你可以看到边距(橙色);内边距不存在(应该显示为绿色)。那么复选框右侧和底部的这个伪边距是什么?这些是用于复选框的图像的一部分。这就是为什么仅使用vertical-align: middle并不能真正满足要求,也是跨浏览器问题的根源。 那我们能做些什么呢?一个明显的选择是-替换图片!幸运的是,我们可以通过CSS来实现这一点,并用外部图片、base64(在CSS中)图片、in-CSS svg或伪元素来替换它们。这是一种强大的(跨浏览器!)方法,下面是从这个问题中偷来的一个例子:

.checkbox-custom {
  opacity: 0;
  position: absolute;
}
.checkbox-custom,
.checkbox-custom-label {
  display: inline-block;
  vertical-align: middle;
  margin: 5px;
  cursor: pointer;
}
.checkbox-custom + .checkbox-custom-label:before {
  content: '';
  display: inline-block;
  background: #fff;
  border-radius: 5px;
  border: 2px solid #ddd;
  vertical-align: middle;
  width: 10px;
  height: 10px;
  padding: 2px;
  margin-right: 10px;
  text-align: center;
}
.checkbox-custom:checked + .checkbox-custom-label:before {
  width: 1px;
  height: 5px;
  border: solid blue;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  border-radius: 0px;
  margin: 0px 15px 5px 5px;
}
<div>
  <input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox">
  <label for="checkbox-1" class="checkbox-custom-label">First Choice</label>
</div>
<div>
  <input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox">
  <label for="checkbox-2" class="checkbox-custom-label">Second Choice</label>
</div>

您可能需要阅读更深入的有关此类样式的文章,例如列出的这里;这超出了本答案的范围。

好的,那么没有自定义图像或伪元素的解决方案呢?

简而言之:看起来这行不通,使用自定义复选框代替

首先,让我们注意到,如果在其他浏览器中,复选框图标内部的伪边距是任意的,则没有一致的解决方案。为了建立一个解决方案,我们必须探索现有浏览器中此类图像的解剖学。

那么哪些浏览器具有复选框中的伪边距?我已经检查了Chrome 75、Vivaldi 2.5(基于Chromium)、FireFox 54(不要问为什么这么过时)、IE 11、Edge 42、Safari ??(借了一分钟,忘记检查版本了)。只有Chrome和Vivaldi有这样的伪边距(我怀疑所有基于Chromium的浏览器都有,如Opera)。

这些伪边距的大小是多少?可以使用缩放的复选框来找出:

input {
  zoom: 10;
  box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>

我的结果约为宽度/高度的7%,因此在绝对单位中为0.9-1.0像素。然而,准确性可能会受到质疑:尝试使用不同的缩放值进行复选框测试。在我对Chrome和Vivaldi的测试中,伪边距的相对大小在缩放值为10、20和11-19(??)时非常不同:

for zoom = 10 it's 7% while for zoom = 11 it's almost twice that value

scale 似乎更加一致:

input {
  transform: scale(10) translate(50%, 50%);
  box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>

因此,大概是14%和2px是正确的值。

现在我们知道了伪边距的大小,但这还不够。所有浏览器的复选框图标大小都相同吗?唉!以下是未经样式化的复选框的DOM检查器显示的内容:

  • FireFox:13.3px
  • 基于Chromium的浏览器:整个东西12.8px,因此12.8(100%-14%)= 11px,视觉上感知为复选框的大小
  • IE 11、Edge:13px
  • Safari:n / a(我认为应该在同一屏幕上进行比较)

在我们讨论任何解决方案或技巧之前,让我们问一下:什么是正确的对齐方式?我们要实现什么?在某种程度上,这是品味问题,但基本上我可以考虑以下“好”对齐方式的方面:

文本和复选框在同一基线上(我故意不调整复选框大小):

enter image description here

或者在小写字母方面具有相同的中线:

enter image description here

或者在大写字母方面具有相同的中线(对于不同的字体大小,这更容易看出区别):

enter image description here

并且我们还需要决定复选框的大小是否应该与小写字母、大写字母或其他内容(更大、更小或介于小写字母和大写字母之间)相等。 在本讨论中,如果复选框与文本处于同一基线并具有大写字母的大小(这是一个极具争议的选择),则称其对齐方式为良好。

enter image description here

现在我们有哪些工具来:

  1. 调整复选框大小
  2. 识别带有伪边框复选框的Chromium并设置特定样式
  3. 调整复选框/标签的垂直对齐

?

关于复选框大小调整:有widthheightsizezoomscale(我漏掉了什么吗?)。zoomscale不能设置绝对大小,因此它们只能帮助调整到文本大小,而不能设置跨浏览器大小(除非我们可以编写特定于浏览器的规则)。size在Chrome中不起作用(它在旧版IE中起作用吗?无论如何,它并不那么有趣)。widthheight在Chrome和其他浏览器中都有效,因此我们可以设置一个常见的大小,但是在Chrome中,它设置的是整个图像的大小,而不是复选框本身的大小。注意:最小(宽度,高度)定义了复选框的大小(如果宽度≠高度,则在复选框正方形外部的区域会添加“伪边距”)。 不幸的是,在我看来,Chrome复选框中的伪边距没有被设置为任何宽度和高度的零。
  • 恐怕现在没有可靠的仅CSS方法

  • 让我们考虑垂直对齐。由于Chrome的伪边距,vertical-align设置为middlebaseline时无法给出一致的结果,因此获取所有浏览器相同的“坐标系”的唯一真实选项是将标签和输入对齐到top

    comparing vertical-align: top and bottom

    (图片上:垂直对齐:顶部、底部和没有盒子阴影的底部)

  • 那么我们从这里得到的结果是什么?

    input[type="checkbox"] {
        height: 0.95em;
        width: 0.95em;
    }
    label, input {
        vertical-align: top;
    }
    <label><input type="checkbox">label</label>

    上面的片段适用于Chrome(基于Chromium的浏览器),但其他浏览器需要更小的复选框尺寸。似乎不可能以一种可以解决Chromium复选框图像问题的方式调整大小和垂直对齐。我的最终建议是:使用自定义复选框,这样就可以避免沮丧 :)

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,