마우스 오버 시 이미지 변화, 제이쿼리와 js 모두 사용할 수 있다. 

 

혹시 코드를 짜다가 다음과 같은 오류가 발생했다면 참고하고,

그냥 코드가 궁금하다면 이 부분은 skip하고 

해결 방법만 보면 된다!

 

오류 발생 : 이미지는 바뀌었지만 contents의 위치가 오락가락한다.

See the Pen Untitled by yeaseula (@yeaseula) on CodePen.

 

여기서 position:absolute와 display:none를 이용했는데

이들의 특징을 짚어보며 왜 오류가 발생했는지 이해 해 보자.

position:absolute를 적용시키면 그 태그는 본래의 위치를 잃고 가장 앞에 보여진다.
display:none은 흔적도 남기지 않고 없애버린다.
★ visibility:hidden은 흔적은 남겨준다. 

 

위 코드는 마우스 hover 했을 때 display:none을 통해서 cat을 아예 흔적을 없애버렸다.
dog는 나타나긴 했으나 position:absolute가 적용되어 
본래의 위치를 잃고 모든 태그들보다 우선적으로 보여지게된다.


즉, span태그는 왜 위치가 변하느냐?

 

cat이 흔적도 없이 사라졌고, 
dog는 absolute로인해 본래의 자리를 잃어버리고 내가 제일 위에 보일거야~~~라며 마이웨이한다.

 

cat과 dog가 본래의 자리를 잃었기때문에 span이 그 자리를 차지하고 있는 것이다!

 


해결방법 1 ) html 을 통한 접근 : 이미지를 감싸는 div를 만든다.

See the Pen Untitled by yeaseula (@yeaseula) on CodePen.

 

두 개의 이미지를 감싸는 div를 만들어버리면 

이미지가 div가 버티고 있기때문에 이미지에 absolute와 display:none을 사용하더라도 

span이 움직이는 일은 없을 것이다. 

 

다만,
div에 높이를 주지 않으면
첫 번째 이미지가 display:none되면서div까지 끌고 사라져 문제가 발생할 수 있다. 
반응형 페이지가 아니라면 이 방법을 사용하는 것도 좋지만, 
대부분의 페이지를 반응형으로 만들기때문에 이 방법은 적합하지 않을 수 있다.

해결방법 2 ) css를 통한 접근 : (position:absolute / visibility:hidden) 사용

See the Pen Untitled by kimyeaseul (@mog111) on CodePen.

 

 

visibility는 hidden되더라도 본래 자리는 남겨주는, 나름 친절한 성격이기때문에 

굳이 이미지에 div를 씌우지 않아도 각각의 태그들을 자리보존하게 해준다. 

 

개인적으로 제이쿼리를 사용한다면 방법2가 더 나은 것 같다. 

 

해결방법 3 ) js를 이용한 접근

    <style>
        .box {
            width: 원하는값넣기;
            height: 원하는값넣기;
        }
    </style>
<body>
        <div class="box" onmouseover="mouseover()" onmouseleave="mouseleave()">
            <img src="img/best1.jpg" id="best1"> //이미지 경로 입력
        </div>
</body>
    <script>

        let best = document.getElementById('best1');
        function mouseover (){
            best.setAttribute("src","img/best2.jpg");
        }
        
        function mouseleave (){
            best.setAttribute("src","img/best1.jpg");
        }        
    </script>

 

js를 사용하니 코드가 훨씬 깔끔한 느낌이다!

개인적으로 될 수 있으면 js를 이용하는 걸 추천!

요즘 부트스트랩으로 반응형웹을 만들면서..

미디어쿼리로 노가다 할 때와는 다른 편리함을 느끼고 있는중^^

근데 문제는 부트스트랩 레이아웃은 이것저것 건들여서 활용해보지 않으면

표현 가능한 디자인이 너무 한정적이라는 것이다..

 

이번에 슬라이더를 만드는데 왠지..

애니메이션 효과를 주고싶은 욕망이 끝없이 들어서

부트스트랩을 뒤적거렸다.

 

http://https://react-bootstrap.netlify.app/components/carousel/#rb-docs-content

 

나는 이 부트스트랩을 이용하기로했다.

 

 

내가 원하는 레이아웃은

 

1.텍스트가 세로 중앙정렬 되어있고, 슬라이드 왼쪽 부분에 붙어있을 것

2. 반응형이기때문에 화면 넓이가 좁아지면 그에 따라 텍스트의 위치도 일정하게 변화할 것

 

근데 보다시피 기본 템플릿은 텍스트가 가로 중앙정렬, 아래쪽에 붙어있는 형태..

나는 텍스트 위치만 옮기고 싶은 강한 욕망에 휩싸였다..

 

부트스트랩에서 제공하는 기본 코드

import Carousel from 'react-bootstrap/Carousel';

function UncontrolledExample() {
  return (
    <Carousel>
      <Carousel.Item>
        <img
          className="d-block w-100"
          src="holder.js/800x400?text=First slide&bg=373940"
          alt="First slide"
        />
        <Carousel.Caption>
          <h3>First slide label</h3>
          <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
        </Carousel.Caption>
      </Carousel.Item>
      <Carousel.Item>
        <img
          className="d-block w-100"
          src="holder.js/800x400?text=Second slide&bg=282c34"
          alt="Second slide"
        />

        <Carousel.Caption>
          <h3>Second slide label</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        </Carousel.Caption>
      </Carousel.Item>
      <Carousel.Item>
        <img
          className="d-block w-100"
          src="holder.js/800x400?text=Third slide&bg=20232a"
          alt="Third slide"
        />

        <Carousel.Caption>
          <h3>Third slide label</h3>
          <p>
            Praesent commodo cursus magna, vel scelerisque nisl consectetur.
          </p>
        </Carousel.Caption>
      </Carousel.Item>
    </Carousel>
  );
}

export default UncontrolledExample;

 

기본 제공 코드를 이리저리 만져 본 결과..

 

Carousel.Caption이 겁나 말 안듣는다. 

css가 잘 먹히지 않는다.

형님 이 녀석 딜리트 맛 좀 보여줄까요?

없애버리면 어떨까 싶어서 한 번 없애봄.

안되면 다시 살리면되지 머.ㅋ

 

하나씩 삭제해본 결과

  <Carousel>

    <Carousel.Item>

         슬라이더화면1

    </Carousel.Item>

    <Carousel.Item>

         슬라이더화면2

    </Carousel.Item>

</Carousel>

 

최소 이렇게는 써 줘야 우리가 원하는 회전하는 슬라이더를 만들 수 있더라.

한 마디로 Carousel.Caption 없이도 돌아갔다.

수정한 코드

<Carousel>
    <Carousel.Item>
        <div className='slidercontents'>
            <div className='wrapText'>
                <h1>Organic fresh fruits for your health</h1>
                <div className="d-none d-md-block">
                    <p>Interdum et malesuada fames ac ante ipsum primis in 
                    faucibus. Mauris eleifend sagittis mollis. 
                    Nulla finibus arcu eu tortor gravida aliquet</p>
                </div>
                <button>SHOP NOW</button>
            </div>
        </div>
    </Carousel.Item>
    <Carousel.Item>
        <div className='slidercontents2'>
            <div className='wrapText'>
                <h1>Organic fresh fruits for your health</h1>
                <div className="d-none d-md-block">
                    <p>Interdum et malesuada fames ac ante ipsum primis in 
                    faucibus. Mauris eleifend sagittis mollis. 
                    Nulla finibus arcu eu tortor gravida aliquet</p>
                </div>
                <button>SHOP NOW</button>
            </div>
        </div>
    </Carousel.Item>
</Carousel>

css

.slidercontents {
  height: 480px;
  background-image: url(../public/img/slider.jpg);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  display: flex;
  align-items: center;
}

.wrapText {
  margin-left: 12%;
}

 

.slidercontents

아예 전체 화면의 백그라운드 이미지로 사진을 넣었다.

 

 .wrapText

퍼센테이지나 픽셀로 마진을 주면 그 고정된 숫자때문에 어그러지니까

display flex를 이용해 세로 정렬을 center로 맞추었다.

이러니 가로 길이가 줄어들어도 display flex 속성이 자동으로 알맞는 마진값으로 변경해줘서

텍스트가 슬라이더 밖으로 빠져나가지 않았다.

 

 

이 때, 화면 넓이에 상관없이 슬라이드 높이를 일정하게 유지하고싶다면 height값을 직접적으로 줘도 되지만

height 대신 padding을 주는 것도 하나의 방법이다! 

 

 

이렇게 가로 크기가 작아져도 텍스트의 마진은 알아서 조절 됨..!

 

결과물

(왼) pc버전 (오) mobile버전

 

화면 폭이 좁아져도 텍스트가 길을 잃지 않고 일정한 마진을 유지한다. 

 

span과 div의 차이점

div block 요소
span inline 요소

block / inline의 차이점

속성 줄바꿈 너비,높이 지정 여백 지정
block o o o
inline x x 좌우 여백만 가능

 

 

<div>
 <h1>Hello</h1>
 <p>텍스트입니다</p>
</div>
<div>
 <span>Hello</span>
 <span>텍스트입니다</span>
</div>

 

위와 아래는 차이가 있다.

 

h1,p 는 block 요소이기 때문에 자동으로 줄바꿈 처리가 되는 반면, 

span은 줄바꿈 되지않는다.

 

만약 span을 사용해서 줄바꿈 하고싶다면 span의 css에 display:block 혹은 display:inline-block 을 주면 된다.

 

See the Pen Untitled by kimyeaseul (@mog111) on CodePen.

 

 

결론

block 을 주었을 때는 가로 넓이 전체를 차지하며 줄바꿈이 가능하다. 
inline-block은 줄바꿈 안됨(inline 속성), 넓이/높이 지정 가능(block 속성) 하다.

 


 

그치만 span태그 안에 텍스트를 사용 할 경우 주의점이 있다. 

 

font-size와 넓이,높이 속성을 같이 주게 되면 오히려 깔끔한 레이아웃을 잡는 데 방해가 될 수 있다. 

span의 넓이를 제한시킨 가운데 내부에 있는 font-size가 너무 작거나 큰 경우가 생기기 때문이다.

 

See the Pen Untitled by kimyeaseul (@mog111) on CodePen.

 

 

 

 

그래서 span태그 사용할 때는 넓이, 높이를 잡기보단 

block속성을 추가해서 padding을 사용하는 편이 더 깔끔할 수 있다.

See the Pen Untitled by kimyeaseul (@mog111) on CodePen.

 

 

이렇게 사용하면 해당 영역과 다른 영역간의 margin값을 더 편하게 조정할 수 있을 것 같다!

 

 

'개발 > css scss' 카테고리의 다른 글

CSS scroll down animation (keyframes)  (0) 2022.12.17
z-index 적용 안된다면?  (0) 2022.10.23

useEffect를 적극 활용해서 웹사이트에 동적인 효과를 주는 방법을 터득했다. 

일단, react 사용한다면 몰라서는 안되는 개념 state에 대해 정리해봤다.

 

state의 기본 개념

State란?
변수 대신 쓰는 데이터 저장 공간
state 쓰는 이유?
state가 변경될 때 새로고침 없이 재렌더링이 가능하다.
자동으로 재렌더링이 된단 말, 때문에 부드러운 화면 전환이 가능하다.
state 언제 쓸까?
중요한 변수, 자주 바뀌는 변수는 state에 담아라.
state 특징은?
state는 직접적으로 변경이 불가능하다.
state를 변경하려면 useState를 사용한다.

 

state, useState 사용 예시

import React, { useEffect, useState } from 'react';

function App() {

  let [click,setClick]=useState(false);


  return (
    <div className='App'>
      <div className='black-nav'>
        <h3>고양이를 불러봅시다</h3>
      </div>
      
      <button onClick={()=>{setClick(!click)}} className="btn">야옹</button>

      {click && <Cat/>}

    </div>
  );
}


이 코드를 해석 해 보자면,

  1. click이라는 변수의 초기 값은 false로 설정했다.
  2. Cat이라는 컴포넌트는 click의 값이 false일 때 안보이게 해둔다.
  3. 버튼을 클릭하면 setClick의 값이 현재의 값과 반대가 된다.
    현재 click의 값이 false라면 true가 되고, 
    true라면 false가 된다!

 

이제 버튼을 누르면 고양이가 나온다.

 

 

근데 우리 고양이는 멋있으니까 등장할 때 멋지게 등장했으면 싶다.

웹 사이트에서 사진이 그냥 아무 효과없이 튀어나오면 상당히 재미없다.

이럴 때 사용할 수 있는것이 useEfffect 이다.

 

useEffect란?

렌더링 될 때 마다 특정 작업을 수행할 수 있게 해주는 Hook.
여기서 마운트, 언마운트라는 단어가 나오는데
마운트는 쉽게말해 등장하는 것 이라고 이해했다.
반대로 언마운트는 없어지는 것.
useEffect 활용법

1. useEffect( ()=> {} )
콜백함수만 인자로 받는다. 이 때는 컴포넌트가 랜더링 될 때 마다 실행된다. 

2. useEffect( ()=>{}, [value] )
콜백함수와 배열 두 가지를 인자로 받는다.
이 때는 value의 값이 바뀔 때 마다 실행된다.

3.useEffect( ()=>{}, [] )
콜백함수와 빈 배열 두 가지를 인자로 받는다.
이 때는 화면이 처음 나타났을 때 한 번만 실행된다.

 

useEffect로 사진에 애니메이션 효과 주기

function Cat (click) {

  let [fade,setFade] = useState('');


  useEffect(()=>{
     setFade('end') ;
  
      return ()=>{
          setFade('');
          console.log("클릭할때마다 useEffect 실행됩니다");
      };
  },[click]);

  return (
    <div>
      <img src='img/cat.png' className={'start '+ fade}></img>
    </div>
  );
};

**App.css에는 아래 코드를 넣는다.**

.start {
  transform: scale(0);
  width: 500px;
}
.end {
  transform: scale(1);
  transition :all 0.5s;
  width: 500px
}

Cat이라는 컴포넌트를 따로 만들었다.
let이라는 변수의 초기값은 빈 문자열이다. 
useEffect함수는 click의 value 값이 변할 때 마다 실행될 것이다. 
click은 상위 컴포넌트에서 사용 한 변수이기 때문에 
인자로 전달했다.

이제 버튼을 누르면 변수 click의 값이 바뀌기때문에 
사진이 등장하면서 useEffect가 실행된다. 
useEffect의 return값은 useEffect를 종료했을 때 뱉어내는 결과라고 이해했다.

 

**버튼 클릭하면 useeEffect가 fade값을 end로 만든다.
또 다시 버튼 클릭하면 useEffect는 return값을 뱉어낸다.**

X 무한반복~~~

이 때 console창을 보면 useEffect hook이 제대로 돌아가고 있는지 확인할 수 있다!

이렇게 useEffect를 가지고 img의 className을 자유자재로 바꿀 수 있다!
버튼을 눌러서 fade값에 end가 들어갔을 땐 scale이 0에서 1로 0.5초동안 바뀌며 사진이 등장하게된다.

 

 

결과물

 

good 용맹캣 완성

+ Recent posts