본문 바로가기

CSS

[#. CSS] Canlendar UI(HTML5 + CSS + JS) 달력 UI

반응형

 

 

 

 

 

 

HTML에서 달력을 구현하기 위해

보기에 깔끔하고 코드도 깔끔한 UI 라이브러리를 서치하게 됐다

 

 

 

 

 

 

① 

 

https://codepen.io/B8bop/pen/GhCAb

 

Calendar

Calendar I made for a little project....

codepen.io

 

 

 

 

 

⑴ HTML

 

<head>
  <link href='https://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
</head>
<body>
  <div id="calendar">
    <div id="calendar_header"><i class="icon-chevron-left"></i>          <h1></h1><i class="icon-chevron-right"></i>         </div>
    <div id="calendar_weekdays"></div>
    <div id="calendar_content"></div>
  </div>
</body>

 

 

 

 

⑵ CSS

 

body{
  background-color: #F5F1E9;
}
#calendar{
  margin-left: auto;
  margin-right: auto;
  width: 320px;
  font-family: 'Lato', sans-serif;
}
#calendar_weekdays div{
  display:inline-block;
  vertical-align:top;
}
#calendar_content, #calendar_weekdays, #calendar_header{
  position: relative;
  width: 320px;
  overflow: hidden;
  float: left;
  z-index: 10;
}
#calendar_weekdays div, #calendar_content div{
  width:40px;
  height: 40px;
  overflow: hidden;
  text-align: center;
  background-color: #FFFFFF;
  color: #787878;
}
#calendar_content{
  -webkit-border-radius: 0px 0px 12px 12px;
  -moz-border-radius: 0px 0px 12px 12px; 
  border-radius: 0px 0px 12px 12px;
}
#calendar_content div{
  float: left;
}
#calendar_content div:hover{
  background-color: #F8F8F8;
}
#calendar_content div.blank{
  background-color: #E8E8E8;
}
#calendar_header, #calendar_content div.today{
  zoom: 1;
  filter: alpha(opacity=70);
  opacity: 0.7;
}
#calendar_content div.today{
  color: #FFFFFF;
}
#calendar_header{
  width: 100%;
  height: 37px;
  text-align: center;
  background-color: #FF6860;
  padding: 18px 0;
  -webkit-border-radius: 12px 12px 0px 0px;
  -moz-border-radius: 12px 12px 0px 0px; 
  border-radius: 12px 12px 0px 0px;
}
#calendar_header h1{
  font-size: 1.5em;
  color: #FFFFFF;
  float:left;
  width:70%;
}
i[class^=icon-chevron]{
  color: #FFFFFF;
  float: left;
  width:15%;
  border-radius: 50%;
}

 

 

 

 

⑶ JS

 

$(function(){function c(){p();var e=h();var r=0;var u=false;l.empty();while(!u){if(s[r]==e[0].weekday){u=true}else{l.append('<div class="blank"></div>');r++}}for(var c=0;c<42-r;c++){if(c>=e.length){l.append('<div class="blank"></div>')}else{var v=e[c].day;var m=g(new Date(t,n-1,v))?'<div class="today">':"<div>";l.append(m+""+v+"</div>")}}var y=o[n-1];a.css("background-color",y).find("h1").text(i[n-1]+" "+t);f.find("div").css("color",y);l.find(".today").css("background-color",y);d()}function h(){var e=[];for(var r=1;r<v(t,n)+1;r++){e.push({day:r,weekday:s[m(t,n,r)]})}return e}function p(){f.empty();for(var e=0;e<7;e++){f.append("<div>"+s[e].substring(0,3)+"</div>")}}function d(){var t;var n=$("#calendar").css("width",e+"px");n.find(t="#calendar_weekdays, #calendar_content").css("width",e+"px").find("div").css({width:e/7+"px",height:e/7+"px","line-height":e/7+"px"});n.find("#calendar_header").css({height:e*(1/7)+"px"}).find('i[class^="icon-chevron"]').css("line-height",e*(1/7)+"px")}function v(e,t){return(new Date(e,t,0)).getDate()}function m(e,t,n){return(new Date(e,t-1,n)).getDay()}function g(e){return y(new Date)==y(e)}function y(e){return e.getFullYear()+"/"+(e.getMonth()+1)+"/"+e.getDate()}function b(){var e=new Date;t=e.getFullYear();n=e.getMonth()+1}var e=480;var t=2013;var n=9;var r=[];var i=["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"];var s=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var o=["#16a085","#1abc9c","#c0392b","#27ae60","#FF6860","#f39c12","#f1c40f","#e67e22","#2ecc71","#e74c3c","#d35400","#2c3e50"];var u=$("#calendar");var a=u.find("#calendar_header");var f=u.find("#calendar_weekdays");var l=u.find("#calendar_content");b();c();a.find('i[class^="icon-chevron"]').on("click",function(){var e=$(this);var r=function(e){n=e=="next"?n+1:n-1;if(n<1){n=12;t--}else if(n>12){n=1;t++}c()};if(e.attr("class").indexOf("left")!=-1){r("previous")}else{r("next")}})})

 

 

 

 

 

See the Pen Calendar by B8bop (@B8bop) on CodePen.

 

 

 

 

 

 

https://codepen.io/joshbader/pen/LYYdGdB

 

Calendar UI

In issue 171 of the CSS-Tricks Newsletter (https://css-tricks.com/newsletter/171/), Robin explains how he likes to ask interviewers to recreate a calen...

codepen.io

 

 

 

 

 

⑴ HTML

 

<div class="calendar-wrap">
  <h2 class="month-year">January 2020</h2>

  <table class="calendar">
    <thead>
      <tr>
        <th class="day-title" scope="col">Sun</th>
        <th class="day-title" scope="col">Mon</th>
        <th class="day-title" scope="col">Tue</th>
        <th class="day-title" scope="col">Wed</th>
        <th class="day-title" scope="col">Thu</th>
        <th class="day-title" scope="col">Fri</th>
        <th class="day-title" scope="col">Sat</th>
      </tr>
    </thead>
    <tbody>
      <tr class="week">
        
        <td class="day prev-mon" tabindex="0"><span class="day-number">29</span></td>
        <td class="day prev-mon" tabindex="0"><span class="day-number">30</span></td>
        <td class="day prev-mon" tabindex="0"><span class="day-number">31</span></td>
        <td class="day" tabindex="0"><span class="day-number">1</span></td>
        <td class="day today" tabindex="0"><span class="day-number">2</span></td>
        <td class="day" tabindex="0"><span class="day-number">3</span></td>
        <td class="day" tabindex="0"><span class="day-number">4</span></td>
      </tr>
      <tr class="week">
        <td class="day" tabindex="0"><span class="day-number">5</span></td>
        <td class="day" tabindex="0"><span class="day-number">6</span></td>
        <td class="day" tabindex="0"><span class="day-number">7</span></td>
        <td class="day" tabindex="0"><span class="day-number">8</span></td>
        <td class="day" tabindex="0"><span class="day-number">9</span></td>
        <td class="day" tabindex="0"><span class="day-number">10</span></td>
        <td class="day" tabindex="0"><span class="day-number">11</span></td>
      </tr>
      <tr class="week">
        <td class="day" tabindex="0"><span class="day-number">12</span></td>
        <td class="day" tabindex="0"><span class="day-number">13</span></td>
        <td class="day" tabindex="0"><span class="day-number">14</span></td>
        <td class="day" tabindex="0"><span class="day-number">15</span></td>
        <td class="day" tabindex="0"><span class="day-number">16</span></td>
        <td class="day" tabindex="0"><span class="day-number">17</span></td>
        <td class="day" tabindex="0"><span class="day-number">18</span></td>
      </tr>
      <tr class="week">
        <td class="day" tabindex="0"><span class="day-number">19</span></td>
        <td class="day" tabindex="0"><span class="day-number">20</span></td>
        <td class="day" tabindex="0"><span class="day-number">21</span></td>
        <td class="day" tabindex="0"><span class="day-number">22</span></td>
        <td class="day" tabindex="0"><span class="day-number">23</span></td>
        <td class="day" tabindex="0"><span class="day-number">24</span></td>
        <td class="day" tabindex="0"><span class="day-number">25</span></td>
      </tr>
      <tr class="week">
        <td class="day" tabindex="0"><span class="day-number">26</span></td>
        <td class="day" tabindex="0"><span class="day-number">27</span></td>
        <td class="day" tabindex="0"><span class="day-number">28</span></td>
        <td class="day" tabindex="0"><span class="day-number">29</span></td>
        <td class="day" tabindex="0"><span class="day-number">30</span></td>
        <td class="day" tabindex="0"><span class="day-number">31</span></td>
        <td class="day next-mon" tabindex="0"><span class="day-number">1</span></td>
      </tr>
    </tbody>
  </table>
  
  <a class="button reset">Clear date-range</a>
</div>

 

 

 

 

⑵ CSS

 

*,
*::before,
*::after {
  padding: 0;
  margin: 0;
  box-sizing: border-box
}

body {
  display: flex;
  min-height: 100vh;
  padding: 5vh 5vw;
  color: #37474f;
  line-height: 1.5;
  font-family: Lato, sans-serif;
  background-color: #cfd8dc;
}

.note {
  font-size: calc(0.5vw + 0.75rem);
  text-align: center;
  opacity: 0.5;
}

.button {
  display: inline-block;
  padding: 0.5em 1em;
  color: #fff;
  font-weight: bold;
  font-size: 0.6875em;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.0625em;
  background-color: #37474F;
  border-radius: 1.5em;
  cursor: pointer;
}

.calendar-wrap {
  width: 100%;
  padding: 0.75em;
  margin: auto;
  font-size: 4vw;
  background-color: #fff;
  border-radius: 1.5em;
  user-select: none;
  box-shadow:
    0 0.0625em 0.25em rgba(0,20,50,0.2),
    0 0.5em 0.5em 0.125em rgba(0,20,50,0.1);
}

@media (min-width: 500px) {
  .calendar-wrap {
    width: 450px;
    font-size: 1.25rem;
  }
}

.month-year {
  margin-bottom: 0.75em;
  font-weight: normal;
  font-size: 1.25em;
  text-align: center;
}

.calendar {
  table-layout: fixed;
  width: 100%;
  margin-bottom: 0.75em;
  overflow: hidden;
  border-collapse: collapse;
  -webkit-tap-highlight-color: transparent;
}

.day-title {
  width: 4em;
  height: 4em;
  vertical-align: top;
  font-weight: bold;
  font-size: 0.75em;
  text-transform: uppercase;
  letter-spacing: 0.0625em;
  box-shadow:
    inset 0 -0.875em #fff,
    inset 0 -1em rgba(0,20,50,0.1);
}

.day {
  position: relative;
  height: 3em;
}

.day:focus {
  outline: none;
}

.day:focus .day-number::after {
  content: '';
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  width: 80%;
  height: 80%;
  transform: translate(-50%,-50%);
  border: 0.25em solid #0288d1;
  border-radius: 50%;
}

.day.active-a:focus .day-number::after,
.day.active-b:focus .day-number::after {
  width: 100%;
  height: 100%;
}

.day.today:focus .day-number::after {
  width: 102%;
  height: 102%;
}

.day:hover span.day-number {
  color: #0288d1;
}

.day:first-child,
.day:last-child {
  color: rgba(0,0,0,0.5);
}

.day.range {
  color: #0288d1;
  background-color: #e1f5fe;
}

.day.range.active-a,
.day:not(.range) + .day.range.active-b {
  background-color: transparent;
  box-shadow: inset -1.5em 0 #e1f5fe;
}

.day.range.active-b,
.day.range + .day.range.active-a {
  background-color: transparent;
  box-shadow: inset 1.5em 0 #e1f5fe;
}

.day.range.active-a:first-child,
.day.range.active-b:first-child {
  box-shadow: none;
}

.day.range.active-a:first-child + .day.range,
.day.range.active-b:first-child + .day.range {
  box-shadow: -1.5em 0 #e1f5fe;
}

.day.range.active-a:first-child + .day:not(.range),
.day.range.active-b:first-child + .day:not(.range) {
  box-shadow: -4.5em 0 #e1f5fe;
}

.day.range.active-a:first-child + .day.range.active-b {
  box-shadow:
    -1.5em 0 #e1f5fe,
    inset 1.5em 0 #e1f5fe;
}

.day-number {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 3em;
  border-radius: 50%;
}

.day.active-a span.day-number,
.day.active-b span.day-number {
  color: #fff;
  background-color: #03A9F4;
}

.day.prev-mon .day-number,
.day.next-mon .day-number {
  color: rgba(0,0,0,0.3);
}

.day.prev-mon[class*="active"] .day-number,
.day.next-mon[class*="active"] .day-number {
  color: rgba(255,255,255,0.5);
  background-color: #81D4FA;
}

.day.today span.day-number {
  color: #fff;
  border: 0.25em solid transparent;
  box-shadow: inset 0 0 0 2em #37474F;
}

.calendar-wrap .reset {
  display: block;
}

 

 

 

 

⑶ JS

 

*,
*::before,
*::after {
  padding: 0;
  margin: 0;
  box-sizing: border-box
}

body {
  display: flex;
  min-height: 100vh;
  padding: 5vh 5vw;
  color: #37474f;
  line-height: 1.5;
  font-family: Lato, sans-serif;
  background-color: #cfd8dc;
}

.note {
  font-size: calc(0.5vw + 0.75rem);
  text-align: center;
  opacity: 0.5;
}

.button {
  display: inline-block;
  padding: 0.5em 1em;
  color: #fff;
  font-weight: bold;
  font-size: 0.6875em;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.0625em;
  background-color: #37474F;
  border-radius: 1.5em;
  cursor: pointer;
}

.calendar-wrap {
  width: 100%;
  padding: 0.75em;
  margin: auto;
  font-size: 4vw;
  background-color: #fff;
  border-radius: 1.5em;
  user-select: none;
  box-shadow:
    0 0.0625em 0.25em rgba(0,20,50,0.2),
    0 0.5em 0.5em 0.125em rgba(0,20,50,0.1);
}

@media (min-width: 500px) {
  .calendar-wrap {
    width: 450px;
    font-size: 1.25rem;
  }
}

.month-year {
  margin-bottom: 0.75em;
  font-weight: normal;
  font-size: 1.25em;
  text-align: center;
}

.calendar {
  table-layout: fixed;
  width: 100%;
  margin-bottom: 0.75em;
  overflow: hidden;
  border-collapse: collapse;
  -webkit-tap-highlight-color: transparent;
}

.day-title {
  width: 4em;
  height: 4em;
  vertical-align: top;
  font-weight: bold;
  font-size: 0.75em;
  text-transform: uppercase;
  letter-spacing: 0.0625em;
  box-shadow:
    inset 0 -0.875em #fff,
    inset 0 -1em rgba(0,20,50,0.1);
}

.day {
  position: relative;
  height: 3em;
}

.day:focus {
  outline: none;
}

.day:focus .day-number::after {
  content: '';
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  width: 80%;
  height: 80%;
  transform: translate(-50%,-50%);
  border: 0.25em solid #0288d1;
  border-radius: 50%;
}

.day.active-a:focus .day-number::after,
.day.active-b:focus .day-number::after {
  width: 100%;
  height: 100%;
}

.day.today:focus .day-number::after {
  width: 102%;
  height: 102%;
}

.day:hover span.day-number {
  color: #0288d1;
}

.day:first-child,
.day:last-child {
  color: rgba(0,0,0,0.5);
}

.day.range {
  color: #0288d1;
  background-color: #e1f5fe;
}

.day.range.active-a,
.day:not(.range) + .day.range.active-b {
  background-color: transparent;
  box-shadow: inset -1.5em 0 #e1f5fe;
}

.day.range.active-b,
.day.range + .day.range.active-a {
  background-color: transparent;
  box-shadow: inset 1.5em 0 #e1f5fe;
}

.day.range.active-a:first-child,
.day.range.active-b:first-child {
  box-shadow: none;
}

.day.range.active-a:first-child + .day.range,
.day.range.active-b:first-child + .day.range {
  box-shadow: -1.5em 0 #e1f5fe;
}

.day.range.active-a:first-child + .day:not(.range),
.day.range.active-b:first-child + .day:not(.range) {
  box-shadow: -4.5em 0 #e1f5fe;
}

.day.range.active-a:first-child + .day.range.active-b {
  box-shadow:
    -1.5em 0 #e1f5fe,
    inset 1.5em 0 #e1f5fe;
}

.day-number {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 3em;
  border-radius: 50%;
}

.day.active-a span.day-number,
.day.active-b span.day-number {
  color: #fff;
  background-color: #03A9F4;
}

.day.prev-mon .day-number,
.day.next-mon .day-number {
  color: rgba(0,0,0,0.3);
}

.day.prev-mon[class*="active"] .day-number,
.day.next-mon[class*="active"] .day-number {
  color: rgba(255,255,255,0.5);
  background-color: #81D4FA;
}

.day.today span.day-number {
  color: #fff;
  border: 0.25em solid transparent;
  box-shadow: inset 0 0 0 2em #37474F;
}

.calendar-wrap .reset {
  display: block;
}

 

 

 

 

 

See the Pen Calendar UI by Josh Bader (@joshbader) on CodePen.

 

 

 

 

 

 

둘 중 사용하기에 ①이 적합해서 ①을 사용했다

사용하려는 캘린더 기능에 적합한 것으로 골라서 사용하면 된다

 

 

 

 

 

반응형