2024.0415 업데이트 내용
- 디자인 수정
- 휴일 체크시 입력부분 Disable처리
- 버그 수정 및 코드 정리
------------------
다니는 회사가 자율 출퇴근이고 근무시간을 관리하는 HR이 있긴 하지만 조금 불편한 부분이 있어서 만들어보았다.
모바일 대응을 하긴 했는데 UX적으로 세로 스크롤이 길어지는 바람에 더 불편한 느낌이다. 나중에 개선을 좀 해야할것같고.
머 기본적으로 사용하는데는 문제는 없는것같다.
출근시간이 입력되어있고 퇴근시간이 입력되지 않은 첫번째 요일의 퇴근시간을 계산해 준다. 원래는 금요일 퇴근시간만 생각하고 만들었다가 금요일 휴일이면 어떻하지 하면서 개발이 수정되었다.
하루 기본 8시간 근무로 주 40시간을 채워야 하고, 하루 최대 근무 인정시간은 9시간으로 한시간을 누적시킬 수 있어서 금요일 전까지 최대 4시간을 누적시키면 (9+9+9+9) 36시간을 채울 수 있고 금요일은 4시간 근무만 하고 퇴근할 수 있다.
경우의 수가 좀 많다보니 코드가 아직은 완벽하지 않지만 조금씩 업데이트 해 나갈 생각이다.
index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>일주일 개인 근무시간 관리</title>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="style.css?v=0.0.9">
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<link rel="stylesheet" as="style" crossorigin
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/timepicker/jquery.timepicker.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/timepicker/jquery.timepicker.min.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div calss="content">
<div class="title-center">일주일 개인 근무시간 관리</div>
<div class="chart-container">
<canvas id="workTimeChart"></canvas>
<div class="total-remainning-time" id="total-remainning-time">
-
</div>
</div>
<div class="table-container">
<table id="workHoursTable">
<thead>
<tr>
<th class="table-title first">요일</th>
<th class="table-title second">출근 시간</th>
<th class="table-title third">퇴근 시간</th>
<th class="table-title forth">휴가 시간</th>
<th class="table-title fifth">휴일</th>
<th class="table-title sixth">근무 인정 시간(최대 9시간)</th>
<th class="table-title seventh">적립시간</th>
</tr>
</thead>
<tbody>
<!-- JavaScript를 통해 동적으로 행 추가 -->
</tbody>
</table>
</div>
<div class="action-container">
<button onclick="calculatedayExitTime()">퇴근 가능 시간 계산</button>
<button class="reset-all" onclick="resetAll()">모든 설정 리셋</button>
<div id="dayExitTime"></div>
</div>
<script src="script.js?v=0.0.9"></script>
</div>
</body>
</html>
script.js
const color1 = '#0ACFD9';
const color2 = '#F67777';
const color3 = '#666666';
const color4 = '#FFFFFF';
const color5 = '#f3f3f3';
const color6 = '#B068FF';
const color7 = '#F6F3FA';
const chartColor11 = '#C8A6F1'; // 휴일 색상
const chartColor22 = '#9CE4F1'; // 근무 인정 시간 색상
const chartColor33 = '#F7E58B'; // 휴가 시간 색상
const chartColor44 = '#F79999'; // 남은 시간 색상
let remainingMinutes;
window.onload = function () {
makeTable();
$('.timepicker-input').timepicker({
'scrollDefault': 'now',
'timeFormat': 'H:i A',
'step': 1,
'disableTimeRanges': [
['00:00 AM', '08:00 AM'],
['09:30 PM', '11:59 PM']
]
});
updateWorkHours();
};
// make chart
var ctx = document.getElementById('workTimeChart').getContext('2d');
var workTimeChart = new Chart(ctx, {
type: 'doughnut', // 원형 그래프 유형
data: {
labels: ['휴일', '근무 인정 시간', '휴가 시간', '남은 시간'],
datasets: [{
label: '근무 시간',
data: [0, 0, 0, 0], // 첫 번째 값은 인정된 근무 시간, 두 번째 값은 남은 근무 시간(40시간 중에서)
backgroundColor: [
chartColor11, // 휴일 색상
chartColor22, // 근무한 시간 색상
chartColor33,
chartColor44 // 남은 시간 색상
],
borderColor: [
color4,
color4,
color4,
color4
],
borderWidth: 0
}]
},
options: {
responsive: true, // 차트가 컨테이너 크기에 맞춰 조정.
plugins: {
legend: {
display: true, // 범례 표시 설정
position: 'bottom', // 범례의 위치
},
tooltip: { // Chart.js 3.x 이상에서는 tooltip을 사용
callbacks: {
label: function (context) {
let label = context.label || '';
if (label) {
label += ': ';
}
if (context.parsed !== undefined) {
const value = context.parsed;
label += formatMinutesAsHours(value);
}
return label;
}
}
}
}
}
});
function makeTable() {
const days = ['월', '화', '수', '목', '금'];
const titles = ['요일', '출근 시간', '퇴근 시간', '휴가 시간', '휴일 체크', '인정 시간(최대 9시간)', '적립시간'];
const tableBody = document.getElementById('workHoursTable').getElementsByTagName('tbody')[0];
days.forEach((day, index) => {
let row = tableBody.insertRow();
row.insertCell(0).innerText = day;
row.cells[0].setAttribute('data-title', titles[0]);
row.cells[0].classList.add('title');
row.cells[0].style.backgroundColor = color5;
row.cells[0].style.fontWeight = '700';
row.classList.add('day-row');
row.setAttribute('data-day', day);
for (let i = 1; i <= 6; i++) { // 셀 추가로 인덱스 6까지 확장
let cell = row.insertCell(i);
cell.setAttribute('data-title', titles[i]);
cell.classList.add('title');
cell.classList.add(day);
if (i < 3) { // 출근 시간과 퇴근 시간 입력란
let input = document.createElement('input');
input.type = 'text';
input.inputMode = 'numeric';
input.pattern = '[0-9]*';
input.className = 'timepicker-input';
if (i === 1) {
input.value = localStorage.getItem(`startTime${index + 1}`) || '';
}
if (i === 2) {
input.value = localStorage.getItem(`endTime${index + 1}`) || '';
}
let resetBtn = document.createElement('button');
resetBtn.className = 'btn item-reset';
resetBtn.textContent = 'R';
resetBtn.onclick = () => {
input.value = '';
updateWorkHours();
};
cell.appendChild(input);
cell.appendChild(resetBtn);
} else if (i === 3) { // 휴가 시간 선택
let select = document.createElement('select');
['없음', '2시간', '4시간'].forEach(option => {
let optionElement = document.createElement('option');
optionElement.value = option;
optionElement.textContent = option;
select.appendChild(optionElement);
});
select.value = localStorage.getItem(`vacationTime${index + 1}`) || '없음';
cell.appendChild(select);
} else if (i === 4) { // 휴일 체크박스
let label = document.createElement('label');
label.className = 'custom-checkbox';
let input = document.createElement('input');
input.type = 'checkbox';
input.checked = localStorage.getItem(`holiday${index + 1}`) === 'true';
let span = document.createElement('span');
label.appendChild(input);
label.appendChild(span);
cell.appendChild(label);
} else {
cell.innerText = ''; // 나머지 셀은 초기값 설정
}
}
});
}
function updateWorkHours() {
const { totalHolidayTime, totalAccumulatedMinutes, totalVacationMinutes } = calcTotalRequiredMinutesAndUpdateTable();
updateChart(totalAccumulatedMinutes - totalVacationMinutes, remainingMinutes, totalHolidayTime, totalVacationMinutes);
}
// update chart
function updateChart(completedTime, remainingTime, holidayTime, vacationTime) {
workTimeChart.data.datasets[0].data[0] = holidayTime;
workTimeChart.data.datasets[0].data[1] = completedTime;
workTimeChart.data.datasets[0].data[2] = vacationTime;
workTimeChart.data.datasets[0].data[3] = remainingTime;
workTimeChart.update();
var numColor = color2;
if (remainingMinutes > 0) {
numColor = color2
} else {
numColor = color1
}
document.getElementById('total-remainning-time').innerHTML =
'<div>잔여 근무시간' + '<span class="total-remainning-time-num" style="color: ' + numColor + '">' + formatMinutesAsHours(remainingMinutes) + '</span></div>'; // 잔여 근무 시간 업데이트
document.getElementById('dayExitTime').innerText = '';
}
// 잔여 근무 시간 계산
function calcTotalRequiredMinutesAndUpdateTable() {
const rows = document.getElementById('workHoursTable').rows;
let totalAccumulatedMinutes = 0;
// 휴일에 대해 빼줄 근무 시간 총합
let totalHolidayTime = 0;
let totalVacationMinutes = 0;
for (let i = 1; i < rows.length; i++) {
const isHoliday = rows[i].cells[4].children[0].children[0].checked;
rows[i].cells[0].style.color = color3;
rows[i].style.backgroundColor = color4;
if (isHoliday) {
// 휴일인 경우 전체 근무 시간에서 하루 8시간(480분)을 빼줌
totalHolidayTime += 8 * 60;
rows[i].cells[5].innerText = '휴일(8시간 제외)'; // 휴일인 경우 근무 시간을 '휴일'로 표시
rows[i].cells[5].style.color = color6;
rows[i].style.backgroundColor = color7;
rows[i].cells[1].children[0].style.backgroundColor = color7;
// rows[i].cells[1].children[0].value = '';
rows[i].cells[1].children[0].disabled = true;
rows[i].cells[2].children[0].style.backgroundColor = color7;
// rows[i].cells[2].children[0].value = '';
rows[i].cells[2].children[0].disabled = true;
rows[i].cells[3].children[0].style.backgroundColor = color7;
rows[i].cells[3].children[0].value = '없음';
rows[i].cells[3].children[0].disabled = true;
rows[i].cells[6].innerText = '';
rows[i].cells[0].style.color = color6;
// rows[i].cells[5].backgroundColor = color5;
continue;
}
rows[i].cells[1].children[0].style.backgroundColor = color4;
rows[i].cells[2].children[0].style.backgroundColor = color4;
rows[i].cells[3].children[0].style.backgroundColor = color4;
rows[i].cells[1].children[0].disabled = false;
rows[i].cells[2].children[0].disabled = false;
rows[i].cells[3].children[0].disabled = false;
const startTime = rows[i].cells[1].children[0].value;
const endTime = rows[i].cells[2].children[0].value;
const vacationTime = rows[i].cells[3].children[0].value;
let vacationMinutes = vacationTime === '없음' ? 0 : parseInt(vacationTime) * 60;
totalVacationMinutes += vacationMinutes;
let workMinutes = calculateWorkDuration(startTime, endTime);
// 근무 인정 시간에 휴가 시간 포함
workMinutes += vacationMinutes;
let dailyMaxWorkMinutes = Math.min(workMinutes, 9 * 60); // 하루 최대 근무 인정 시간 9시간으로 제한
totalAccumulatedMinutes += dailyMaxWorkMinutes; // 휴가 시간 포함하여 누적
let hours = Math.floor(dailyMaxWorkMinutes / 60);
let mins = dailyMaxWorkMinutes % 60;
rows[i].cells[5].innerText = (workMinutes > 0) ? `${pad(hours)}:${pad(mins)}` : ''; // 근무 인정 시간 업데이트
if (dailyMaxWorkMinutes < 480) {
if (dailyMaxWorkMinutes === 0) {
rows[i].cells[5].style.color = color3;
// rows[i].cells[5].style.backgroundColor = color4
} else {
rows[i].cells[5].style.color = color2;
if (dailyMaxWorkMinutes < 0) {
rows[i].cells[5].innerText = `출퇴근시간 AM/PM 확인`;
}
}
} else {
rows[i].cells[5].style.color = color1;
}
// 적립시간 표시
rows[i].cells[6].innerText = ''; // 리셋먼저...
if (i < rows.length && dailyMaxWorkMinutes !== 0) {
let addedTime = dailyMaxWorkMinutes - 480;
let isMinus = false;
if (addedTime < 0) {
isMinus = true;
addedTime *= -1;
}
let _hours = Math.floor(addedTime / 60);
let _mins = addedTime % 60;
if (isMinus) {
rows[i].cells[6].innerText = `-${pad(_hours)}:${pad(_mins)} 부족`;
rows[i].cells[6].style.color = color2;
} else {
if (addedTime === 0) {
rows[i].cells[6].style.color = color3;
rows[i].cells[6].innerText = '.';
} else {
rows[i].cells[6].innerText = `+${pad(_hours)}:${pad(_mins)} 적립`;
rows[i].cells[6].style.color = color1;
}
}
}
}
let totalRequiredMinutes = (40 * 60) - totalHolidayTime; // 주당 근무 시간에서 휴일 시간을 뺀 값
remainingMinutes = Math.max(0, totalRequiredMinutes - totalAccumulatedMinutes); // 음수 방지
return { totalHolidayTime, totalAccumulatedMinutes, totalVacationMinutes };
}
function calculateWorkDuration(startTime, endTime) {
const startMoment = moment(startTime, "HH:mm");
const endMoment = moment(endTime, "HH:mm");
let duration = 0;
if (startMoment.isValid() && endMoment.isValid()) {
duration = moment.duration(endMoment.diff(startMoment)).asMinutes();
// 점심 시간 체크
if (!endMoment.isBefore(moment('12:30', "HH:mm")) && !startMoment.isAfter(moment('13:30', "HH:mm"))) {
duration -= 60;
}
}
return duration;
}
function formatMinutesAsHours(minutes) {
let hours = Math.floor(minutes / 60);
let mins = minutes % 60;
return `${pad(hours)}:${pad(mins)}`;
}
function pad(number) {
return number < 10 ? '0' + number : number.toString();
}
function saveTimeToLocalStorage() {
const rows = document.getElementById('workHoursTable').rows;
for (let i = 1; i < rows.length; i++) {
const startTime = rows[i].cells[1].children[0].value;
const endTime = rows[i].cells[2].children[0].value;
const vacationTime = rows[i].cells[3].children[0].value;
const isHoliday = rows[i].cells[4].children[0].children[0].checked;
localStorage.setItem(`startTime${i}`, startTime);
localStorage.setItem(`endTime${i}`, endTime);
localStorage.setItem(`vacationTime${i}`, vacationTime);
localStorage.setItem(`holiday${i}`, isHoliday);
}
}
function resetAll() {
const rows = document.getElementById('workHoursTable').rows;
for (let i = 1; i < rows.length; i++) {
localStorage.removeItem(`startTime${i}`);
localStorage.removeItem(`endTime${i}`);
localStorage.removeItem(`vacationTime${i}`);
localStorage.removeItem(`holiday${i}`);
rows[i].cells[0].style.color = color3;
rows[i].cells[1].children[0].value = '';
rows[i].cells[2].children[0].value = '';
rows[i].cells[3].children[0].value = '없음';
rows[i].cells[4].children[0].children[0].checked = false;
rows[i].cells[5].innerText = '';
// rows[i].cells[5].style.backgroundColor = color4;
rows[i].style.backgroundColor = color4;
rows[i].cells[5].style.color = color3;
rows[i].cells[6].innerText = '';
rows[i].cells[1].children[0].style.backgroundColor = color4;
rows[i].cells[2].children[0].style.backgroundColor = color4;
rows[i].cells[3].children[0].style.backgroundColor = color4;
rows[i].cells[1].children[0].disabled = false;
rows[i].cells[2].children[0].disabled = false;
rows[i].cells[3].children[0].disabled = false;
}
remainingMinutes = 2400;
document.getElementById('total-remainning-time').innerHTML = '<div>잔여 근무시간' + '<span class="total-remainning-time-num" style="color: ' + color2 + '">' + formatMinutesAsHours(remainingMinutes) + '</span></div>';
document.getElementById('dayExitTime').innerText = '';
updateChart(0, 2400);
}
function calculatedayExitTime() {
var targetDayOfWeek = "";
const rows = document.getElementById('workHoursTable').rows;
let targetRow = null;
for (let i = 1; i < rows.length; i++) {
if (
rows[i].cells[2].children[0].value === '' &&
rows[i].cells[4].children[0].children[0].checked === false) {
targetRow = rows[i];
if (i === 1) {
targetDayOfWeek = "월요일";
} else if (i === 2) {
targetDayOfWeek = "화요일";
} else if (i === 3) {
targetDayOfWeek = "수요일";
} else if (i === 4) {
targetDayOfWeek = "목요일";
} else if (i === 5) {
targetDayOfWeek = "금요일";
}
break;
}
}
if (targetRow === null) {
alert(`퇴근시간이 궁금한 요일의 퇴근시간을 비워주세요.`);
return;
}
const startTime = targetRow.cells[1].children[0].value; // 출근 시간
if (!startTime) {
alert(`${targetDayOfWeek}의 출근 시간을 입력해주세요.`);
return;
}
let remainingTotalMinutes = remainingMinutes;// (remainingHours * 60) + remainingMinutes;
const targetdayStartMoment = moment(startTime, "HH:mm");
const lunchStart = moment('12:30', "HH:mm");
const lunchEnd = moment('13:30', "HH:mm");
// 출근 시간과 남은 근무 시간을 기준으로 초기 퇴근 시간을 계산
let tentativeTargetdayExitMoment = targetdayStartMoment.clone().add(remainingTotalMinutes, 'minutes');
let isLaunchTime = false;
// 점심시간이 근무 시간에 포함되어 있는지 확인 후 조정
if (targetdayStartMoment.isBefore(lunchEnd) && tentativeTargetdayExitMoment.isAfter(lunchStart)) {
// 점심시간이 포함되어 있으면, 퇴근 시간을 60분 연장
remainingTotalMinutes += 60;
isLaunchTime = true;
}
// 금요일이 아닌경우 휴가가 포함되어있으면 휴가시간 제외
if (targetDayOfWeek !== "금요일") {
const vacationTime = targetRow.cells[3].children[0].value;
let vacationMinutes = vacationTime === '없음' ? 0 : parseInt(vacationTime) * 60;
remainingTotalMinutes -= vacationMinutes;
}
// 조정된 근무 시간으로 최종 퇴근 시간 계산
const targetdayExitMoment = targetdayStartMoment.clone().add(remainingTotalMinutes, 'minutes');
// 퇴근 시간을 AM/PM 포맷으로 출력
const exitTimeFormatted = targetdayExitMoment.format("hh:mm A");
let remainingTimeFormatted = formatMinutesAsHours(remainingTotalMinutes);
const vacationTime = targetRow.cells[3].children[0].value;
let checkVacationMinutes = vacationTime === '없음' ? 0 : parseInt(vacationTime) * 60;
let checkRemainingTotalMinutes = remainingTotalMinutes + checkVacationMinutes;
if (checkRemainingTotalMinutes / 60 > 10) {
let overWorkTime = checkRemainingTotalMinutes - 540 - 60;
let overWorkTimeFormatted = formatMinutesAsHours(overWorkTime);
const targetdayOverExitMoment = targetdayStartMoment.clone().add(remainingTotalMinutes - overWorkTime, 'minutes');
const exitOverTimeFormatted = targetdayOverExitMoment.format("hh:mm A");
document.getElementById('dayExitTime').innerHTML = `<span class="dayExitTimeNormal">${targetDayOfWeek} 근무시간을 최대한 채울 수 있는 시간(9시간)인 </span>${exitOverTimeFormatted}<span class="dayExitTimeNormal">에 퇴근하면</span><br />
<span class="dayExitTimeNormal">남은 총 근무시간은</span> <span class="dayExitTimeAlert">${overWorkTimeFormatted}</span> <span class="dayExitTimeNormal">입니다.</span>`
} else {
document.getElementById('dayExitTime').innerHTML
= `<span class="dayExitTimeNormal">남은 근무시간은 ${isLaunchTime ? "휴게시간 포함</span>" : "</span>"} ${remainingTimeFormatted} <br />
<span class="dayExitTimeNormal">${targetDayOfWeek} 퇴근은</span> ${exitTimeFormatted} <span class="dayExitTimeNormal">이후부터 가능해요.</span>`;
}
}
document.getElementById('workHoursTable').addEventListener('change', (event) => {
updateWorkHours();
saveTimeToLocalStorage();
});
style.css
html,
body {
margin: 20px;
padding: 0px;
min-height: calc(100%-40px);
font-family: 'Pretendard Variable', 'Apple SD Gothic Neo', sans-serif;
font-size: 16px;
font-weight: 400;
line-height: 1.5;
color: #666666;
text-size-adjust: 100%;
overflow-x: hidden;
overflow-y: auto;
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
table,
th,
td {
border: 1px solid #dfdfdf;
}
th,
td {
padding: 10px;
text-align: center;
word-wrap: break-word;
}
.table-title {
background-color: #f3f3f3;
width: auto;
}
.first {
width: 40px;
}
.second {
width: 100px;
}
.third {
width: 100px;
}
.forth {
width: 60px;
}
.fifth {
width: 50px;
}
.sixth {
width: 180px;
}
.seventh {
width: 150px;
}
.chart-container {
position: relative;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
/* height: 100vh; */
}
canvas {
position: relative;
max-width: auto;
max-height: 300px;
margin-bottom: 40px;
z-index: 100;
}
.total-remainning-time {
position: absolute;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
z-index: 0;
top: -40px;
left: 0px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
pointer-events: none;
}
.total-remainning-time-num {
font-weight: 900;
display: block;
font-size: 20px;
}
button {
margin: 10px 5px;
padding: 10px 20px;
font-size: 1rem;
cursor: pointer;
border: none;
background-color: #0ACFD9;
color: #ffffff;
border-radius: 10px;
transition: background-color 0.3s ease;
}
.reset-all {
background-color: #898989;
}
.item-reset {
position: relative;
font-size: 0.7rem;
width: 20px;
height: 20px;
text-align: center;
border-radius: 10px;
margin: 0px;
padding: 0px;
background-color: #d2d2d2;
}
.table-container {
width: 100%;
overflow-x: auto;
}
.action-container {
text-align: center;
margin-top: 40px;
margin-bottom: 40px;
}
button:hover {
background-color: #18aab1;
}
.item-reset:hover,
.reset-all:hover {
background-color: #7d7d7d;
}
#dayExitTime {
margin-top: 20px;
font-size: 14px;
font-weight: 400;
color: #0ACFD9;
}
.dayExitTimeNormal {
color: #6f6f6f;
font-weight: 200;
}
.dayExitTimeAlert {
color: #EF6D81;
font-weight: 400;
}
.title-center {
font-weight: 900;
font-size: 3rem;
text-align: center;
margin-top: 20px;
margin-bottom: 20px;
color: #3f3f3f;
}
input[type="text"] {
padding: 5px 5px 5px 5px;
border-radius: 5px;
border: 1px solid #d4d4d4;
color: #777777;
background-color: #ffffff;
width: 80px;
margin-right: 10px;
}
select {
padding: 5px 5px 5px 5px;
border-radius: 5px;
border: 1px solid #d4d4d4;
color: #777777;
background-color: #ffffff;
text-align: center;
}
.custom-checkbox input {
display: none;
}
/* 커스텀 디자인 */
.custom-checkbox span {
height: 18px;
width: 18px;
background-color: #ffffff;
display: inline-block;
position: relative;
border-radius: 5px;
border: 1px solid #d4d4d4;
}
/* 체크된 상태의 스타일 */
.custom-checkbox input:checked+span {
background-color: #DCBCFF;
border: 1px solid #B068FF;
}
.custom-checkbox input:checked+span:after {
content: "";
position: absolute;
left: 7px;
top: 3px;
width: 3px;
height: 8px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
@media screen and (max-width: 1100px) {
html,
body {
margin: 10px;
font-size: 14px;
line-height: 1.3;
min-height: calc(100%-20px);
}
.title-center {
font-size: 2.5rem;
text-align: center;
margin-top: 0px;
margin-bottom: 20px;
}
th,
td {
padding: 10px 0px 10px 0px;
}
}
@media screen and (max-width: 935px) {
th,
td {
padding: 10px 0px 10px 0px;
}
input[type="text"],
select {
width: 60px;
transform: scale(0.9);
}
input[type="checkbox"] {
transform: scale(1.3);
}
}
@media screen and (max-width: 784px) {
table,
thead,
tbody,
th,
td,
tr {
display: block;
width: 100%;
border: 0px;
}
.title-center {
font-size: 2.5rem;
text-align: center;
margin-top: 0px;
margin-bottom: 20px;
}
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
border: 0px;
}
tr {
border: 1px solid #ccc;
border-radius: 0px;
margin-bottom: 20px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
width: calc(100% - 2px);
}
td {
position: relative;
align-items: flex-start;
justify-content: center;
border: none;
border-bottom: 1px solid #dedede;
/* padding: 10px; */
padding: 10px 10px 10px 10px;
padding-left: calc(28% + 30px);
text-align: right;
white-space: normal;
height: 22px;
width: auto;
margin: 0px;
}
td:last-child {
border-bottom: none;
}
td:before {
position: absolute;
top: 0;
left: 0;
width: 28%;
height: 22px;
padding: 10px;
content: attr(data-title);
font-weight: bold;
font-size: 14px;
color: #666666;
background-color: #f3f3f3;
text-align: right;
}
input[type="text"],
select {
margin: 0px;
padding: 4Px;
transform: scale(1);
margin-right: 10px;
width: auto;
/* max-width: 100%; */
}
select {
transform: scale(1);
/* padding: 5px 5px 5px 5px; */
border-radius: 5px;
border: 1px solid #d4d4d4;
color: #777777;
background-color: #ffffff;
margin: 0px;
padding: 4Px;
/* text-align: center; */
/* margin: 0px; */
}
input[type="checkbox"] {
transform: scale(1.3);
margin: 0px;
/* margin-right: 5px; */
color: #777777;
margin: 0px;
padding: 4Px;
}
}
@media screen and (max-width: 510px) {
html,
body {
margin: 10px;
font-size: 14px;
min-height: calc(100%-20px);
}
.title-center {
font-size: 2rem;
text-align: center;
}
.action-container,
.title-center,
#dayExitTime {
margin-top: 15px;
margin-bottom: 15px;
}
td {
font-size: 12px;
padding-left: calc(40% + 30px);
height: 18px;
}
td:before {
width: 40%;
font-size: 12px;
height: 18px;
}
input[type="text"],
select {
max-width: 60%;
padding: 4px;
font-size: 12px;
}
button {
font-size: 0.8rem;
font-size: 14px;
}
.item-reset {
padding: 0px 0px;
font-size: 0.8rem;
font-size: 12px;
}
}
@media screen and (max-width: 309px) {
.total-remainning-time {
top: -50px;
font-size: 10px;
}
.total-remainning-time-num {
font-size: 18px;
}
}