em单位下的边框宽度 - 但设置最小边框宽度

7

我希望一个div的边框宽度与字体大小成比例,所以我设置了像 border-width: 0.1em; 这样的值。但是如果字体太小,边框就不会显示出来,因为它渲染成了0.5px。这显然不是我想要的结果。有没有办法设置最小边框宽度为1px呢?

div {
    border: 0.1em solid black;
}

2
不,边框使用像素。您可以使用盒子阴影来模拟边框并在其上添加em空格。 - Christina
我不明白为什么不能使用相对长度。你能证明吗?虽然百分比行不通。你能给我一个box-shadow解决方案的例子吗?@Hiral 我添加了我使用的代码,但这是显而易见的。 - luke
您还可以使用 thinmediumthick 来设置 border-width(只要它们与您喜欢的宽度匹配)。它们会随着界面的缩放而自适应。 - tomasz86
2个回答

5
在CSS3中,如果您的浏览器支持它,您可以尝试滥用max CSS函数。
border-width: max(1px, 0.1em);
border-style: solid; 
border-color: black;

不幸的是,目前没有任何浏览器支持这个惊人的CSS3特性,但我希望这很快会改变!

但在CSS2中 - 不行,你不能这么做。
但是,你可以使用JavaScript / jQuery来循环遍历所有元素,并将边框大小增加到1px。

但是,如果页面上有太多元素(例如超过50-100行的表),那么这会消耗大量的性能,使你的浏览器崩溃。
因此,换句话说,不可能实现。

$("[id$='ReportViewerControl']").find('*')

    .each(function () {

        if($(this).is('#ParametersRowReportViewerControl *')) 
            return;

        //console.log("Processing an element");
        //var cls = $(this).attr("class");

        // Don't add a border to sort-arrow
        if ($(this).is('img')) {
            return;
        }

        var anywidth = $(this).css('width');
        var anywidth = parseFloat(anywidth);
        //console.log("anywidth: " + anywidth);


        //var lol = $(this).css('borderLeftWidth');
        var blw = $(this).css('border-left-width');
        var brw = $(this).css('border-right-width');
        var btw = $(this).css('border-top-width');
        var bbw = $(this).css('border-bottom-width');

        var borls = $(this).css('border-left-style') == "solid";
        var borrs = $(this).css('border-right-style') == "solid";
        var borts = $(this).css('border-top-style') == "solid";
        var borbs = $(this).css('border-bottom-style') == "solid";

        var blw = parseFloat(blw);
        var brw = parseFloat(brw);
        var btw = parseFloat(btw);
        var bbw = parseFloat(bbw);

        //parseInt($(this).css("borderRightWidth"))
        //console.log(parseInt($(this).css("borderLeftWidth")));

        // UpdateLock = true;


        // Set width to 1px where 0px
        if (anywidth == 0)
            $(this).css('width', '1px');

        if (borls && blw == 0.0 || (blw > 0.0 && blw < 1.0)) {
            //console.log("setting border width");
            $(this).css('border-left-width', '1px');
        }

        if (borrs && brw == 0.0 || (brw > 0.0 && brw < 1.0)) {
            $(this).css('border-right-width', '1px');
        }

        if (borts && btw == 0.0 || (btw > 0.0 && btw < 1.0)) {
            $(this).css('border-top-width', '1px');
        }

        if (borbs && bbw == 0.0 || (bbw > 0.0 && bbw < 1.0)) {
            $(this).css('border-bottom-width', '1px');
        }

        // UpdateLock = false;
    });           // End $('*').each

谢谢,min()函数正是我需要的,尽管它目前还没有得到支持。 - luke
2
@luke:小心,口语和数学之间有区别。你需要使用max函数,而不是min函数 ;) 在1px和0.1em的边框宽度之间,为了使边框至少为1px(或更宽),你需要选择两个值中的最大值! - Stefan Steiger
似乎min/max函数文档的描述不太好。我从这里阅读了更多内容:http://www.dreamdealer.nl/articles/css3_calc_min_and_max_functions.html,但他们的示例是错误的。顺便问一下,为什么你要写abuse?这个函数实际上是用来做什么的? - luke
注:当你使用sass时,max()方法不起作用,因为sass会覆盖本地的CSS函数。有人知道解决这个问题的方法吗? - Ini

2
看起来不同的浏览器对于小于1像素的边框处理方式不同。在Firefox中,这样的边框似乎呈现为1像素宽,但在Chrome中则会消失。另一方面,看起来Chrome即使box-shadow小于1像素也会呈现出来,所以使用它代替边框可能是一个好主意(Christina在问题的评论中实际上建议这样做)。然而,有些浏览器如果box-shadow太细的话就不会呈现出来(Firefox会这样做)。此外,box-shadow不会增加盒模型,因此可能需要使用额外的margin

以下是克服这些问题的尝试。请注意,我不得不采用JavaScript userAgent检测黑客(如果是webkit浏览器,只需向body添加一个额外的类),因为我无法仅使用CSS实现它。

if (navigator.userAgent.toLowerCase().indexOf("webkit") > -1)
{
    document.body.className += " webkitHack";
}
/* Borders */

.border{
  border:0.0625em solid black;
}

.shadowyBorder{
  box-shadow: 0 0 0 0.0625em black;
  /* Compensating for the fact that box-shadow doesn't count towards box model */
  margin: 0.0625em;
}

.comboBorder
{
  /* If it's not webkit use border */
  border:0.0625em solid black;
}

/* If it's webkit use box-shadow */
.webkitHack .comboBorder
{
  border: none;
  box-shadow: 0 0 0 0.0625em black;
  /* Compensating for the fact that box-shadow doesn't count towards box model */
  margin: 0.0625em;
}

/* Extras */
td, th
{
  padding:5px;
}
.em05
{
  font-size:8px;
}

.em1
{
  font-size:16px;
}

.em2
{
  font-size:32px;
}

.box
{
  display:inline-block;
  height:1em;
  width:1em;
}
<table>
  <tr>
    <th>Font size</th><th>Border</th><th>Box shadow</th><th>Box shadow in webkit</th>
  </tr>
  <tr>
    <td>
      8px
    </td>
    <td class="em05">
      <div class="box border"></div>
    </td>
    <td class="em05">
      <div class="box shadowyBorder"></div>
    </td>
    <td class="em05">
      <div class="box comboBorder"></div>
    </td>
  </tr>
  <tr>
    <td>
      16px
    </td>
    <td class="em1">
      <div class="box border"></div>
    </td>
    <td class="em1">
      <div class="box shadowyBorder"></div>
    </td>
    <td class="em1">
      <div class="box comboBorder"></div>
    </td>
  </tr>
  <tr>
    <td>
      32px
    </td>
    <td class="em2">
      <div class="box border"></div>
    </td>
    <td class="em2">
      <div class="box shadowyBorder"></div>
    </td>
    <td class="em2">
      <div class="box comboBorder"></div>
    </td>
  </tr>
</table>


使用此方法可以从所有边缘或仅从单个边缘重新创建边框,但要实现在2或3个边缘上的边框组合,可能需要使用inset box-shadow和额外填充。 - jahu
1
当前版本的Chrome似乎将边框渲染得比1px更细,但是如果要针对旧的Webkit浏览器(例如Android 4.x上的Android浏览器)进行目标定位时,这个技巧仍然可能很有用。 - jahu

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