How does `border-style: double` split the pixels?

China☆狼群 提交于 2021-02-07 07:46:32

问题


How does the browser decide how many pixels each of the 3 lines will get? Here are some cases that I hope will help you understand:

  • border: 1px double black => 1,0,0 or 0,1,0 or 0,0,1
  • border: 2px double black => 0,2,0 or 1,1,0 or 1,0,1
  • border: 4px double black => 2,1,1 or 1,2,1 or 1,1,2
  • border: 5px double black => 2,2,1 or 2,1,2 or 1,3,1
  • etc.

Are there any inconsistencies between browsers?

I'm mostly curious about this question and would appreciate an answer from a reliable source.


回答1:


From the specification we can read:

Two parallel solid lines with some space between them. (The thickness of the lines is not specified, but the sum of the lines and the space must equal border-width.)

So basically there is no rule defined thus each browser may use its own implementation. They simply need to respect the sum of the lines.


As a side note, the specification doesn't always define the exact behavior. Here is another question related to border too (If border-color is not set, it inherits the color of the element) where you can read UAs may choose their own algorithm.


Update

For google chrome you can check the Chromimum source code here: https://cs.chromium.org/ and with some search you will find the component that is used to paint the border BoxBorderPainter and inside there is a function called DrawDoubleBorder(). If you investigate this code you will probably find what you want.

For Firefox you can do the same searching here https://dxr.mozilla.org and you will find the nsCSSBorderRenderer and inside the DrawBorders() function




回答2:


As Temani said, “each browser may use its own implementation”.

So… I know that's not a “reliable” source, but it's possible to see the “logics / pattern” that is employed by each browser.

We could do something like this to help us seeing that:

// Parameter we can change
var iMax = 15;

// Creation of the list
var i;
var myOl = document.createElement("ol");
document.body.appendChild(myOl);
for (i = 1; i <= iMax; i++) {
  var myLi = document.createElement("li");
  myLi.classList.add("bord");
  myLi.style.borderWidth = i + "px";
  myLi.style.height = (iMax * 2) + "px";
  myOl.appendChild(myLi);
}
ol {
  list-style-type: decimal;
}

.bord {
  box-sizing: border-box;
  width: 66%;
  border-style: double;
  border-color: black;
  background: #EEE;
  margin-bottom: 1em;
}

⋅ ⋅ ⋅

Then, by thinking about it, I extracted an algorithm from the pattern I was seeing (I'm using Chrome):

// Parameter we can change
var iMax = 15;

// Creation of the list
var i, wBords, wSpace;
var myOl = document.createElement("ol");
document.body.appendChild(myOl);
for (i = 1; i <= iMax; i++) {
  // Calculation of split
  wBords = Math.floor(i / 3) + (i == 1) + (i % 3 == 2);
  wSpace = i - 2 * wBords;
  var myText = document.createTextNode("Borders width: " + wBords + " / Space width: " + wSpace);

  // Div for visual result
  var myDiv = document.createElement("div");
  myDiv.classList.add("bord");
  myDiv.style.borderWidth = i + "px";
  myDiv.style.height = (iMax * 2) + "px";
  
  // Output
  var myLi = document.createElement("li");
  myLi.appendChild(myText);
  myLi.appendChild(myDiv);
  myOl.appendChild(myLi);
}
ol {
  list-style-type: decimal;
}

.bord {
  box-sizing: border-box;
  width: 66%;
  border-style: double;
  border-color: black;
  background: #EEE;
  margin-bottom: 1em;
}

This pattern is very “logical”. Depending on the amount of pixels remaining from the division by 3, it splits that amount between the 2 borders, or the space.
It works well for:

  • Chrome 72
  • Firefox 65
  • Edge 42 (even if Edge adds a blurry grey color sometimes)



回答3:


There is two size in html/css inner size and outer size. With box-sizing, you can set border size inner or outer.

Border in outer width :

div {
  box-sizing:   content-box; /* default */
}

Border in inner width (width - border-width) :

div {
  box-sizing:   border-box; /* default */
}

Source: W3 - Box Sizing

Example :

For example, the following properties set the inner size of the box to 100px, and the outer size to 120px:

.box {
  box-sizing:   content-box; /* default */
  width:        100px;
  padding-left: 10px;
  border-left:  10px solid;
}

On the other hand, by changing to border-box, the inner size is now 80px, while the outer size is 100px:

.box {
  box-sizing:   border-box;
  width:        100px;
  padding-left: 10px;
  border-left:  10px solid;
}

The inner size can’t be less than zero, so if the padding + border is greater than the specified outer size, the box will end up larger than specified. In this case, the inner size will be 0px while the outer size is 120px, even though width: 100px is specified:

.box {
  box-sizing:   border-box;
  width:        100px;
  padding-left: 60px;
  border-left:  60px solid;
  /* padding + border = 120px */
}

Box dimension

8.1 Box dimensions

Each box has a content area (e.g., text, an image, etc.) and optional surrounding padding, border, and margin areas; the size of each area is specified by properties defined below. The following diagram shows how these areas relate and the terminology used to refer to pieces of margin, border, and padding:

The margin, border, and padding can be broken down into top, right, bottom, and left segments (e.g., in the diagram, "LM" for left margin, "RP" for right padding, "TB" for top border, etc.).

The perimeter of each of the four areas (content, padding, border, and margin) is called an "edge", so each box has four edges:

  • content edge or inner edge The content edge surrounds the rectangle given by the width and height of the box, which often depend on the element's rendered content. The four content edges define the box's content box.

  • padding edge The padding edge surrounds the box padding. If the padding has 0 width, the padding edge is the same as the content edge. The four padding edges define the box's padding box.

  • border edge The border edge surrounds the box's border. If the border has 0 width, the border edge is the same as the padding edge. The four border edges define the box's border box.

  • margin edge or outer edge The margin edge surrounds the box margin. If the margin has 0 width, the margin edge is the same as the border edge. The four margin edges define the box's margin box.

Each edge may be broken down into a top, right, bottom, and left edge.

The dimensions of the content area of a box — the content width and content height — depend on several factors: whether the element generating the box has the 'width' or 'height' property set, whether the box contains text or other boxes, whether the box is a table, etc. Box widths and heights are discussed in the chapter on visual formatting model details.

The background style of the content, padding, and border areas of a box is specified by the 'background' property of the generating element. Margin backgrounds are always transparent.




回答4:


You can see the firefox render code on : cs_border_segment.glsl and border.rs (-> servo).

Also, if you want a specif size 1 - 5 - 1 or 3 - 1 - 2, you can set your own border image, like you can see here.

The size depends on navigator library used to resize the border image. You can use an image with multiple of your border-width to be sure to have 1 - 5 - 1 or 3 - 1 - 2...

Example :

div {
  background:white;
  border: 30px solid orange;
  border-image: url("https://i.imgur.com/t0bFvLi.png") round;
  /* but other 'border' properties can be set after */
  border-image-slice:48;
  box-sizing:border-box;
}

div {
  height: 112px;
  width: 312px;
  margin-bottom:5px;
}

.ct {
  border-width:60px;
  height: 20px;
  box-sizing:content-box;
}

.lt {
  border-width: 6px;
  height: 20px;
  box-sizing:content-box;
}
<div>border: 30px - size: 312x312px</div>

<div class="ct">border: 10px - size: 312x312px</div>

<div class="lt">border: 10px - size: 312x312px</div>


来源:https://stackoverflow.com/questions/54749741/how-does-border-style-double-split-the-pixels

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!