반응형

Select와 Option으로 사용 시 스타일링의 어려움이 있기 때문에 아래와 같이 ul 과 li로 구성 하였습니다.

 

HTML

<div class="dropdown">
    <div class="dropdown-selected">Select an option</div>
    <ul class="dropdown-options">
        <li data-value="1">Option 1</li>
        <li data-value="2">Option 2</li>
        <li data-value="3">Option 3</li>
        <li data-value="4">Option 4</li>
    </ul>
</div>

 

CSS (SASS)

.dropdown {
    position: relative;
    width: 250px;

    /* 선택된 항목 표시 */
    .dropdown-selected {
        padding: 5px;
        border: 1px solid #ccc;
        border-radius: 4px;
        background-color: #f9f9f9;
        cursor: pointer;
        font-size: 16px;
        color: #333;
    }

    /* 화살표 표시 */
    .dropdown-selected::after {
        content: "▼";
        position: absolute;
        top: 50%;
        right: 15px;
        transform: translateY(-50%);
        font-size: 12px;
        color: #333;
    }

    /* 옵션 목록 */
    .dropdown-options {
        display: block;
        list-style: none;
        margin: 0;
        padding: 0;
        position: absolute;
        width: 100%;
        border: 1px solid #ccc;
        background-color: #fff;
        z-index: 100;
        border-radius: 4px;
        max-height: 150px;
        overflow-y: auto;

        &.show {
            display: show;
        }

        /* 옵션 항목 */
        li {
            padding: 10px;
            cursor: pointer;

            /* 호버 및 선택된 항목 스타일 */
            &:hover{
                background-color: #007bff;
                color: #fff;
            }

            &.selected{
                background-color: #007bff;
                color: #fff;
            }
        }
    }
}

 

 

아래는 참고용으로 Vue로 Select Option을 제대로 이벤트 동작하게끔 하기 위해 정리합니다.

Vue

<div class="dropdown" ref="dropdown">
    <div class="dropdown-selected" @click="toggleDropdown">Select an option</div>
    <ul class="dropdown-options" v-if="isOpen">
        <li data-value="1" @click="selectOption(1)">Option 1</li>
        <li data-value="2" @click="selectOption(2)">Option 2</li>
        <li data-value="3" @click="selectOption(3)">Option 3</li>
        <li data-value="4" @click="selectOption(4)">Option 4</li>
    </ul>
</div>

export default{
	data() {
        return {
            isOpen:false
        }
    },
    methods: {
    	toggleDropdown() {
            this.isOpen = !this.isOpen;
        },
        selectOption(option) {
            this.selectedText = option.text;
            this.isOpen = false;
        },
        handleClickOutside(event) {
            // dropdown 외부 클릭 시 드롭다운 닫기
            if (!this.$refs.dropdown.contains(event.target)) {
                this.isOpen = false;
            }
        }
    },
    mounted() {
        document.addEventListener('click', this.handleClickOutside);
    },
    beforeDestroy() {
        document.removeEventListener('click', this.handleClickOutside);
    },    
}

 

반응형
<div class="loading-ispinner">
    <div class="ispinner ispinner-large">
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
        <div class="ispinner-blade"></div>
    </div>
</div>

 

/* Progress Bar (iSpinner) - 로딩 바 */
.loading{position: fixed;width: 100%;height: 100%;z-index: 12000;top: 0;left:0;background: rgba(0,0,0,.7);}
.ispinner {width: 52px;height: 52px;position: absolute;top: 50%;left: 50%;margin: -26px 0 0 -26px}
.ispinner .ispinner-blade {position: absolute;top: 37%;left: 44.5%;width: 10%;height: 25%;background-color: #fff;border-radius: 50%/20%;
    -webkit-animation: iSpinnerBlade 1s linear infinite;
            animation: iSpinnerBlade 1s linear infinite;
    will-change: opacity; 
}
.ispinner .ispinner-blade:nth-child(1) {
  -webkit-transform: rotate(30deg) translate(0, -150%);
          transform: rotate(30deg) translate(0, -150%);
  -webkit-animation-delay: -1.6666666667s;
          animation-delay: -1.6666666667s; }
.ispinner .ispinner-blade:nth-child(2) {
  -webkit-transform: rotate(60deg) translate(0, -150%);
          transform: rotate(60deg) translate(0, -150%);
  -webkit-animation-delay: -1.5833333333s;
          animation-delay: -1.5833333333s; }
.ispinner .ispinner-blade:nth-child(3) {
  -webkit-transform: rotate(90deg) translate(0, -150%);
          transform: rotate(90deg) translate(0, -150%);
  -webkit-animation-delay: -1.5s;
          animation-delay: -1.5s; }
.ispinner .ispinner-blade:nth-child(4) {
  -webkit-transform: rotate(120deg) translate(0, -150%);
          transform: rotate(120deg) translate(0, -150%);
  -webkit-animation-delay: -1.4166666667s;
          animation-delay: -1.4166666667s; }
.ispinner .ispinner-blade:nth-child(5) {
  -webkit-transform: rotate(150deg) translate(0, -150%);
          transform: rotate(150deg) translate(0, -150%);
  -webkit-animation-delay: -1.3333333333s;
          animation-delay: -1.3333333333s; }
.ispinner .ispinner-blade:nth-child(6) {
  -webkit-transform: rotate(180deg) translate(0, -150%);
          transform: rotate(180deg) translate(0, -150%);
  -webkit-animation-delay: -1.25s;
          animation-delay: -1.25s; }
.ispinner .ispinner-blade:nth-child(7) {
  -webkit-transform: rotate(210deg) translate(0, -150%);
          transform: rotate(210deg) translate(0, -150%);
  -webkit-animation-delay: -1.1666666667s;
          animation-delay: -1.1666666667s; }
.ispinner .ispinner-blade:nth-child(8) {
  -webkit-transform: rotate(240deg) translate(0, -150%);
          transform: rotate(240deg) translate(0, -150%);
  -webkit-animation-delay: -1.0833333333s;
          animation-delay: -1.0833333333s; }
.ispinner .ispinner-blade:nth-child(9) {
  -webkit-transform: rotate(270deg) translate(0, -150%);
          transform: rotate(270deg) translate(0, -150%);
  -webkit-animation-delay: -1s;
          animation-delay: -1s; }
.ispinner .ispinner-blade:nth-child(10) {
  -webkit-transform: rotate(300deg) translate(0, -150%);
          transform: rotate(300deg) translate(0, -150%);
  -webkit-animation-delay: -0.9166666667s;
          animation-delay: -0.9166666667s; }
.ispinner .ispinner-blade:nth-child(11) {
  -webkit-transform: rotate(330deg) translate(0, -150%);
          transform: rotate(330deg) translate(0, -150%);
  -webkit-animation-delay: -0.8333333333s;
          animation-delay: -0.8333333333s; }
.ispinner .ispinner-blade:nth-child(12) {
  -webkit-transform: rotate(360deg) translate(0, -150%);
          transform: rotate(360deg) translate(0, -150%);
  -webkit-animation-delay: -0.75s;
          animation-delay: -0.75s; }
.ispinner.ispinner-large {width: 50px;height: 50px; }
.ispinner.ispinner-large .ispinner-blade {
   width: 5.5714285714%;
   height: 25.7142857143%;
border-radius: 50%/16.67%; 
}
@-webkit-keyframes iSpinnerBlade {
  0% {opacity: 0.9;}
  50% {opacity: 0.25;}
  100% {opacity: 0.25;} 
}
@keyframes iSpinnerBlade {
  0% {opacity: 0.9;}
  50% {opacity: 0.25;}
  100% {opacity: 0.25;} 
}
/* Progress Bar - iSpinner */

 

반응형

CSS로만 사용하여 X 버튼을 만드려고 합니다. 아래와 같이 사용하면 됩니다.

 

HTML

<span className='btn_x'></span>

 

CSS

.btn_x {
			position: absolute;
			top: 20px;
			right: 40px;

			&:hover {
				&::before,
				&::after {
					background-color: #555;
				}
			}

			&::before,
			&::after {
				content: '';
				display: block;
				position: absolute;
				width: 3px;
				height: 25px;
				background-color: #999;
				cursor: pointer;
			}

			&::before {
				transform: rotate(45deg) translateX(0px);
			}

			&::after {
				transform: rotate(-45deg) translateX(0px);
			}
		}
	}
반응형

간편하게 레이어 팝업을 만들기 위해 소스 정리합니다.

 

html

<div class="layer-popup">
    <div class="layer-content">
    	<!-- contents-->
    </div>
</div>

 

style

.layer-popup{
        position: absolute;
        top:0;
        width:100%;
        height: 100%;
        background-color: rgba( 0, 0, 0, 0.5 );
        z-index: 9999;

	.layer-content{
            position: fixed;
            left: 0;
            top: 0;
            width: 90%; //Content 영역 조절)
            top : 50%;
            left : 50%;
            transform : translate(-50%, -50%);            
            z-index: 10000;  
            border-radius: 16px;

            /*style*/
            background: white;
            box-shadow: 0 0 6px 1px rgb(0 0 0 / 30%);
     }
}

 

Tailwind

<div class="layer-popup fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center">
    <div class="layer-content fixed bg-white shadow-md rounded-lg z-60 p-4 transform -translate-y-1/2">
        <div className="w-[300px]">
            데이터 보여주면 되는 부분?
        </div>
    </div>
</div>
반응형

모바일에서 Input 박스 클릭 시 가상키보드가 무조건적으로 뜨는데 foucs를 주면 뜨지않게 하기 위한 HTML 태그입니다.

 

Input 박스에 inputmode="none" 를 사용하면 가상 키보드가 뜨지 않습니다.

 

단, 계속 뜨지 않기 떄문에 복사 붙혀넣기 할때만 사용 하시는게 좋습니다.

반응형

카카오톡에서 URL을 입력 시 해당 사이트에 데이터들이 나오는데 그것들이 제대로 나오지 않는 경우가 있습니다.

 

아래의 데이터를 Head 태그 안에 넣어서 수정하고 카카오톡 사이트에 들어가서 캐시를 지워주면 바로 보실 수 있습니다.

<meta property="og:type" content="website" />
<meta property="og:title" content="타이틀" />
<meta property="og:image" content="사이트 시 이미지" />
<meta property="og:site_name" content="사이트 이름" />
<meta property="og:url" content="URL" />
<meta property="og:description" content="사이트 설명" />

 

카카오톡 캐시 지우는 사이트 링크 (로그인 필수)

https://developers.kakao.com/tool/clear/og

 

카카오계정 로그인

여기를 눌러 링크를 확인하세요.

accounts.kakao.com

 

 

반응형

오랜만에 작성하는 블로그 글입니다.

 

메일에서 pdf를 다운로드 받을 수 있게 A 태그를 사용하여 마크업을 만들고 

 

메일 내용에서 다운 받을 수 있게 하는 마크업을 만드려고 하였습니다.

 

하지만 pdf는 파일다운로드는 실패하였고 Viewer로만 나오게 하는 것만 성공 하였습니다.

 

해당 내용 관련하여 정리합니다.

 

 

결론 : 브라우저 정책 마다 다운로드 되기도 하고 안되기도 하고 한다.

정리 : https에서 http 사이트의 pdf 다운로드 하는게 목적

※브라우저※
IE : 가능
엣지 : 경고창으로 띄어주고 사용자가 직접 다운로드 받게 하였음.
크롬 : 정책상 불가능 (20년도 9월쯤 http에 pdf 파일을 다운로드 받는 것을 차단 시켜버림)
        ※ 참고 - https://blog.chromium.org/2020/02/protecting-users-from-insecure.html
파이어 폭스 : 가능

직접 다운로드는 불가능 하고 파일 다이렉트 경로를 a href에 지정하여 브라우저의 pdf 뷰어로 열게끔 하는것은 모든 브라우저가 가능하여 그렇게 작업 하였음.


반응형

table을 사용하다 보면 제목? table head 부분을 고정시키고 아래있는 Tbody (Table Body)부분은 스크롤을 만들어서 사용 하고 싶을 떄가 있습니다.

 

물론 CSS로 조지면 당연히 원하는대로 만들 수 있지만 빠르게 만들어야 하고 CSS도 많이 건들여야 하는 상황에서는 어떻게 해야될까요?

 

답은 아래에 있습니다.

 

slimScrollBar API를 사용하면 됩니다.

http://rocha.la/jQuery-slimScroll

 

jQuery slimScroll | rocha.la | JavaScript and my other hobbies

Lorem ipsum dolor sit amet, consectetur .... snip

rocha.la

https://github.com/rochal/jQuery-slimScroll

 

rochal/jQuery-slimScroll

small jQuery plugin that transforms any div into a scrollable area with a nice scrollbar. Demo and more: - rochal/jQuery-slimScroll

github.com

 

심플하게 사용해 볼까요?

아래의 HTML이 있습니다. 

Id는 SlimScrollBar를 위해 만들었습니다.

<div>
	<table>
    	<thead>
        	<tr>
            	<th>행고정</th>
                <th>행고정</th>
                <th>행고정</th>
                <th>행고정</th>
            </tr>
        </thead>
        <tbody id="slimScroll">
        	<tr>
            	<td>Test1<td>
                <td>Test1<td>
                <td>Test1<td>
                <td>Test1<td>
            </tr>
        </tbody>
    </table>

</div>

 

JavaScript

$('#slimScroll').slimScroll({  
  size : "5px", //스크롤 사이즈
  alwaysVisible: true //항상 보여줄 것인지  
})

 

이렇게 HTML을 만들고 JavaScript에 SlimScroll을 넣으면 그 해당 영역에는 스크롤이 얉게 생길 겁니다 ㅎ

이 것으로 테이블에 제목 행을 고정하고 내용에 스크롤이 들어가는 API 사용법을 알게 되었습니다.

 

직접 사이트에 들어가면 slimScroll의 속성들도 많이 있으니 한번정도 읽어보시는게 좋을 것 같습니다.

 

+ Recent posts