It's because span is an inline element by default and padding top/bottom will not affect the height. If you want to set padding, just set span display: block. Reference: https://www.w3.org/TR/CSS2/visudet.html#inline-non-replaced
body {
margin: unset;
}
button, div {
display: block;
width: 100%;
justify-content: center;
align-items: center;
padding: 12px;
border: 1px solid black;
}
button span,
div span {
/* if button, div is set to display: block, their (parent) padding isn't factored in */
padding: 10px;
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div><span>div</span></div>
<button><span>button</span></button>
</body>
</html>
About display: flex behaviour:
The display value of a flex item is blockified: if the specified
display of an in-flow child of an element generating a flex container
is an inline-level value, it computes to its block-level equivalent.
(See CSS2.1§9.7 [CSS21] and CSS Display [CSS3-DISPLAY] for details on
this type of display value conversion.)
Reference: https://www.w3.org/TR/css-flexbox-1/#flex-containers