[css]프로젝트에서 사용한 스타일링

서론

여기선 활용편인거지 모든 css 속성들 정리하는게 아니므로 속성은 공식 홈페이지 참고!

여기선 단지 다양한 UI 스타일링 한것을 기록 및 연습하기 위함이며,
간단한 개인 프로젝트에는 CSS 프레임워크, codepen 사이트 등을 이용하는 것을 추천

  • 이전의 React스타일링도 참고 추천 - React스타일링
  • 참고로 bootstrap, tailwind 라는 유용한 CSS 프레임워크가 있으므로 참고!
    • bootstrap은 반응형에 좋으며, tailwind는 가벼워서 좋다.
  • 또한 codepen 라는 다른사람들이 UI 스타일링한 CSS 코드를 공유한 사이트도 유용하다.


다음부터 볼 내용들은 개인 프로젝트에서 정말 간단한 쇼핑몰을 만든게 있는데,

이곳에 사용한 스타일링을 기록해본다.


웹에 맨 위에있는 네비게이션 바(상단 메뉴바) 라고 볼 수 있다.
공간을 적절히 배분해서 나누는것을 볼 수 있다.

코드확인 : Navbar.jsx

  • Wrapper(Container의 하위 자식)을 display: flex를 통해 가로로 나타내며,
    justify-content: space-between 를 통해 사이 공백으로 정확히 나눈다(Left, Center, Right)
  • Leftflex:1, Center또한 flex:1, Rightflex:1

image-20220801185320682


Slider

웹 화면의 범위를 넘어서는 그림을 슬라이더 형식으로 볼 수 있다.
왼쪽, 오른쪽 화살표 버튼을 이용해서 이전, 다음 그림으로 넘어갈 수 있다.

코드확인 : Slider.jsx

  • Container(제일 부모)overflow: hidden을 통해서 가로로 많은 사진 데이터들이 이어져 있는것을 숨긴다.
  • Arrow(화살표)position: absolute를 통해 절대적 구조를 가져서 위치를 어디든 겹쳐서 이동이 가능하다.(그림위에 화살표가 있을 수 있는 이유이다) 참고로 부모는 position: relative 해야한다.
    • 화살표 선택시 cursor: pointer를 통해 마우스 포인터의 모양을 바꿀 수 있다.
    • 중요 !! z-index: 2를 통해서 우선 순번 index를 지정해야 화살표가 그림과 겹쳐도 앞으로 나타난다.
      만약 무조건 제일 상위에 나타내고 싶은게 있다면 간단히 z-index: 999로 하면 되겠죠
    • left: ${props=>{return props.direction === "left" ? "10px" : null}};
      왼쪽 화살표의 위치배치 예시로 direction은 왼쪽 화살표의 이름으로 left를 의미하며 삼항 연산을 통해 배치시켰다. 왜냐하면 그냥은 왼쪽, 오른쪽 화살표 위치로 이동이 힘들기 때문이다.
  • Wrapper(그림들 담은 큰틀)은 Container의 바로 자식이다.
    display: flex를 통해 가로로 많은 그림들을 볼 수 있다.(이것을 안하면 세로로 나타난다)
    • transition: all 1.5s ease를 통해 1.5초 동안 그림넘기는 애니메이션 기능이다.
      ease가 기본 속성이며, 다른 속성들 사용시 넘어가는 효과들이 달라진다.
    • transform: translateX(${props=> props.slideIndex * -100}vw)를 통해 그림 한개씩을 넘긴다.
      이게 가능한 이유는 -100px, -200px… 를 해보면 점점 오른쪽 그림들로 넘어간다는 것을 알 수 있다.
      여기서 100vw는 100% 화면너비를 의미하므로, -100vw를 통해서 그림 한개 단위로 넘길 수 있다.
      => 물론 그림 한개가 웹 화면너비 100%로 가득 채워서 만들었을때의 가정이다.
  • Slide(그림 한개 담아지는 틀)은 Wrapper의 바로 자식이다.
    여기서는 100% 너비보단 width: 100vw 로 너비 지정하는 것이 더욱 오차가 없다.
    • width:100% 를 사용하다보니, 원치 않게 자꾸 화면에 맞춰서 작아진 경우가 있다. 그러나 px로 다루면 크기가 정해진거라서 변하지 않는다.
    • 크기를 정하고 싶었기 때문에 px역할을 해줄 width:100vw 로 px로 100% 너비 지정해준 효과로 된다.
    • 즉, 이방법을 사용해야 그림들을 가로로 화면 크기 이상 나타낼 수 있다.
    • 그러므로 이것을 감싸는 부모는? 화면에 딱 맞춰 나타내야 할테니 높이는 height:100% 로 작성해줘야 좋다
  • Button(SHOW NOW 의미)처럼 배경색과 어우러지는 방법은 background-color: transparent 이다.
    이것은 색이 아예 없다는것을 의미한다.

image-20220801180759003


Product

그림 처럼 제품에 마우스를 올리면 UI가 반응하는것을 볼 수 있다.

코드확인 : Product.jsx

  • Container(제일 부모)에 position: relative를 통해서 나머지 하위 자식들은
    position: absolute를 이용하여 절대적 구조를 가져서 그림 겹친다.
    • &:hover { opacity: 1; } 를 통해 마우스 올려뒀을때 투명도(opacity)를 바꾼다
  • Info(3개 Icon의 부모)에서도 &:hover { opacity: 1; } 를 통해 마우스 올려뒀을때 투명도를 바꾼다
    z-index: 3을 통해서 제일 상위로 꺼내는 작업도 필수이다.
  • Icon(3개의 Icon)의 &:hover{ background-color: #e9f5f5; transform: scale(1.1); }은 커서를 올려두면 Icon이 커지는 이벤트를 작성한다.

image-20220801195411539


보통 홈페이지의 맨 아래쪽이며,
ul, li 태그를 사용하는 스타일링을 잘 확인할 것

코드확인 : Footer.jsx

  • Container(제일부모)의 Left, Center, Right 중에서 Center 부분을 ul, li 태그 사용
  • CenterContainer의 자식인데, 이 Center의 자식을 ul, li 태그로 지정
    • uldisplay:flex를 선언하고, list-style: none을 통해 점 표시를 제거한다.
      flex-wrap: wrap은 Flex 컨테이너에서 Flex 아이템을 한 줄로 표시할 지, 또는 행(行)을 되풀이 해서 복수의 행(行)으로 표시할지 여부를 지정하며 wrap은 복수의 행으로 표시한다.
      => 참고 : wrap쓸때 애초에 한줄에 한개item만 있으면 전혀 쓸필요가 없으니 잘 구분해서 사용!
    • liul태그의 자식으로서 width: 50% 선언시 그림처럼 절반씩 가지는 복수의 행으로 표시!
  • Rightflex:1을 가진 오른쪽 그림이며, ContactItem 3개를 자식으로 구성 중이다.
    이것은 display:flex 상태가 아니란점을 잘 구분해야한다.
  • ContactItemdisplay:flex를 통해 Flex 형태로 바꾸면서 그림, 글자의 위치가 맞게 된다.

image-20220801234945962


Category

카테고리 구성한 것이며, 그림 내에 추가로 공간을 겹쳐서 사용중이며,
이미지를 크기에 딱 맞게 맞췄다.

코드확인 : CategoriyItem.jsx

  • Container(제일 부모) 를 해당 그림 한개로 보면 되고, 각 flex:1로 서로 공간 할당 했다
    • position: relative 를 통해 absolute를 자식이 사용
  • Image 가 근데 너무 크면 할당한 공간을 넘겨버리기 때문에, width:100%; height:100%; 필수!
    • 대신 그림이 우겨넣은것 처럼 보일수 있으므로, 잘려도 괜찮다면 object-fit: cover
      를 이용해서 공간에 맞게끔 잘라서 사용한다.
  • Infoposition: absolute 를 통해 절대적 구조 사용해서 겹칠수 있는것

image-20220802010059964


Login - background 스타일링

로그인이지만, 배경만 볼것이다.
배경을 스타일링 한것을 잘 확인할 것

코드확인 : Login.jsx

const Container = styled.div`
  width: 100vw;
  height: 100vh;
  background: linear-gradient(
      rgba(255, 255, 255, 0.5),
      rgba(255, 255, 255, 0.5)
    ),
    url("https://images.pexels.com/photos/6984650/pexels-photo-6984650.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940")
      center;
  // 배경화면에 url을통해 이미지를 중앙배치해서 0.5투명도로 넣은것이고 배경색을 연하게 한것
  background-size: cover;
  display: flex;
  align-items: center;
  justify-content: center;
`;
  • background: linear-gradient는 배경색을 연하게 한 것이다.
  • background-size: cover 처럼 cover로 지정하면 배경 이미지의 가로/세로 길이 모두 요소 보다 크다라는 조건하에 가능한한 배경이미지를 작게 조절한다.
    이때 가로/세로 비율도 유지
  • 추가로 text-decoration: underline 은 그림처럼 텍스트에 밑줄 긋기

image-20220802012136424


Cart - H1태그 꾸미기

H1 선을 꾸민것이다.

코드확인 : Cart.jsx

  • background-color: #eee; border: none; height: 1px;

image-20220802012914133


Mobile - responsive.js

모바일에서 웹을 보면 당연히 배치나 크기 등이 다를것이다. 이를 해결하는 방안이다.

코드확인 : responsive.jsx

  • css를 아래처럼 사용하려면 import가 꼭 필요하다.
  • Iphone X를 기준으로 하였고, 간단한 예시만 보이겠다.
// responsive.js
import {css} from "@emotion/react"

export const mobile = (props) => {
    return css`
        @media screen and (max-width: 380px) { // Iphone X
            ${props}
        }
    `
}
// Navbar.jsx
const Language = styled.div`
  font-size: 14px;
  cursor: pointer; // cursor를 pointer 표시(커서 모양 변경)
  ${mobile({ display: "none" })}
`;

// Categories.jsx
const Container = styled.div`
  display: flex;
  padding: 20px;
  justify-content: space-between;
  ${mobile({padding : "0px", flexDirection:"column"})}
`;

image-20220802014229350

  • 이처럼 display: none은 크기도 차지하지 않고, 화면에서 사라져 주기 때문에 유용하다.
    • 이해가 안된다면, 위에서 이전 사진들과 비교해봐라. 검색란 왼쪽에 EN을 볼 수 있다.
  • 또한 가로로 긴배치는 세로로(column) 배치하는것도 좋은 아이디어 이다.
    • flexDirection:"column" 을 의미


상단 메뉴바인데, 이것을 스크롤해도 맨위 상단에 고정 시키는것과
오른쪽의 아이콘들을 직접 커스텀한것을 중점으로 확인

코드확인 : topbar.css

  • .topbar(제일 부모) 를 제일 상단에 고정시키면 되는데,
    position: sticky; top:0; z-index: 999; 속성을 설정하면 된다.
  • .topbarWrapper(topbar의 바로 하위자식) 은 .topLeft, .topRight를 위해
    display: flex; justify-content: space-between; 설정을 해준다.
  • .topbarIconContainer(.topRight의 바로 하위자식) 은 .topIconBadge 와 겹치기위해
    position: relative; 로 절대적 구조를 위한 기반을 다진다.
  • .topIconBadge 에서 position: absolute; 를 통해 겹쳐서 표현한다.
    border-radius: 50%; 를 통해 동그라미로 만들고 나머지도 스타일링 한다.

image-20220802162039591


Sidbar

그림처럼 왼쪽의 모습이며, 해당 위치로 이동과 해당 위치에서 고정 시키는 방법
마우스 올렸을시 변화되는 UI를 중점으로 확인한다
마지막으로 box-shadow를 활용한 그림자 커스텀한것을 확인한다

코드확인 : Sidbar.css

  • 우선 위치 이동한 방식을 설명하자면,
    App.js에서 Topbar(상단의 메뉴바) 추가한 다음에 <div id=container/> 하나 추가해주고
    App.css에서 container를 display:flex 를 했기 때문에 container 하위 자식으로
    Sidbar(현재 다룰 왼쪽 그림의 바)와 오른쪽 다양한 페이지들 형태로 나타낼 수 있는것이다.
    실제로 아래에선 왼쪽 Sidbarflex:1, 오른쪽 Homeflex:4 로 1:4로 분배했다.

  • .sidebar(제일 부모) 는 그림의 왼쪽에 위치하기위해 높이를 height: calc(100vh - 50px)로 설정
    그리고 position: sticky; top: 50px; 을 통해 높이 50px 아래에 위치시켜 고정시킨다

    • height 설정을 추가 설명하자면 ,
      Topbar(상단의 메뉴바) 가 height가 50px이기 때문에 이렇게 설정하는 것이다.
      100vh는 100%로 볼 수 있으며 Topbar 높이만큼은 빼줘야 .sidebar 가 이쁘게 설정 된다.
  • .sidebarIcon 는 mui-icon을 담은 컴포넌트인데 font-size로 크기변경 한다.

    • 잘 안먹히는 경우 !important 속성을 추가하라. (하지만 이를 남발하면 좋지않으니 조심히 사용)
  • .sidebarListItem 는 active와 hover(마우스 올렸을때 이벤트) 일때 UI를 변경시킨다.

    • .sidebarListItem.active,
      .sidebarListItem:hover {
        background-color: rgb(240, 240, 255);
      }
      
    • 참고로 active는 <li className="sidebarListItem active"> 이런식의 태그에 반응한다.
  • featuredInfo.css의 .featuredItem 는 그림 오른쪽의 Home.jsx 페이지 부분인데,
    UI들이 그림자로 꾸며진것을 볼 수 있다. box-shadow를 커스텀하는 페이지를 이용한것이다.

    • -webkit-box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75);
      box-shadow: 0px 0px 15px -10px rgba(0, 0, 0, 0.75);
      

image-20220802163609738


Recharts

차트를 활용한 것이다. 사이트에서 import를 해서 사용한다.
다양한 커스텀 방법은 꼭 사이트 참고

코드확인 : Chart.jsx

  • ResponseiveContainer 이 반응형 컨테이너. 즉, width="100%" aspect={4 / 1} 로 하면
    높이는 너비의 1/4크기로 나온다.
  • LineChart 는 실제 차트 데이터를 넣는 부분(더미 데이터를 활용함 dummyData.js)
  • XAxis, YAxis 는 x축, y축이며 색은 stroke으로 설정
  • Line 은 데이터에 따른 그래프 선을 설정
  • Tooltip 은 해당 데이터에 마우스 가져다대면 y축인 값을 보여줌
  • CartesianGrid 를 통해 grid나타냄(모눈종이같이)
    그리고 strokeDasharray 5 5(선길이, 선사이공백길이)를통해 실선이 아닌 점선처럼 보여줌

image-20220802170910653


WidgetLG

페이지에 구성된 위젯의 Table태그 활용과 버튼 스타일링 정리

코드확인 : widgetLg.css

  • .widgetLgTable 은 table태그이며, table선은 간단히 border:none 을 통해 없앨수 있다.

    • border-spacing: 20px 을 통해 내부 td, th값들도 margin효과를 얻음
      테이블 선 기준으로 margin 하는 느낌이라고 이해하면 된다.
  • .widgetLgButton 은 버튼이며 Approved, Declined, Pending 마다 배경색, 글자색을 다르게 표현

    • // jsx
      const Button = ({ type }) => {
          return <button className={"widgetLgButton " + type}>{type}</button>;
      };
          
      <Button type="Declined" />
          
      // css
      .widgetLgButton.Approved{
          background-color: #e5faf2;
          color: #3bb077;
      }
      .widgetLgButton.Declined{
          background-color: #fff0f1;
          color: #d95087;
      }
      .widgetLgButton.Pending{
          background-color: #ebf1fe;
          color: #2a7ade;
      }
      
    • 이런식으로 간단히 사용할 수 있다. (위에서 정리한 Sidbar의 active였을때를 활용한 예시이다)

image-20220802175012485


UserList

mui 사이트에서 table(data table)관련 라이브러리를 활용한것이다.

코드확인 : UserList.jsx

  • DataGrid 가 테이블 구성하는 컴포넌트이다.
    • rows속성에 데이터를 넣어준다(dummyData.js 활용)
    • disableSelectionOnClick 속성 넣어주면 요소 선택시 체크박스X
      checkboxSelection 속성 넣어주면 체크박스는 체크 가능하다
    • columns 속성에 테이블의 열 속성을 설정한다
      여기서 중요한것은 renderCell 이며, 테이블의 해당 셀(열)부분 커스텀해서 재렌더 한다
      즉, 각 셀들 커스텀이 가능한것이다. 나머지는 코드를 확인할 것
    • pageSize 속성은 화면에 보이는 한 페이지에 몇개 데이터를(행) 보여줄건지 설정

image-20220802181353778


User

원래 input 태그에서 file 타입을 사용하면, 파일을 입력받을수 있는 버튼 역할을 하는데 이를 활용해서
그림의 오른쪽처럼 이미지 업로드를 mui-icon으로 커스텀해서 입력 받는 방법을 볼것이다

코드확인 : User.jsx

  • <label htmlFor="file">
        <PublishIcon className="userUpdateIcon" />
    </label>
    <input type="file" id="file" style= />
    
  • 이처럼 label의 속성을 id가 file인것과 연결하고, mui-icon인 PublishIcon으로 커스텀한다.
    그리고 나서 타입이 file인 input태그와 연결을 위해 id를 file로 설정한다.
    마지막으로 해당 버튼을 display:”none” 속성을 줘서 사라지게 한다.

image-20220802182737086


Button

중복 방지, 클릭시 UI도 변경, 클릭도 불가하게 바꾸는 유용한 방식

  • isFetching은 redux에서 가지고 있으며 api호출과 연동한 부분이다
  • 로그인 시작시 true, 로그인이 끝나야 false로 바뀐다
  • 즉, api의 동작에 따라 isFetching이 풀리기 때문에 버튼이 여러번 누르는게 방지
  • jsx에서 동작이다.
// jsx
&:disabled{
  color: green;
  cursor: not-allowed;
}

<Button disabled={isFetching}> </Button>
  • 마찬가지로 css에서도 할 수 있다
    • .updateButton:disabled {} 를 추가하면 된다.
// css
.updateButton {
  margin-top: 10px;
  border: none;
  padding: 5px  10px;
  background-color: rgb(97, 161, 161);
  color: white;
  border-radius: 10px;
  cursor: pointer;
  font-weight: 500;
}

.updateButton:disabled{
  cursor: not-allowed;
  background-color: rgb(136, 168, 168);
}

태그:

카테고리:

업데이트:

댓글남기기