This is an interview question from Bytedance.

The original problem

* {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 500px;
	flex-shrink: 2;
	background: red;
}
.right {
	width: 400px;
	flex-shrink: 1;
	background: blue;
}
Copy the code

Find the width of the final left and right.

parsing

Let’s look at the actual presentation

Left: 285.72 px right: 314.28 pxCopy the code

When the sum of the child widths exceeds the width of the parent, instead of just calculating the child widths by 500:400 or 2:1, the actual calculation should look like this:

  1. Calculate the excess: 500+400-600=300
  2. Notice, here’s the point: the actual ratio of the excess is 500×2 to 400×1, which is 5:2
  3. The width of the left is 500-3005/7 ≈ 285.71, Right: 400-3002/7 ≈ 314.29, in line with the actual situation.

extension

Let’s add the padding

* {
	padding: 0;
	margin: 0;
}
.container {
	width: 600px;
	height: 300px;
	display: flex;
}
.left {
	width: 500px;
	padding: 40px;
	flex-shrink: 2;
	background: red;
}
.right {
	width: 400px;
	padding: 20px;
	flex-shrink: 1;
	background: blue;
}
Copy the code

The practical effect is:

left: 280px

right: 320px
Copy the code

So let’s think about why did it change?

The reason is that

  1. When we don’t setbox-sizing, its default value iscontent-boxThat is, the standard box model, the width of the box is not includedpadding,borderSo if the width of the parent container is not taken into account, the space occupied by the left is 500 + 40×2= 580 and the space occupied by the right is 400 + 40×2=440.
  2. When the Flex item calculates the available space, the padding part is frozen and does not participate in the allocation. So the available space for left is 580-40×2=500, and the available space for right is 440-20×2=400.

Below is a W3C description of the available space in a Flex layout

w3c: Determine the available main and cross space for the flex items. For each dimension, If that dimension of the flex container’s content box is a definite size, use that; if that dimension of the flex container is being sized under a min or max-content constraint, the available space in that dimension is that constraint; Subtract the flex container’s margin, border, and padding from the space available to the flex container in that dimension and use that value. This might result in an infinite value.

Margin, border, and padding are subtracted from the available space for flex entries.

So the calculation here is:

  1. Calculate the excess according to the real occupied space: 580+440-600=420
  2. The ratio is out of proportion, excluding the padding: 500×2:400×1, which is 5:2
  3. So the width of left is: 580-420×5/7 = 280, and the width of right is: 440-420×2/7 = 320, which is consistent with the actual situation.

Box-sizing: border-box

* {
		padding: 0;
		margin: 0;
	}
	.container {
		width: 600px;
		height: 300px;
		display: flex;
	}
	.left {
		width: 500px;
		padding: 40px;
		flex-shrink: 2;
		background: red;
		box-sizing: border-box;
	}
	.right {
		width: 400px;
		padding: 20px;
		flex-shrink: 1;
		background: blue;
		box-sizing: border-box;
	}
Copy the code

The actual effect is

left: 290px

right: 310px
Copy the code

When we set box-sizing: Border-box, also known as IE box model, the width of the box includes padding and border. If the width of the parent container is not considered, the space occupied by the left is still 500 and the space occupied by the right is 400. The left and right Spaces are 500-40×2=420 and 400-20×2=360 respectively, so the calculation is as follows:

  1. Calculate the excess and calculate it as the real occupied space: 500+400-600=300
  2. The ratio is out of proportion, excluding padding: 420×2:360×1, which is 7:3
  3. So the width of left is: 500-300×7/10 = 290, and the width of right is: 400-300×3/10 = 310, which is consistent with the actual situation.

conclusion

So let’s summarize the calculation

  1. Figure out the excess based on the actual footprint of the child (regardless of the width of the parent container)
  2. Calculate the allocation ratio of the excess portion according to the available space after subtracting margin, padding, border and flex reduction or magnification
  3. According to the reduction allocation ratio, the specific reduction pixel