兩個 <div>:.main (相對定位容器) 與 .cloud (絕對定位裝飾)。初期將 .cloud 放入 .main 內部,IE 無法正確顯示。
position: absolute 參考最近的**已定位祖先** (relative/absolute/fixed)。.cloud 在 .main 內,且 .main 為 relative,則 .cloud 相對 .main 定位,可能被 .main 的 overflow: hidden 或邊框裁切。hasLayout 與定位上下文有特殊 Bug。
/* HTML 結構:雙方同層,不嵌套 */
<div class="cloud"></div>
<div class="main">...</div>
/* CSS */
.main {
position: relative; /* 建立定位上下文 (可選) */
top: 30px;
width: 600px;
margin: 0 auto;
background: #fff;
border: 5px solid #f011;
}
.cloud {
position: absolute; /* 相對最近定位祖先 (若無則 body) */
top: 0;
right: 0;
width: 345px;
height: 171px;
background: url(../image/cloud.gif) no-repeat 100% 50%;
z-index: 1000; /* 確保疊在 .main 上方 */
}
核心原則:裝飾性絕對定位元素**盡量放在文檔流外部 (body 直屬)**,避免受容器 overflow、z-index 上下文影響。
$months = [1=>'1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'];
$days = range(1, 31);
$years = range(1930, date('Y'));
echo '<select name="year">';
foreach ($years as $y) {
$sel = ($y == 1987) ? ' selected' : '';
echo "<option value=\"$y\"$sel>$y 年</option>";
}
echo '</select>';
echo '<select name="month">';
foreach ($months as $k => $v) echo "<option value=\"$k\">$v</option>";
echo '</select>';
echo '<select name="day">';
foreach ($days as $d) echo "<option value=\"$d\">$d 日</option>";
echo '</select>';
**前端 JS 動態更新天數** (無需後端):
<script>
const ySel = document.querySelector('[name="year"]');
const mSel = document.querySelector('[name="month"]');
const dSel = document.querySelector('[name="day"]');
function updateDays() {
const y = +ySel.value, m = +mSel.value;
const days = new Date(y, m, 0).getDate(); // 下月 0 日 = 本月天數
dSel.innerHTML = '';
for (let d=1; d<=days; d++) {
dSel.add(new Option(d+'日', d));
}
}
ySel.addEventListener('change', updateDays);
mSel.addEventListener('change', updateDays);
updateDays(); // 初始化
</script>
function isValidDate(int $y, int $m, int $d): bool {
return checkdate($m, $d, $y); // 內建函數含閏年邏輯
}
checkdate() 驗證不可少。<input type="date"> (原生日期選擇器)、Flatpickr、Vue/React 日期組件。