๊ฐœ๋ฐœ ๐Ÿพ/HTML,CSS

select ํƒœ๊ทธ ์ปค์Šคํ…€ ํ•˜๊ธฐ, ํ˜น์€ ์ง์ ‘ ๋งŒ๋“ค๊ธฐ (feat. javascript)

JOTOKKI 2021. 6. 18. 14:27
728x90

1. Select CSS Customizing 

 

Select ํƒœ๊ทธ์˜ ์™ธํ˜•์€ ์ฃผ๋กœ ๊ฐ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ •์˜ ํ•ฉ๋‹ˆ๋‹ค. 

Chrome ๊ณผ IE

๋ณด๋‹ค ์‹œํ”ผ ํฌ๋กฌ(์™ผ์ชฝ), IE(์˜ค๋ฅธ์ชฝ) ์ด ๋˜‘๊ฐ™์ด ๋ณด์ด๋ฉด์„œ๋„ ๋ฏธ์„ธ ํ•˜๊ฒŒ ๋‹ค๋ฆ„๋‹ˆ๋‹ค. 

๊ณตํ†ต์ ์œผ๋กœ ๋‘˜ ๋‹ค ๊ทธ๋ฆฌ ์˜ˆ์˜๊ฒŒ ์ƒ๊ธฐ์ง„ ์•Š์•˜์Šต๋‹ˆ๋‹ค. 

 

๊ฐ ํ”„๋กœ์ ํŠธ ๋ณ„๋กœ ์Šคํƒ€์ผ์— ๋งž๊ฒŒ css๋ฅผ ํ†ตํ•ด ์™ธํ˜•์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

์‚ฌ์ด์ฆˆ๋‚˜ ํฐํŠธ ์ปฌ๋Ÿฌ ๋“ฑ์€ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ผ๋ถ€ ์ œํ•œ์ ์œผ๋กœ ํ†ต์ œ๋˜๊ธฐ ๋•Œ๋ฌธ์— (ํ™”์‚ดํ‘œ ์ด๋ฏธ์ง€ ๋“ฑ) 

์•ฝ๊ฐ„์˜ ํŽธ๋ฒ•(?)์„ ํ†ตํ•˜์—ฌ ์™ธํ˜•์„ ๋ณ€๊ฒฝ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

 

1-1. Select ๊ธฐ๋ณธ ํ™”์‚ดํ‘œ ์—†์• ๊ธฐ

<select name="fruits" class="select">
  <option disabled selected>fruits ๐ŸŠ</option>
  <option value="apple">apple</option>
  <option value="orange">orange</option>
  <option value="grape">grape</option>
  <option value="melon">melon</option>
</select>
/* IE */
select::-ms-expand { 
	display: none;
}
.select {
  -o-appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

 

appearance none์„ ํ†ตํ•ด ํ™”์‚ดํ‘œ๋ฅผ ์—†์•จ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

๋‹จ, IE๋Š” select::expand ๋ฅผ ์—†์• ์•ผ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. 

 

1-2. select์— background ์ด๋ฏธ์ง€ ๋„ฃ๊ธฐ

์ดํ›„ select ์ž์ฒด์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ด๋ฏธ์ง€๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 

/* IE */
{ ... }
.select {
  { ... }
  width: 150px;
  height: 35px;
  background: url('https://freepikpsd.com/media/2019/10/down-arrow-icon-png-7-Transparent-Images.png') calc(100% - 5px) center no-repeat;
  background-size: 20px;
  padding: 5px 30px 5px 10px;
  border-radius: 4px;
  outline: 0 none;
}
.select option {
  background: black;
  color: #fff;
  padding: 3px 0;
}

์œ„์˜ ์†Œ์Šค๋ฅผ ๋ณด๋ฉด option ์—๋„ background์™€ color๋„ ์ปค์Šคํ…€์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

๊ฒฐ๊ณผ

select background ์ปค์Šคํ…€

 

1-3. select ์™€ ์ด๋ฏธ์ง€๋ฅผ ๋ถ„๋ฆฌํ•˜๊ธฐ 

๋‹จ์ˆœํžˆ ์™ธํ˜•๋งŒ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด ์œ„์˜ ๋ฐฉ๋ฒ•์ด ๋งˆํฌ์—…์ด ์ œ์ผ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. 

ํ•˜์ง€๋งŒ ์ข€ ๋” ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์˜ ๋ฒ”์œ„๋ฅผ ๋„“ํžˆ๊ณ  ์‹ถ๋‹ค๋ฉด ์•„์ด์ฝ˜๋งŒ ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. 

์˜ˆ๋ฅผ ๋“ค์–ด, select์— focus์‹œ ์•„์ด์ฝ˜์„ ํšŒ์ „ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

๋ฌผ๋ก  select๋ฅผ ํ•œ๋ฒˆ ๊ฐ์‹ธ๊ณ  ์ด๋ฏธ์ง€๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

<div class="selectBox">
  <select name="fruits" class="select">
    <option disabled selected>fruits ๐ŸŠ</option>
    <option value="apple">apple</option>
    <option value="orange">orange</option>
    <option value="grape">grape</option>
    <option value="melon">melon</option>
  </select>
  <span class="icoArrow"><img src="https://freepikpsd.com/media/2019/10/down-arrow-icon-png-7-Transparent-Images.png" alt=""></span>
</div>
.selectBox {
  position: relative;
  width: 150px;
  height: 35px;
  border-radius: 4px;
  border: 2px solid lightcoral;
}
.selectBox .select {
  width: inherit;
  height: inherit;
  background: transparent;
  border: 0 none;
  outline: 0 none;
  padding: 0 5px;
  position: relative;
  z-index: 3; // select๊ฐ€ ์œ„๋กœ ์˜ฌ๋ผ์™€์•ผ ํ•จ
}
.selectBox .select option {
  background: lightcoral;
  color: #fff;
  padding: 3px 0;
  font-size: 16px;
}
.selectBox .icoArrow {
  position: absolute; 
  top: 0; 
  right: 0; 
  z-index: 1; 
  width: 35px; 
  height: inherit;
  border-left: 2px solid lightcoral;
  display: flex;
  justify-content: center;
  align-items: center;
}

.selectBox .icoArrow img {
  width: 50%;
  transition: .3s; // ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ํšŒ์ „
}

.selectBox .select:focus + .icoArrow img {
  transform: rotate(180deg);
}

๊ฒฐ๊ณผ

ํ™”์‚ดํ‘œ ์•„์ด์ฝ˜ ๋ถ„๋ฆฌ

์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ๊ฒ ์ง€๋งŒ ๋” ๋งŽ์€ ์กฐ์ž‘๊ณผ ์ œํ•œ์ด ์žˆ๋Š” option์˜ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์„ ๋” ์ž์œ ๋กญ๊ฒŒ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, 

select ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. 

css๋ถ€ํ„ฐ script ๊นŒ์ง€ ์ง์ ‘ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€๋„ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

2. Select ์ง์ ‘ ๊ตฌ์ถ•

<div class="selectBox2 ">
  <button class="label">fruits ๐ŸŠ</button>
  <ul class="optionList">
    <li class="optionItem">apple</li>
    <li class="optionItem">orange</li>
    <li class="optionItem">grape</li>
    <li class="optionItem">melon</li>
  </ul>
</div>
.selectBox2 * { box-sizing: border-box; }
.selectBox2 {
  position: relative;
  width: 150px;
  height: 35px;
  border-radius: 4px;
  border: 2px solid lightcoral;
  background: url('https://freepikpsd.com/media/2019/10/down-arrow-icon-png-7-Transparent-Images.png') calc(100% - 7px) center no-repeat;
  background-size: 20px;
  cursor: pointer;
}

.selectBox2:after {
  content: '';
  display: block; 
  width: 2px;
  height: 100%; 
  position: absolute; 
  top: 0; 
  right: 35px;
  background: lightcoral;
}

.selectBox2 .label {
  display: flex;
  align-items: center;
  width: inherit;
  height: inherit;
  border: 0 none;
  outline: 0 none;
  padding-left: 15px;
  background: transparent;
  cursor: pointer;
}

.selectBox2 .optionList {
  position: absolute; 
  top: 28px;
  left: 0;
  width: 100%;
  background: lightcoral;
  color: #fff;
  list-style-type: none;
  padding: 0;
  border-radius: 6px;
  overflow: hidden;
  max-height: 0;
  transition: .3s ease-in;
}

.selectBox2.active .optionList {
  max-height: 500px;
}

.selectBox2 .optionItem {
  border-bottom: 1px dashed rgb(170, 72, 72);
  padding: 5px 15px 5px;
  transition: .1s;
}

.selectBox2 .optionItem:hover {
  background: rgb(175, 93, 93);
}

.selectBox2 .optionItem:last-child {
  border-bottom: 0 none;
}

// ์Šคํฌ๋กค ์ปค์Šคํ…€
.selectBox2 .optionList::-webkit-scrollbar {width: 6px;}
.selectBox2 .optionList::-webkit-scrollbar-track {background: transparent; }
.selectBox2 .optionList::-webkit-scrollbar-thumb {background: #303030; border-radius: 45px;}
.selectBox2 .optionList::-webkit-scrollbar-thumb:hover {background: #303030;}

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์•ž์„œ ์ปค์Šคํ…€ํ•œ select ํƒœ๊ทธ์™€ ์™ธํ˜•์ด ๊ฑฐ์˜ ๊ฐ™์•„์ง‘๋‹ˆ๋‹ค. 

๊ทธ๋ฆฌ๊ณ  select ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ผ๋งŒ ๋‚จ์•˜์Šต๋‹ˆ๋‹ค. 

* ๊ธฐ๋Šฅ 

1. ํด๋ฆญ์‹œ ์˜ต์…˜ ๋ชฉ๋ก์ด ์—ด๋ฆผ

2. ํ•œ๋ฒˆ ๋” ํด๋ฆญ์‹œ ์˜ต์…˜ ๋ชฉ๋ก์ด ๋‹ซํž˜

3. ์˜ต์…˜ ํด๋ฆญ์‹œ ์˜ต์…˜์˜ ํ…์ŠคํŠธ๊ฐ€ select ์•ˆ์œผ๋กœ ๋“ค์–ด๊ฐ€๋ฉด์„œ ์˜ต์…˜ ๋ชฉ๋ก์ด ๋‹ซํž˜

 

/* ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ */
const label = document.querySelector('.label');
const options = document.querySelectorAll('.optionItem');

// ํด๋ฆญํ•œ ์˜ต์…˜์˜ ํ…์ŠคํŠธ๋ฅผ ๋ผ๋ฒจ ์•ˆ์— ๋„ฃ์Œ
const handleSelect = (item) => {
  label.parentNode.classList.remove('active');
  label.innerHTML = item.textContent;
}
// ์˜ต์…˜ ํด๋ฆญ์‹œ ํด๋ฆญํ•œ ์˜ต์…˜์„ ๋„˜๊น€
options.forEach(option => {
	option.addEventListener('click', () => handleSelect(option))
})

// ๋ผ๋ฒจ์„ ํด๋ฆญ์‹œ ์˜ต์…˜ ๋ชฉ๋ก์ด ์—ด๋ฆผ/๋‹ซํž˜
label.addEventListener('click', () => {
  if(label.parentNode.classList.contains('active')) {
  	label.parentNode.classList.remove('active');
  } else {
  	label.parentNode.classList.add('active');
  }
})
/* ์ผ๋ฐ˜ํ•จ์ˆ˜ */
const label = document.querySelector('.label');
const options = document.querySelectorAll('.optionItem');
// ํด๋ฆญํ•œ ์˜ต์…˜์˜ ํ…์ŠคํŠธ๋ฅผ ๋ผ๋ฒจ ์•ˆ์— ๋„ฃ์Œ
const handleSelect = function(item) {
  label.innerHTML = item.textContent;
  label.parentNode.classList.remove('active');
}
// ์˜ต์…˜ ํด๋ฆญ์‹œ ํด๋ฆญํ•œ ์˜ต์…˜์„ ๋„˜๊น€
options.forEach(function(option){
  option.addEventListener('click', function(){handleSelect(option)})
})
// ๋ผ๋ฒจ์„ ํด๋ฆญ์‹œ ์˜ต์…˜ ๋ชฉ๋ก์ด ์—ด๋ฆผ/๋‹ซํž˜
label.addEventListener('click', function(){
  if(label.parentNode.classList.contains('active')) {
    label.parentNode.classList.remove('active');
  } else {
    label.parentNode.classList.add('active');
  }
});

๊ฒฐ๊ณผ

div๋กœ ๋งŒ๋“  select


 

์ปค์Šคํ…€๋œ ์…€๋ ‰ํŠธ ๋ฐ•์Šค๊ฐ€ ๊ฐœ์ˆ˜๋ฅผ ์•Œ ์ˆ˜ ์—†๋Š” ์—ฌ๋Ÿฌ๊ฐœ์ธ ๊ฒฝ์šฐ for๋ฌธ์œผ๋กœ ๊ฐ๊ฐ ํ•˜์œ„์˜ ๊ฐ’์„ ์ฐพ์•„์„œ ๋”ฐ๋กœ ๊ธฐ๋Šฅ์„

๋ถ™์—ฌ์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค! ์•„๋ž˜์— ์ฐธ๊ณ ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค. 

 

 

* ๋‹จ์ผ์ธ ๊ฒฝ์šฐ 

 

 

* ๋ฉ€ํ‹ฐ์ธ ๊ฒฝ์šฐ

 

 

 

๋ฐ˜์‘ํ˜•