관리 메뉴

CASSIE'S BLOG

쇼핑몰 프로젝트 시작 본문

PROGRAMMING/프로젝트

쇼핑몰 프로젝트 시작

ITSCASSIE1107 2023. 10. 29. 00:11

 

 

ecommerce 폴더 만든 후 "npx create-react-app"
근데 there are some default stuff here. 
그래서 repository clone으로 시작할거임
 
"yarn"은 JavaScript 패키지 매니저 중 하나입니다. Node.js 환경에서 사 용되며, 프로젝트의 의존성 패키지를 관리하고 설치하는 데 도움을 주는 도 구입니다. "yarn start" 명령은 일반적 으로 Javascript 프로젝트의 개발 서 버를 시작하기 위해 사용됩니다.



https://youtu.be/c1xTDSIXit8?si=H6HcSC6YB0xFy4Ul

 
 
git clone --single-branch -b react-mini https://github.com/safak/youtube.git .
 
점까지 해야지 모든 files이 install 됨. 주의 할 것. 제일 마지막에 온점 있음. 
 
it's here but as you realize we don't have our dependencies to install them you can write here npm install or
2:55
if you are using yarn just yeah i will enter
 
npm install or yarn 둘중에 하나만 하면 되는데 나는 npm 쓰니까 그거 설치하기. 
 
 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <style>
      * {
        margin: 0;
        font-family: 'Urbanist', sans-serif;
      }
    </style>
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

 
font-family는 또 style태그 안에 넣어줘야한다.
 

 
직면문제: 실행이 안됐다.
jsx 파일이 있었다.
나는 json파일에 starts script를추가했는데. 
 
 
"node" 명령어로 JSX 파일을 직접 실행하려고 하면 오류가 발생할 것입니다. JSX 파일은 JavaScript 코드가 아니므로 "node" 명령어로 실행할 수 없습니다.

JSX 파일은 주로 React 애플리케이션의 구성 요소로 사용되며, JSX 파일을 브라우저에서 렌더링하려면 번들러(예: Webpack, Vite)를 사용해야 합니다. 번들러는 JSX 파일을 JavaScript 파일로 변환하고 브라우저에서 실행 가능한 형식으로 만듭니다.

만약 JSX 파일을 실행하려는 것이라면, React 애플리케이션을 개발 중이라고 가정하고, 프로젝트 디렉토리 내에서 다음과 같이 개발 서버를 실행해야 합니다 (일반적으로 Vite나 Create React App와 같은 도구를 사용합니다):

프로젝트 디렉토리로 이동합니다.
개발 서버를 시작하는 스크립트를 실행합니다. 예를 들어, "npm run dev" 또는 "yarn dev"와 같은 명령을 사용합니다. 스크립트 이름은 "package.json" 파일의 "scripts" 항목에 정의되어 있어야 합니다.
JSX 파일을 실행하려면 React 애플리케이션의 빌드 및 실행 프로세스를 따라야 합니다. JSX 파일을 단독으로 실행하는 것은 일반적으로 지원되지 않습니다.
 
 

{
  "name": "vite",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.28",
    "@types/react-dom": "^18.0.11",
    "@vitejs/plugin-react": "^4.0.0",
    "eslint": "^8.38.0",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.3.4",
    "vite": "^4.3.2"
  }
}

 
이미 clone해온 파일을 보니 vite를 쓰고있었다.
vite 를 깔아야한다.
 
npm run dev
 
깔끔실행됨

 
이 확장팩을 사용하라고함. 

 
다운받음
 

설치하고나서
일반함수: rfc
화살표함수: rafce 
 
 

rfc: 
 
function~으로 만들고 export 바로 함. 

import React from 'react'

export default function Home() {
  return (
    <div>
     
    </div>
  )
}

rafce: 이 방법이 더 모던함.

import React from 'react'

const Home = () => {
  return (
    <div>
     
    </div>
  )
}

export default Home

 
instead of div we are going to create our container to use style components we should import our library first so i

will expand here and i'm going to open new terminal and i'm going to add style

components library to do that you can write here npm install and style components

or yarn add style components

so firstly instead of div we can create our own style components

styled-components 설치하려면 다른 터미널 한번 더 열어야한다.
 
 

ibrary as you can see styled from style components and after that i will say dot

and my html element which is div because we are using div here

and after that i'm gonna use backticks and inside i'm gonna write my style 
 
이거랑 똑같음

 

 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    height:60px;
    background-color:black;
`

const Navbar = () => {
  return (
    <Container>
      Navbar
    </Container>
  )
}

export default Navbar

 
 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    height:60px;
    background-color:black;
`

const Wrapper = styled.div`
    padding: 10px 20px;
`;


const Navbar = () => {
  return (
    <Container>
      Navbar
    </Container>
  )
}

export default Navbar

10px = top & bottom
20px; right & left 
 
 
 styled.div는 실제로 스타일이 적용된 새로운 div 컴포넌트를 생성합니다. 이 새로운 div 컴포넌트는 스타일이 적용되었으며 원래의 HTML div 요소와 동일한 역할을 하지만 스타일이 적용되어 있습니다.

이것은 React 컴포넌트로 사용할 수 있는 styled-components의 핵심 기능 중 하나입니다. 즉, 스타일링된 컴포넌트를 만들어서 해당 컴포넌트를 React 애플리케이션에서 사용할 수 있습니다. 이렇게 하면 스타일이 미리 정의되어 있고, 컴포넌트 단위로 재사용 가능한 스타일을 적용할 수 있습니다.
 
styled.div는 div 요소에 대한 스타일을 정의하고 해당 스타일이 적용된 새로운 div 컴포넌트를 생성합니다. 이렇게 생성된 div 컴포넌트는 다른 React 컴포넌트처럼 사용할 수 있으며, 해당 스타일이 그 div 컴포넌트에 적용됩니다.

즉, 위의 코드에서 Container는 스타일이 적용된 div 컴포넌트를 나타냅니다. Wrapper도 비슷하게 스타일이 적용된 div 컴포넌트를 나타내며, Navbar 컴포넌트 내에서 이러한 스타일이 사용됩니다.
 

 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    height:60px;
    background-color:yellow;
`

const Wrapper = styled.div`
    padding: 10px 20px;
    display: flex;
`;


const Left = styled.div``;
const Center = styled.div``;
const Right = styled.div``;


const Navbar = () => {
    return (
        <Container>
            <Wrapper>
                <Left>left</Left>
                <Center>center</Center>
                <Right>right</Right>
            </Wrapper>
        </Container>
    )
}

export default Navbar

 
flex 추가
 

 
 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    height:60px;
    background-color:yellow;
`

const Wrapper = styled.div`
    padding: 10px 20px;
    display: flex;
    justify-content: space-between;
`;


const Left = styled.div``;
const Center = styled.div``;
const Right = styled.div``;


const Navbar = () => {
    return (
        <Container>
            <Wrapper>
                <Left>left</Left>
                <Center>center</Center>
                <Right>right</Right>
            </Wrapper>
        </Container>
    )
}

export default Navbar

 
 
 
33.33333333333333333%보다는 flex:1를 한다는데?
 
정확한 분할: flex: 1을 사용하면 사용 가능한 공간을 모든 자식 요소가 공평하게 나누어 가집니다. 이것은 상위 컨테이너의 가로 공간을 자식 요소들 사이에 균등하게 분배해주는데 도움이 됩니다. 반면에 33.33333333333333333%를 사용하면 소수점 아래의 정밀도 문제로 인해 정확한 분할이 어려울 수 있습니다.

그러면 flex:2를 하면 어떻게 되는거야?

flex 속성은 비율을 나타내는 값으로, 부모 컨테이너 내에서 다른 flex 아이템들과 비교하여 각 아이템의 크기를 결정합니다. 기본적으로 모든 아이템의 flex 값은 1입니다.

다시 말해서, flex: 2를 사용하면 해당 아이템은 다른 아이템보다 큰 공간을 차지하게 됩니다. 만약 모든 아이템이 동일한 flex 값을 갖는다면, 공간은 모든 아이템 사이에 균등하게 분배될 것이며, 아이템의 크기는 동등하게 조절됩니다.

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    height:60px;
    background-color:yellow;
`

const Wrapper = styled.div`
    padding: 10px 20px;
    display: flex;
    justify-content: space-between;
`;


const Left = styled.div`
    width: 33.33333%`;
const Center = styled.div`
    width: 33.3%`;
const Right = styled.div`
    width: 33.3%`;


const Navbar = () => {
    return (
        <Container>
            <Wrapper>
                <Left>left</Left>
                <Center>center</Center>
                <Right>right</Right>
            </Wrapper>
        </Container>
    )
}

export default Navbar

 
두 코드 예제는 styled-components를 사용하여 스타일이 적용된 React 컴포넌트를 생성하는 방법을 보여줍니다. 주요 차이점은 다음과 같습니다:

width vs. flex 속성: 첫 번째 예제에서는 width 속성을 사용하여 각 Left, Center, Right 컴포넌트의 너비를 정의합니다. 각 컴포넌트의 너비가 고정됩니다.

두 번째 예제에서는 flex 속성을 사용하여 flex: 1로 각 Left, Center, Right 컴포넌트의 너비를 동일하게 설정합니다. 이것은 각 컴포넌트가 사용 가능한 공간을 동등하게 나누는 "flexbox" 레이아웃을 만듭니다.

justify-content 속성: 두 번째 예제에서는 Wrapper 컴포넌트에 justify-content: space-between; 스타일을 적용하여 Left, Center, Right 컴포넌트 사이에 동일한 간격을 만듭니다. 이로 인해 컴포넌트 간 간격이 균등하게 분배됩니다.

두 예제 모두 네비게이션 바를 만드는데 사용되며, 레이아웃 및 스타일을 다르게 정의합니다. 첫 번째 예제에서는 각 컴포넌트의 너비가 고정되고, 두 번째 예제에서는 flex를 사용하여 동적으로 레이아웃을 구성합니다. 선택은 디자인 요구사항 및 개발자 선호에 따라 달라질 수 있습니다.
 

 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    height:60px;
    background-color:yellow;
`

const Wrapper = styled.div`
    padding: 10px 20px;
    display: flex;
    justify-content: space-between;
`;


const Left = styled.div`
    flex: 1`;
const Center = styled.div`
     flex: 1`;
const Right = styled.div`
     flex: 1`;

const Language = styled.span`
    font-size: 14px;
    cursor: pointer;
`

const Navbar = () => {
    return (
        <Container>
            <Wrapper>
                <Left>left</Left>
                <Center>center</Center>
                <Right>right</Right>
            </Wrapper>
        </Container>
    )
}

export default Navbar

 
 
💌 https://mui.com/material-ui/material-icons/

 

React Icon Component - Material UI

Guidance and suggestions for using icons with Material UI.

mui.com

 
as you can see we should import this library first but it's not enough we should also import material ui and core
library otherwise we are not gonna able to use these icons so let's do that 
 
 

 

 
https://mui.com/material-ui/material-icons/?query=search
 
 
npm install @mui/icons-material @mui/material @emotion/styled @emotion/react
 

 
 

 

 
display 속성을 설정하는 방식은 flex 속성과 함께 사용할 때 중요한 역할을 합니다. display: flex;는 해당 요소를 Flexbox 컨테이너로 만들고, 그 하위 요소들을 Flexbox 아이템으로 처리합니다.

이 두 가지 코드 예제를 살펴보겠습니다:

Left 컴포넌트에 flex: 1;만 설정된 경우:
 

const Left = styled.div`
    flex: 1;
`

 
이 코드는 Left 컴포넌트를 Flexbox 컨테이너로 만들고 해당 컨테이너 내부의 Flexbox 아이템들을 동일한 비율로 확장합니다. 아이템들 사이에 간격이 없고, 모든 아이템이 사용 가능한 공간을 동등하게 나눠 차지합니다.

Left 컴포넌트에 flex: 1;과 display: flex;가 함께 설정된 경우:
 

const Left = styled.div`
    flex: 1;
    display: flex;
`

 
이 코드는 Left 컴포넌트를 Flexbox 컨테이너로 만든 후, 그 컨테이너 내부에서 다시 Flexbox 레이아웃을 적용합니다. 이것은 Left 컴포넌트 내부의 하위 요소에 대한 추가적인 Flexbox 레이아웃을 생성합니다. 즉, Left 컴포넌트 내부의 요소들 간에 Flexbox 레이아웃을 설정할 수 있습니다.

이것은 중첩된 Flexbox 레이아웃을 만드는 방법 중 하나일 수 있으며, 필요에 따라 컴포넌트 내부의 요소들을 추가적으로 정렬하고 배치하는 데 사용할 수 있습니다. 중첩된 Flexbox 레이아웃을 사용하면 복잡한 레이아웃을 만들 수 있습니다.
 
부모요소에해줘야한다.

i will do the same thing i'm gonna use display flags here our parent i will say display flex
they are horizontal right now but as you can see they are not vertically centered to do that i will write here align item
center and have some they are centered
 

const Left = styled.div`
    flex: 1;
    display: flex;
    align-items: center;
`

 
왜 그런지 모르겠지만 search container에도 해준다.
so i can do the same thing for this search container let's come here i will say display flex
and align some center
 
네, align-items: center; 속성은 Flexbox 컨테이너 내에서 아이템들을 수직으로 중앙에 정렬하는 역할을 합니다.

Flexbox 레이아웃에서 align-items 속성은 주로 아이템들의 수직 정렬을 다루며, 가능한 값은 다음과 같습니다:

flex-start: 아이템을 컨테이너의 시작 부분에 정렬합니다.
flex-end: 아이템을 컨테이너의 끝 부분에 정렬합니다.
center: 아이템을 수직으로 가운데에 정렬합니다.
baseline: 아이템의 기준선(baseline)을 맞춥니다.
stretch: 아이템을 컨테이너의 높이에 맞게 늘립니다.
align-items: center;를 사용하면 Flexbox 컨테이너 내부의 아이템들이 수직으로 중앙에 정렬됩니다. 이는 주로 가로로 나열된 아이템이 수직으로 중앙에 정렬되도록 할 때 유용합니다.
 
 
okay so i hope you understood how to use flexbox to make your whole items horizontal you can use flexbox to center
them vertically align itemcenter and to center them horizontally

Flexbox 컨테이너는 Flexbox 레이아웃을 사용하여 그 안에 포함된 아이템들을 배치하는 역할을 하는 요소입니다. Flexbox 컨테이너는 그 자체로 HTML 요소일 수 있으며, 그 안에 다른 HTML 요소나 컴포넌트를 포함할 수 있습니다.

Flexbox 컨테이너는 내부의 아이템을 수평 또는 수직으로 정렬하고, 간격을 설정하며, 동적으로 조정할 수 있게 하는 레이아웃 기술을 제공합니다. 이를 통해 복잡한 레이아웃을 보다 쉽게 구현할 수 있습니다.
 
 

 

import React from 'react'
import styled from 'styled-components'
import SearchIcon from '@mui/icons-material/Search';
import { display } from '@mui/system';
import { Badge } from '@mui/material';
import ShoppingCartOutlinedIcon from '@mui/icons-material/ShoppingCartOutlined';

const Container = styled.div`
    height:60px;
    background-color:yellow;
`

const Wrapper = styled.div`
    padding: 10px 20px;
    display: flex;
    align-item: center;
    justify-content: space-between;
`;


const Left = styled.div`
     flex: 1;
    display: flex;
    align-items: center;
`
const Language = styled.span`
    font-size: 14px;
    cursor: pointer;
`

const SearchContainer = styled.div`
    border: 0.5px solid lightgray;
    display: flex;
    align-items: center;
    margin-left: 25px;
    padding: 5px;
   
`

const Input = styled.input`
    border: none;
`

const Center = styled.div`
     flex: 1;
     text-align: center;
`

const Logo = styled.h1`
    font-weight: bold;
`

const Right = styled.div`
     flex: 1;
     display:flex;
`

const MenuItem = styled.div`
    font-size: 14px;
    cursor: pointer;
`

const Navbar = () => {
    return (
        <Container>
            <Wrapper>
                <Left>
                    <Language>english</Language>
                    <SearchContainer>
                        <Input />
                        <SearchIcon />
                    </SearchContainer>
                </Left>
                <Center><Logo>CASSIE</Logo></Center>
                <Right>
                    <MenuItem>REGISTER</MenuItem>
                    <MenuItem>SIGN IN</MenuItem>
                    <MenuItem>
                        <Badge badgeContent={4} color="primary">
                        <ShoppingCartOutlinedIcon/>
                        </Badge>
                    </MenuItem>
                </Right>
            </Wrapper>
        </Container>
    )
}

export default Navbar



 

 

이걸 해줘야 카트모양이 오른쪽으로 간다. 
 
flex-end 제일 왼쪽 끝으로 가는 거
 

import React from 'react'
import styled from 'styled-components'
import SearchIcon from '@mui/icons-material/Search';
import { display } from '@mui/system';
import { Badge } from '@mui/material';
import ShoppingCartOutlinedIcon from '@mui/icons-material/ShoppingCartOutlined';

const Container = styled.div`
    height:60px;
    background-color:yellow;
`

const Wrapper = styled.div`
    padding: 10px 20px;
    display: flex;
    align-item: center;
    justify-content: space-between;
`;


const Left = styled.div`
     flex: 1;
    display: flex;
    align-items: center;
`
const Language = styled.span`
    font-size: 14px;
    cursor: pointer;
`

const SearchContainer = styled.div`
    border: 0.5px solid lightgray;
    display: flex;
    align-items: center;
    margin-left: 25px;
    padding: 5px;
   
`

const Input = styled.input`
    border: none;
`

const Center = styled.div`
     flex: 1;
     text-align: center;
`

const Logo = styled.h1`
    font-weight: bold;
`

const Right = styled.div`
     flex: 1;
     display:flex;
     align-items: center;
     justify-content: flex-end;
`

const MenuItem = styled.div`
    font-size: 14px;
    cursor: pointer;
`

const Navbar = () => {
    return (
        <Container>
            <Wrapper>
                <Left>
                    <Language>english</Language>
                    <SearchContainer>
                        <Input />
                        <SearchIcon />
                    </SearchContainer>
                </Left>
                <Center><Logo>CASSIE</Logo></Center>
                <Right>
                    <MenuItem>REGISTER</MenuItem>
                    <MenuItem>SIGN IN</MenuItem>
                    <MenuItem>
                        <Badge badgeContent={4} color="primary">
                        <ShoppingCartOutlinedIcon/>
                        </Badge>
                    </MenuItem>
                </Right>
            </Wrapper>
        </Container>
    )
}

export default Navbar



 

 
gray 쌍따옴표
 

import React from 'react'
import styled from 'styled-components'
import SearchIcon from '@mui/icons-material/Search';
import { display } from '@mui/system';
import { Badge } from '@mui/material';
import ShoppingCartOutlinedIcon from '@mui/icons-material/ShoppingCartOutlined';

const Container = styled.div`
    height:60px;
    background-color:yellow;
`

const Wrapper = styled.div`
    padding: 10px 20px;
    display: flex;
    align-item: center;
    justify-content: space-between;
`;


const Left = styled.div`
     flex: 1;
    display: flex;
    align-items: center;
`
const Language = styled.span`
    font-size: 14px;
    cursor: pointer;
`

const SearchContainer = styled.div`
    border: 0.5px solid lightgray;
    display: flex;
    align-items: center;
    margin-left: 25px;
    padding: 5px;
   
`

const Input = styled.input`
    border: none;
`

const Center = styled.div`
     flex: 1;
     text-align: center;
`

const Logo = styled.h1`
    font-weight: bold;
`

const Right = styled.div`
     flex: 1;
     display:flex;
     align-items: center;
     justify-content: flex-end;
`

const MenuItem = styled.div`
    font-size: 14px;
    cursor: pointer;
   margin-left: 25px;
`

const Navbar = () => {
    return (
        <Container>
            <Wrapper>
                <Left>
                    <Language>english</Language>
                    <SearchContainer>
                        <Input />
                        <SearchIcon style={{color: "gray", fontsize: 18}}/>
                    </SearchContainer>
                </Left>
                <Center><Logo>CASSIE</Logo></Center>
                <Right>
                    <MenuItem>REGISTER</MenuItem>
                    <MenuItem>SIGN IN</MenuItem>
                    <MenuItem>
                        <Badge badgeContent={4} color="primary">
                        <ShoppingCartOutlinedIcon/>
                        </Badge>
                    </MenuItem>
                </Right>
            </Wrapper>
        </Container>
    )
}

export default Navbar



 

 

 

import styled from "styled-components"

const Container = styled.div`
    height: 30px;
    background: teal;
    color: white;
`

export const Announcement = () => {
  return (
    <Container>
        Super Deal! Free Shipping on Orders Over $100!
    </Container>
  )
}

 
 
align-items: center; /* 아이템을 수직으로 중앙에 정렬
*/ justify-content: center; /* 아이템을 수평으로 중앙에 정렬 */
 
 

import styled from "styled-components"

const Container = styled.div`
    height: 30px;
    background: teal;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 500;
`

export const Announcement = () => {
  return (
    <Container>
        Super Deal! Free Shipping on Orders Over $100!
    </Container>
  )
}

 
position: absolute;를 사용하면 요소가 다른 요소와 더 이상 공간을 공유하지 않고 페이지 상에서 절대 위치에 배치됩니다. 반면에 position 속성을 지정하지 않은 요소는 문서 흐름(flow)에 따라 배치되며, 다른 요소와 공간을 공유합니다.

따라서 position: absolute;와 사용하지 않은 경우의 차이는 다음과 같습니다:

position: absolute;를 사용한 경우:

요소가 다른 요소에 영향을 주지 않고 절대 위치에 배치됩니다.
주어진 위치에 대한 top, right, bottom, left 속성을 사용하여 정확한 위치를 지정할 수 있습니다.
다른 요소와 겹치거나 다른 요소 위에 놓일 수 있으므로 주의가 필요합니다.
position 속성을 지정하지 않은 경우:

요소는 문서 흐름에 따라 배치되며, 다른 요소와 공간을 공유합니다.
다른 요소와의 관계에 따라 위치가 결정됩니다.
주로 요소가 흐름에 따라 배치되어야 하는 경우에 사용됩니다.
따라서 상황에 따라 position: absolute;를 사용하면 요소를 원하는 위치에 정확하게 배치할 수 있으며, 이를 통해 페이지 레이아웃을 더 세밀하게 제어할 수 있습니다. 하지만 position: absolute;를 남용하면 요소가 겹쳐 보이거나 페이지 레이아웃이 예상치 못한 방식으로 깨질 수 있으므로 주의가 필요합니다.
 

 
자식을 absolute 속성을 넣어주면 반드시 부모요소에는 position: relative를 넣어줘야하는거야?
ChatGPT

네, 정확한 위치 지정을 위해 position: absolute;를 사용하는 자식 요소를 가지고 있는 경우, 부모 요소에 position: relative;를 지정하는 것이 일반적으로 권장되는 방법입니다. 이렇게 함으로써 자식 요소는 부모 요소를 기준으로 위치가 결정됩니다.

position: absolute;는 요소가 문서 흐름에서 벗어나고 다른 요소의 위치에 상대적이 아닌 절대적인 위치를 갖게 만듭니다. 그러므로 position: relative;가 지정된 부모 요소를 기준으로 position: absolute;가 지정된 자식 요소가 배치됩니다.

이 방법을 사용하면 요소 간의 상대적인 위치를 조정할 때 레이아웃을 더 세밀하게 제어할 수 있습니다. 하지만 주의할 점은 지나치게 많은 요소에 position: absolute;를 사용하면 페이지 레이아웃이 복잡해지고 예상치 못한 결과가 발생할 수 있으므로 신중하게 사용해야 합니다.
 

 

 
 

 
&&는 조건부 연산자로 사용되고 있습니다. 이것은 JavaScript에서 자주 사용되며, 특히 JSX나 템플릿 리터럴과 같은 템플릿 언어에서 자주 볼 수 있는 방법 중 하나입니다.

여기서 &&는 논리 연산자로 작동하며, 왼쪽 피연산자가 true일 때 오른쪽 피연산자를 반환하고, 왼쪽 피연산자가 false일 때 false를 반환합니다.
 
또한, 삼항 연산자의 단축 버전으로 사용될 수 있습니다. 예를 들어, 조건에 따라 다른 값을 반환하고 싶을 때 사용합니다.

여기에서 left와 right 속성은 조건에 따라 설정됩니다. ArrowLeftOutlined 컴포넌트는 direction 속성이 "left"일 때 left: 10px;를 적용하고, ArrowRightOutlined 컴포넌트는 direction 속성이 "right"일 때 right: 10px;를 적용합니다.

즉, props.direction === "left" 조건이 참일 때 left: 10px;를 설정하고, props.direction === "right" 조건이 참일 때 right: 10px;를 설정합니다. 이렇게 하면 ArrowLeftOutlined 컴포넌트는 왼쪽에, ArrowRightOutlined 컴포넌트는 오른쪽에 각각 10px의 간격을 가지게 됩니다.
 
 

 


Background-color: transparent 도 있음 버튼 할 때 유용

슬라이드 만들 때 속성

overflow: hidden;

뷰포트 너비

translateX는 CSS의 transform 속성에서 사용되는 함수 중 하나입니다. 이 함수는 요소를 수평으로 이동시킬 때 사용됩니다. translateX 함수는 괄호 안에 이동할 거리를 지정하며, 이 거리는 기본 단위인 픽셀(px) 또는 다른 길이 단위로 지정할 수 있습니다.

예를 들어, transform: translateX(100px);은 해당 요소를 오른쪽으로 100픽셀만큼 이동시킵니다. 100wh는 뷰포트 너비(Viewport Width, vw)의 100%를 나타내므로, 이 코드는 현재 뷰포트의 너비만큼 요소를 오른쪽으로 이동시킵니다.

뷰포트
자바스크립트에서 "뷰포트(Viewport)"는 웹 페이지의 가시 영역을 나타냅니다.

화살표 arrow component에 z-index: 2 넣는 이유

화살표를 클릭하면 왼쪽 또는 오른쪽 이동하는 슬라이드를 만드는데 화살표가 const arrow 컴포넌트인데 여기에 왜 z-index: 2; 이렇게 설정을 해주는거야?


z-index: 2;는 화살표(arrow) 컴포넌트가 다른 요소들보다 높은 층위에 표시되도록 하는 CSS 속성입니다. 이렇게 설정하는 이유는 화살표가 슬라이드 위에 떠 있거나 강조되어야 하는 경우에 사용됩니다. 이것은 슬라이드와 화살표가 겹칠 때 화살표가 슬라이드 위에 표시되도록 하는 방법 중 하나입니다. z-index 값이 높을수록 해당 요소는 다른 요소들보다 앞쪽에 나타납니다.

state hook을 쓸거라고 함 and we are gonna decide our slide index
처음에는
const [slideIndex, setSlideIndex] = useState(0);

that’s because we’re gonna be using slide arrays.

상위폴더 src에 data.js 만들고 slideritems를 객체로 만들어줄 것

export sliderItems = [ {
    id:1,
    img:
    title:
    bg:
},

{}


]

이런 식으로 적고

Slider.jsx기존에 슬라이드 적어둔 거 다 지우고 import를 하는데 curly brackets 열어서 import

자바스크립트의 import 문에서 중괄호는 명명된(Named) 내보내기(Export)를 사용할 때 필요합니다.

뼈대 component는 그대로 쓰는데 속성을 중괄호로 해서 넣어주는거야.
슬라이드 만드는 컴포넌트는 기존에 3개 만들었던 거 중에 1개 남아있는 뼈대 그대로 씀

여기서 item이 eachItem을 뜻하는 말이잖아! 우리가 여기서 명명하는 거임
{ sliderItems.map((item)     }

여기에 뼈대 컴포넌트 넣을 때 이걸 감싸는 중괄호를 단축키로 그냥 그것만 내리면 되잖아…

그 다음에 <Slide bg={item.bg} />

이런 식으로 처리하면 끝


컴포넌트 항상 대문자다.
 

const Slide = styled.div`
`
const ImgContainer = styled.div`
`
const InfoContainer = styled.div`
`

 

 
 

 
 
Arrow 스타일드 컴포넌트의 right 속성을 늘릴수록 오른쪽 화살표가 왼쪽으로 이동하는 현상은 right 속성이 늘어남에 따라 컨테이너 내에서의 화살표 위치가 변하기 때문입니다. 이는 CSS의 position: absolute;를 사용할 때, right 속성을 늘리면 오른쪽으로부터 더 멀리 이동함을 의미합니다.

여기에 주의해야 할 중요한 점은, right 속성은 컨테이너 오른쪽 가장자리로부터의 거리를 나타냅니다. 따라서 right: 500px;로 설정하면 오른쪽 화살표가 컨테이너 오른쪽 가장자리로부터 500px 떨어진 위치에 나타납니다. 이로 인해 왼쪽 화살표는 오른쪽 화살표와 가까워질 수 있습니다.
 
 
일단 의도한대로 다 정리된 코드
 

import { ArrowLeftOutlined, ArrowRightOutlined } from '@mui/icons-material'
import styled from 'styled-components';


const Container = styled.div`
    width: 100%;
    height: 100vh;
    display: flex;
    background-color: coral;
    position: relative;
    left: 10px;
`;

const Arrow = styled.div`
    width: 50px;
    height: 50px;
    background-color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    left: ${props=> props.direction === "left" && "10px"};
    right: ${props=> props.direction === "right" && "10px"};
    margin: auto;
`

const Wrapper = styled.div`
    height: 100%
`


const Slide = styled.div`
    display: flex;
    align-items: center;
`
const ImgContainer = styled.div`
    flex:1;
`

const Image = styled.img`
`

const InfoContainer = styled.div`
flex:1;

`

const Slider = () => {
  return (
    <Container>
        <Arrow direction="left">
            <ArrowLeftOutlined />
        </Arrow>
        <Wrapper>
            <ImgContainer>
            </ImgContainer>
            <InfoContainer></InfoContainer>
        </Wrapper>
        <Arrow direction="right">
            <ArrowRightOutlined />
        </Arrow>
    </Container>
  )
}

export default Slider

 
의도한대로 안 나오는거 보니..
Wrapper가 slide를 감싸줘야했음 이게 맞음
 

import { ArrowLeftOutlined, ArrowRightOutlined } from '@mui/icons-material'
import styled from 'styled-components';


const Container = styled.div`
    width: 100%;
    height: 100vh;
    display: flex;
    background-color: coral;
    position: relative;
    left: 10px;
`;

const Arrow = styled.div`
    width: 50px;
    height: 50px;
    background-color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    left: ${props => props.direction === "left" && "10px"};
    right: ${props => props.direction === "right" && "10px"};
    margin: auto;
    cursor: pointer;
    opacity: 0.5;
`

const Wrapper = styled.div`
    height: 100%
`


const Slide = styled.div`
    width: 100vw;
    height: 100vh;
    display: flex;
    align-items: center;
`
const ImgContainer = styled.div`
    height: 100%;
    flex:1;
`

const Image = styled.img`
    height: 70%;
`

const InfoContainer = styled.div`
    flex:1;
    padding: 50px;

`
const Title = styled.h1`
    font-size: 70px;
`
const Desc = styled.p`
    margin: 50px 0px;
    font-size: 20px;
    font-weight: 500;
    letter-spacing: 3px;
`
const Button = styled.button`
`

const Slider = () => {
    return (
        <Container>
            <Arrow direction="left">
                <ArrowLeftOutlined />
            </Arrow>
            <Wrapper>
                <Slide>
                    <ImgContainer>
                    </ImgContainer>
                    <InfoContainer>
                        <Title>Title</Title>
                        <Desc>Desc</Desc>
                        <Button>SHOP NOW</Button>
                    </InfoContainer>
                </Slide>
            </Wrapper>
            <Arrow direction="right">
                <ArrowRightOutlined />
            </Arrow>
        </Container>
    )
}

export default Slider

 
처음에는 이렇게 되어있다가
 

 
 

 
flex 만 해주면 horizontal로 바뀜. 
 

 
okay also they are like that right now but i don't want to see beyond this

screen i'm just gonna move this slider when i click this button or this one

so i can prevent this overflowing to do that i will go to the container and i

will say overflow hidden

여기서 말하는 overflow가 웹페이지에서 무슨 말이야?

이 문맥에서 "overflow"는 웹페이지의 스크롤바와 관련된 CSS 속성을 가리킵니다. "overflow" 속성은 웹 요소 내에서 컨텐츠가 컨테이너의 영역을 벗어날 때 어떻게 처리할지를 지정하는 데 사용됩니다.

일반적으로 "overflow" 속성은 다음과 같은 값들을 가질 수 있습니다:

visible: 컨텐츠가 컨테이너를 벗어나도 스크롤바가 나타나지 않습니다.
hidden: 컨텐츠가 컨테이너를 벗어날 때, 컨테이너 외부로 보이지 않도록 숨깁니다.
scroll: 컨텐츠가 컨테이너를 벗어나면 스크롤바가 나타나고, 사용자는 스크롤바를 사용하여 숨겨진 컨텐츠를 볼 수 있습니다.
auto: 컨텐츠가 컨테이너를 벗어날 때만 스크롤바가 나타나고, 사용자가 스크롤바를 사용하여 숨겨진 컨텐츠를 볼 수 있습니다. 컨텐츠가 컨테이너 내에 모두 들어갈 경우 스크롤바가 나타나지 않습니다.
상황에 따라 "overflow: hidden"을 사용하면, 컨테이너 내의 컨텐츠가 컨테이너의 영역을 벗어날 때, 해당 컨텐츠를 숨기고 스크롤바를 나타내지 않도록 설정할 수 있습니다. 이렇게 하면 사용자가 스크롤바를 통해 컨텐츠를 확인하지 못하고, 컨테이너 내에서 컨텐츠가 넘치지 않도록 할 수 있습니다.
 
 

const Wrapper = styled.div`
    height: 100%;
    display: flex;
    transform: translateX(-100px);
`

이 것만 해도 이렇게 이동됨.
 

 
처음에는 useState를 안에 0으로 한다는데? 
 

statehook it's going to be 0. that's because we are going to be using slide arrays and it's going to be our first element second element and third
 
이걸 언급안했지만 이걸 해줘야지! 

import React, {useState} from 'react';

 
z-index가 원인...
절대 몰랐음....왼쪽화살표가 사라졌음. 
 
 

슬라이드에 애니메이션 걸어주기 
i will say transition i will say all one second or when i'm
half second and it's gonna be "ease" timing function let's see again
 
transition을 슬라이드를 다 감싸고 있는 Wrapper에다 걸어주는거다. 
 
여기서 1.5s "s"를 안 적어주면 효과 안 나타남.. 주의 할 것
 

const Wrapper = styled.div`
    height: 100%;
    display: flex;
    transform: translateX(${props => props.slideIndex * -100}vw);
    transition: all 1.5s ease;
`

 
 


 
Shipping Category Design
 
rafc : react function component
 



부모요소에 flex:1 속성을 넣어야합니다.

부모 컨테이너에 flex: 1 스타일을 적용하면 그 안에 있는 자식 요소들이 가용 가능한 공간을 동등하게 나누려고 시도합니다. 이는 자식 요소들이 비율에 맞게 크기를 조절하려는 동작입니다. 이것은 Flexbox 레이아웃 기술의 일부로, 자식 요소들을 비율에 따라 레이아웃하고 화면에 적합하게 맞추는 데 사용됩니다.


flex-wrap: wrap
flex 컨테이너는 모든 아이템을 하나의 행에 나란히 배치하려고 시도합니다. 그러나 "flex-wrap: wrap;"을 사용하면, flex 컨테이너 내의 아이템들이 가로 공간이 부족할 때 줄 바꿈을 허용합니다. 이것은 화면 크기가 작거나 아이템이 너무 많아서 모두 하나의 행에 넣을 수 없는 경우에 유용합니다.


부모 요소에 display: flex; 속성을 적용하면 해당 부모 요소는 Flexbox 레이아웃 컨테이너가 됩니다. 이때, 자식 요소들은 자동으로 Flexbox 아이템이 되며, 이를 통해 부모와 자식 요소 간의 레이아웃 및 정렬을 다루기가 편리해집니다.


flex는 부모요소에
자식 컴포넌트들은 부모 컴포넌트 내에서 설정된 Flexbox 속성에 따라 배치됩니다. 이로써 부모 컴포넌트 내의 자식 컴포넌트들을 수평 또는 수직으로 정렬하거나 공간 분배를 조절할 수 있습니다. 부모의 flex-direction, justify-content, align-items, align-self 등의 속성을 사용하여 자식 컴포넌트들의 배치 및 정렬을 제어할 수 있습니다.

기본적으로 Flexbox 아이템은 부모 Flex 컨테이너의 align-items 속성에 따라 수직으로 정렬됩니다. 그러나 align-self를 사용하면 개별 Flexbox 아이템이 부모의 align-items 설정을 무시하고 자체적인 수직 정렬을 갖게 됩니다.

효과를 계산할 때
작은 요소부터 먼저 효과 주고 그 다음 큰 영역으로 넘어감

 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
`
const Img = styled.img`
`
const Info = styled.div`
`
const Title = styled.h1`
`
const Button = styled.button`
`

export const Categoryitem = ({item}) => {
  return (
    <Container>
        <Img src={item.img}/>
        <Info>
            <Title>{item.title}</Title>
            <Button>SHOP NOW</Button>
        </Info>

    </Container>
  )
}

 

 

이해하신 대로, React 17 이상 버전에서는 import React from 'react' 문을 포함하지 않고도 컴포넌트 내에서 속성을 사용할 수 있습니다. 이전 React 버전에서는 import React from 'react' 문을 포함해야 했습니다. 하지만 React 17 이상에서는 React의 핵심 기능이 컴포넌트 파일에서 자동으로 사용 가능하도록 변경되었습니다.

따라서 다음과 같이 React 컴포넌트를 정의하고 속성을 사용할 수 있습니다:

 

위 코드에서는 import React from 'react'을 사용하지 않아도 컴포넌트를 정의하고 속성을 사용할 수 있습니다. 이것은 React 17 이상에서 가능한 것이며, 이전 버전에서는 import React from 'react'이 필요했습니다.

React 17 이상을 사용하는 경우에는 import React from 'react' 문을 생략할 수 있어서 코드를 더 간결하게 작성할 수 있습니다.

 

flex:1이 적용이 안되는 이유가 사이즈를 안줘서 그렇다. 

 

let's make these images a little bit smaller and move this information on this image
56:09
to do that i will write here flex 1 remember all these cards will be same
56:15
size but if you do that it's not going to work that because we didn't give any size for our image
56:22
so i will come here and say with a hundred percent

 

Container 안에 Image에 크기 속성 없음.

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    flex:1;
`
const Image = styled.img`
`
const Info = styled.div`
`
const Title = styled.h1`
`
const Button = styled.button`
`

export const Categoryitem = ({item}) => {
  return (
    <Container>
        <Image src={item.img}/>
        <Info>
            <Title>{item.title}</Title>
            <Info></Info>
            <Button>SHOP NOW</Button>
        </Info>

    </Container>
  )
}

 

 

 

 

 

vh와 %는 CSS 단위로, 요소의 높이(높이 값을 나타내는 데 사용되는)를 설정하는 데 사용됩니다. 그러나 두 단위 사이에 중요한 차이점이 있습니다.

% (퍼센트):

% 단위는 부모 요소의 크기에 상대적으로 설정됩니다. 예를 들어, 부모 요소의 높이가 200px인 경우, 자식 요소에 height: 50%를 설정하면 자식 요소의 높이는 100px이 됩니다. 즉, 상위 요소에 따라 크기가 조절됩니다.
vh (Viewport Height):

vh 단위는 브라우저의 뷰포트 높이에 상대적으로 설정됩니다. 뷰포트 높이는 브라우저 창의 높이를 나타내며, 1vh는 뷰포트 높이의 1%에 해당합니다. 예를 들어, 뷰포트 높이가 800px인 경우, height: 50vh를 가진 요소는 400px의 높이를 가집니다.
따라서, vh와 %의 주요 차이점은 상대성입니다. %는 부모 요소의 크기에 따라 크기가 조절되고, vh는 뷰포트 크기에 따라 크기가 조절됩니다. 따라서 어떤 단위를 선택할지는 디자인 요구사항 및 상황에 따라 다를 수 있습니다.

 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    flex:1;
    margin: 3px;
    height: 70vh;
`
const Image = styled.img`
    width: 100%;
    height: 100%;
    object-fit: cover;
 
`
const Info = styled.div`
`
const Title = styled.h1`
`
const Button = styled.button`
`

export const Categoryitem = ({item}) => {
  return (
    <Container>
        <Image src={item.img}/>
        <Info>
            <Title>{item.title}</Title>
            <Info></Info>
            <Button>SHOP NOW</Button>
        </Info>

    </Container>
  )
}

 

object-fit: cover;

 

네, 정확히 맞습니다. object-fit: cover;는 이미지의 크기를 유지하면서 부모 요소에 맞게 이미지를 조정하여 이미지가 비율을 유지하면서 깨지지 않도록 도와주는 CSS 속성입니다.

일반적으로 object-fit 속성은 이미지의 가로세로 비율(가로 너비 대비 세로 높이 비율)을 유지하면서 이미지를 조절합니다. cover 값은 이미지를 확대 또는 축소하여 부모 요소의 가로세로 비율에 맞게 조정하며, 이미지가 잘리지 않고 부모 요소를 완전히 덮도록 합니다. 그 결과 이미지가 비율을 유지하면서 부모 요소의 배경으로 완벽하게 맞게 표시됩니다.

 

 

 


okay so what i'm gonna do is giving width and height it's gonna be a hundred percent and a hundred percent basically it's gonna contain all our container.

 

 

 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    flex:1;
    margin: 3px;
    height: 70vh;
    position: relative;
`
const Image = styled.img`
    width: 100%;
    height: 100%;
    object-fit: cover;
 
`
const Info = styled.div`
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
`
const Title = styled.h1`
`
const Button = styled.button`
`

export const Categoryitem = ({item}) => {
  return (
    <Container>
        <Image src={item.img}/>
        <Info>
            <Title>{item.title}</Title>
            <Info></Info>
            <Button>SHOP NOW</Button>
        </Info>

    </Container>
  )
}

 

flex..안에서 또 디테일한 속성이 있지않나?

 

 

flex-direction: column; 

 

 

Info 컴포넌트가 중첩되서 그렇다.

 

import React from 'react'
import styled from 'styled-components'

const Container = styled.div`
    flex:1;
    margin: 3px;
    height: 70vh;
    position: relative;
`
const Image = styled.img`
    width: 100%;
    height: 100%;
    object-fit: cover;
 
`
const Info = styled.div`
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
`
const Title = styled.h1`
    color: white;
    margin-bottom: 20px;
`
const Button = styled.button`
    border: none;
    padding: 10px;
    background-color: white;
    color:gray;
    cursor: pointer;
    font-weight: 600;
`;

export const Categoryitem = ({item}) => {
  return (
    <Container>
        <Image src={item.img}/>
        <Info>
            <Title>{item.title}</Title>
            <Button>SHOP NOW</Button>
        </Info>

    </Container>
  )
}

 

import다시하기

unique key categoris 이런데 다 주기. 

 

 

 

styled.다음에 img 태그를 안해서 이미지가 안 불러와져서 고쳤는데...이렇게 뜸

 

import { FavoriteBorderOutlined, SearchOutlined, ShoppingCartOutlined } from '@mui/icons-material'
import React from 'react'
import styled from 'styled-components'


const Container = styled.div`
    flex:1;
    margin: 5px;
    min-width: 280px;
`

const Circle = styled.div`
`

const Image = styled.img`
`
const Info = styled.div`
`
const Icon = styled.div`
`

const Product = ({item}) => {
  return (
    <Container>

    <Circle/>
    <Image src={item.img}/>
    <Info>
        <Icon>
            <ShoppingCartOutlined/>
        </Icon>
        <Icon>
            <SearchOutlined></SearchOutlined>
        </Icon>
        <Icon>
            <FavoriteBorderOutlined/>
        </Icon>
    </Info>
    </Container>
  )
}

export default Product;

 

import React from 'react'
import { popularProducts } from '../data'
import Product from './Product'
import styled from 'styled-components'

const Container = styled.div`
  padding: 20px;
  display:flex;
`

const Products = () => {
  return (
    <Container>
    {popularProducts.map(item => (
        <Product item={item} key={item.id}/>
    ))}
    </Container>
  )
}

export default Products;

 

문제를 고쳐보기.

 

 

 

 

 

before

 

after

 

 

 

color 넣으면서 확인 부모 요소에 relative까지 넣어야 적용됨. 자식은 absolute.

 

import { FavoriteBorderOutlined, SearchOutlined, ShoppingCartOutlined } from '@mui/icons-material'
import React from 'react'
import styled from 'styled-components'


const Container = styled.div`
    flex:1;
    margin: 5px;
    min-width: 280px;
    height: 350px;
    position: relative;
    display: flex;
    align-items:center;
    justify-content: center;
    background-color: #f5fbfd;
`



const Image = styled.img`
    height: 75%;
`
const Info = styled.div`
    width: 100%;
    height: 100%;
    position: absolute;
    top:0;
    left:0;
    background-color: black;
    z-index:2;
`
const Icon = styled.div`
`

const Product = ({item}) => {
  return (
    <Container>
    <Image src={item.img}/>
    <Info>
        <Icon>
            <ShoppingCartOutlined/>
        </Icon>
        <Icon>
            <SearchOutlined></SearchOutlined>
        </Icon>
        <Icon>
            <FavoriteBorderOutlined/>
        </Icon>
    </Info>
    </Container>
  )
}

export default Product;

 

 

 

 

Icon 컴포넌트에 이렇게 해도...flex랑..뭔가 정중앙에 안감. 

 

import { FavoriteBorderOutlined, SearchOutlined, ShoppingCartOutlined } from '@mui/icons-material'
import React from 'react'
import styled from 'styled-components'


const Container = styled.div`
    flex:1;
    margin: 5px;
    min-width: 280px;
    height: 350px;
    position: relative;
    display: flex;
    align-items:center;
    justify-content: center;
    background-color: #f5fbfd;
`



const Image = styled.img`
    height: 75%;
`
const Info = styled.div`
    width: 100%;
    height: 100%;
    position: absolute;
    top:0;
    left:0;
    background-color: gray;
    z-index:2;
    display: flex;
    align-items: center;
    justify-content: center;
`
const Icon = styled.div`
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: white;
    display: flex;
    align-items: center;
    justify-contents: center;
`

const Product = ({item}) => {
  return (
    <Container>
    <Image src={item.img}/>
    <Info>
        <Icon>
            <ShoppingCartOutlined/>
        </Icon>
        <Icon>
            <SearchOutlined></SearchOutlined>
        </Icon>
        <Icon>
            <FavoriteBorderOutlined/>
        </Icon>
    </Info>
    </Container>
  )
}

export default Product;

justify-content: space-between;

 

s가 있고 없고 그냥 단축키 쓰기. 

 

 

스케일이 커짐

 

import { FavoriteBorderOutlined, SearchOutlined, ShoppingCartOutlined } from '@mui/icons-material'
import React from 'react'
import styled from 'styled-components'


const Container = styled.div`
    flex:1;
    margin: 5px;
    min-width: 280px;
    height: 350px;
    position: relative;
    display: flex;
    align-items:center;
    justify-content: center;
    background-color: #f5fbfd;
`



const Image = styled.img`
    height: 75%;
`
const Info = styled.div`
    width: 100%;
    height: 100%;
    position: absolute;
    top:0;
    left:0;
    background-color: gray;
    z-index:2;
    display: flex;
    align-items: center;
    justify-content: center;
`
const Icon = styled.div`
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: white;
    display: flex;
    align-items: center;
    justify-content: center;

    &:hover{
        background-color: #e9f5f5;
        transform: scale(1.1);
    }

`

const Product = ({item}) => {
  return (
    <Container>
    <Image src={item.img}/>
    <Info>
        <Icon>
            <ShoppingCartOutlined/>
        </Icon>
        <Icon>
            <SearchOutlined></SearchOutlined>
        </Icon>
        <Icon>
            <FavoriteBorderOutlined/>
        </Icon>
    </Info>
    </Container>
  )
}

export default Product;

 

Products - > Product

Products의 prop의 Product로


justify-content: space-between;


margin은 바깥에 영역을 줘서 넓히는거 
Icon에서 margin이 영역 바깥쪽에 있는거지? 10px를 준거지?

margin은 그 공간을 주고 싶은 요소에 넣는거다. 

네, 정확히 맞습니다. Icon 컴포넌트에서 margin: 10px;을 지정하면 아이콘 요소 주위에 10px의 마진이 추가됩니다. 이것은 아이콘 요소와 인접한 다른 요소와의 간격을 조절하는 데 사용됩니다. 아이콘 요소 주위에 10px의 마진을 가지게 되므로 아이콘 간에 간격을 조절하거나 레이아웃을 보다 시각적으로 조절할 수 있습니다.

따라서 margin: 10px;은 아이콘 요소 주위에 10px의 마진을 추가하는 효과를 가지고 있습니다. 이것은 아이콘 요소를 다른 내용으로부터 떨어뜨리고, 아이콘 간에도 간격을 만드는 데 사용될 수 있습니다.

 

 

 

처음에는 안 보이게하다가, 마우스가 호버되면 보이게하려고 
일다 Info에 opacity 0로 해놓고 

 

 

 

 

 


flex: 8;와 flex: 1;은 같은 Input 요소 내에서 사용되며, Flexbox 레이아웃을 설정하는 데 사용됩니다. 그러나 두 속성의 차이는 얼마나 많은 공간을 각각의 요소가 차지하는지를 나타내는 것입니다.

flex: 8;: 이 경우, Input 요소가 가용한 공간 중 8/9를 차지합니다. 다시 말해, Input 요소는 더 많은 공간을 가지며, 다른 요소에 비해 넓은 영역을 차지합니다.

flex: 1;: 이 경우, Button 요소가 가용한 공간 중 1/9를 차지하고, Input 요소가 나머지 8/9의 공간을 차지합니다. 다시 말해, Button 요소는 더 좁은 영역을 가지며, Input 요소에 비해 좁은 영역을 차지합니다.

Flexbox에서 flex 속성은 요소가 가용한 공간을 어떻게 나눌지를 결정하는데 사용됩니다. 이때 각 요소의 flex 값에 따라 공간 분배가 결정됩니다. 만약 모든 자식 요소의 flex 값이 1이라면, 가용한 공간은 동일하게 분배됩니다. 그러나 flex 값이 다른 경우, 더 큰 flex 값을 가진 요소가 더 많은 공간을 차지하게 됩니다.

flex 값을 조정하여 각 요소가 필요한 공간을 할당하고 원하는 레이아웃을 만들 수 있습니다.

 

footer 높이가 없으니까 화면에 구현이 안되는거임.

 

여기서 뭘 고쳐야 화면에 구현할 수 있는지 확인하기

 

import { Facebook, Instagram } from '@mui/icons-material'
import React from 'react'
import styled from 'styled-components';


const Container = styled.div`
   display: flex;
`
const Left = styled.div`
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px;
`

const Logo = styled.h1`
`;

const Desc = styled.p`
 
`;

const SocialContainer = styled.div`
  display: flex;
`;

const SocialIcon = styled.div`

`;


const Center = styled.div`
flex: 1;
`

const Right = styled.div`
flex: 1;
`

const Footer = () => {
  return (
    <Container>
     <Left>
        <Logo>Cassie.</Logo>
        <Desc> There are many variations of passages of Lorem Ipsum available, but
          the majority have suffered alteration in some form, by injected
          humour, or randomised words which don’t look even slightly believable.</Desc>
          <SocialContainer>
            <SocialIcon>
                <Facebook/>
                <Instagram/>

            </SocialIcon>

          </SocialContainer>
     </Left>
    <Center></Center>
     <Right></Right>
    </Container>
  )
}

export default Footer;

 

icon이 블랙이여서..안보였음

 


import { FacebookOutlined, Instagram } from '@mui/icons-material';
import React from 'react'
import styled from 'styled-components';


const Container = styled.div`
   display: flex;
`
const Left = styled.div`
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px;

`

const Logo = styled.h1`
`;

const Desc = styled.p`
    margin: 20px 0px;
`;

const SocialContainer = styled.div`
  display: flex;
`;

const SocialIcon = styled.div`
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: black;
`;


const Center = styled.div`
flex: 1;
`

const Right = styled.div`
flex: 1;
`

const Footer = () => {
  return (
    <Container>
     <Left>
        <Logo>Cassie.</Logo>
        <Desc> There are many variations of passages of Lorem Ipsum available, but
          the majority have suffered alteration in some form, by injected
          humour, or randomised words which don’t look even slightly believable.</Desc>
          <SocialContainer>
            <SocialIcon>
                <FacebookOutlined/>
                <Instagram/>
            </SocialIcon>
          </SocialContainer>
     </Left>
    <Center></Center>
     <Right></Right>
    </Container>
  )
}

export default Footer;

 

아..SocialIcon를 태그를 계속 태그를 만들어야했네 color 속성도 SocialIcon에 넣어야함


import { FacebookOutlined, Instagram, Twitter } from '@mui/icons-material';
import React from 'react'
import styled from 'styled-components';


const Container = styled.div`
   display: flex;
`
const Left = styled.div`
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px;

`

const Logo = styled.h1`
`;

const Desc = styled.p`
    margin: 20px 0px;
`;

const SocialContainer = styled.div`
  display: flex;
`;

const SocialIcon = styled.div`
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: black;
    background-color: #${props => props.color};
`;


const Center = styled.div`
flex: 1;
`

const Right = styled.div`
flex: 1;
`

const Footer = () => {
    return (
        <Container>
            <Left>
                <Logo>Cassie.</Logo>
                <Desc> There are many variations of passages of Lorem Ipsum available, but
                    the majority have suffered alteration in some form, by injected
                    humour, or randomised words which don’t look even slightly believable.</Desc>
                <SocialContainer>
                    <SocialIcon color="3B5999">
                        <FacebookOutlined c />
                    </SocialIcon>
                    <SocialIcon  color="E4405F">
                        <Instagram />
                    </SocialIcon>
                    <SocialIcon color="55ACEE" >
                        <Twitter />
                    </SocialIcon>
                </SocialContainer>
            </Left>
            <Center></Center>
            <Right></Right>
        </Container>
    )
}

export default Footer;

 

이거 설명

아이콘들의 부모인 SocialIcon을 flex로 주고 수평 수직 수평을 줘야지 정중앙에 정렬됨. 

 

 

 

 

 

display: flex;
flex-wrap: wrap;

 

flex-wrap: wrap;은 Flexbox 레이아웃에서 사용되는 속성으로, 컨테이너의 자식 요소들이 가로로 나열되어 화면을 넘어갈 때 자동으로 아래 행으로 줄바꿈하도록 지정하는 것을 의미합니다.

 

listitem에 width 50%넣긴 전까지는 이랬는데

 

 

이렇게됨

 

 

일단 여기까지

 


import { FacebookOutlined, Instagram, MailOutline, Phone, Room, Twitter } from '@mui/icons-material';
import React from 'react'
import styled from 'styled-components';


const Container = styled.div`
   display: flex;
`
const Left = styled.div`
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px;

`

const Logo = styled.h1`
`;

const Desc = styled.p`
    margin: 20px 0px;
`;

const SocialContainer = styled.div`
    display: flex;
 
`;

const SocialIcon = styled.div`
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: black;
    background-color: #${props => props.color};
    display: flex;
    align-items:center;
    justify-content: center;
 
`;


const Center = styled.div`
    flex: 1;
    padding: 20px;
`

const Title = styled.h3`
    margin-bottom: 30px;
`

const List = styled.ul`
    margin:0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
`

const ListItem = styled.li`
    width: 50%;
`



const Right = styled.div`
flex: 1;
`

const ContactItem = styled.div`
`


const Payment = styled.img`
`;


const Footer = () => {
    return (
        <Container>
            <Left>
                <Logo>Cassie.</Logo>
                <Desc> There are many variations of passages of Lorem Ipsum available, but
                    the majority have suffered alteration in some form, by injected
                    humour, or randomised words which don’t look even slightly believable.</Desc>
                <SocialContainer>
                    <SocialIcon color="3B5999">
                        <FacebookOutlined c />
                    </SocialIcon>
                    <SocialIcon color="E4405F">
                        <Instagram />
                    </SocialIcon>
                    <SocialIcon color="55ACEE" >
                        <Twitter />
                    </SocialIcon>
                </SocialContainer>
            </Left>
            <Center>
                <Title>Useful Links</Title>
                <List>
                    <ListItem>Home</ListItem>
                    <ListItem>Cart</ListItem>
                    <ListItem>Man Fashion</ListItem>
                    <ListItem>Woman Fashion</ListItem>
                    <ListItem>Accessories</ListItem>
                    <ListItem>My Account</ListItem>
                    <ListItem>Order Tracking</ListItem>
                    <ListItem>Wishlist</ListItem>
                    <ListItem>Wishlist</ListItem>
                    <ListItem>Terms</ListItem>
                </List>
            </Center>
            <Right>
                <Title>Contact</Title>
                <ContactItem>
                    <Room /> South Korea, Seoul
                </ContactItem>
                <ContactItem>
                    <Phone /> +82 234 56 78
                </ContactItem>
                <ContactItem>
                    <MailOutline  /> dudnfsla1@naver.com
                </ContactItem>
                <Payment src="https://i.ibb.co/Qfvn4z6/payment.png" />
            </Right>
        </Container>
    )
}

export default Footer;

 

 

 


import { FacebookOutlined, Instagram, MailOutline, Phone, Room, Twitter } from '@mui/icons-material';
import React from 'react'
import styled from 'styled-components';


const Container = styled.div`
   display: flex;
`
const Left = styled.div`
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 20px;

`

const Logo = styled.h1`
`;

const Desc = styled.p`
    margin: 20px 0px;
`;

const SocialContainer = styled.div`
    display: flex;
 
`;

const SocialIcon = styled.div`
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: black;
    background-color: #${props => props.color};
    display: flex;
    align-items:center;
    justify-content: center;
 
`;


const Center = styled.div`
    flex: 1;
    padding: 20px;
`

const Title = styled.h3`
    margin-bottom: 30px;
`

const List = styled.ul`
    margin:0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
`

const ListItem = styled.li`
    width: 50%;
`



const Right = styled.div`
    flex: 1;
    margin-top: 20px;
`

const ContactItem = styled.div`
    margin-bottom: 20px;
    display: flex;
    align-item: center;
`


const Payment = styled.img`
`;


const Footer = () => {
    return (
        <Container>
            <Left>
                <Logo>Cassie.</Logo>
                <Desc> There are many variations of passages of Lorem Ipsum available, but
                    the majority have suffered alteration in some form, by injected
                    humour, or randomised words which don’t look even slightly believable.</Desc>
                <SocialContainer>
                    <SocialIcon color="3B5999">
                        <FacebookOutlined c />
                    </SocialIcon>
                    <SocialIcon color="E4405F">
                        <Instagram />
                    </SocialIcon>
                    <SocialIcon color="55ACEE" >
                        <Twitter />
                    </SocialIcon>
                </SocialContainer>
            </Left>
            <Center>
                <Title>Useful Links</Title>
                <List>
                    <ListItem>Home</ListItem>
                    <ListItem>Cart</ListItem>
                    <ListItem>Man Fashion</ListItem>
                    <ListItem>Woman Fashion</ListItem>
                    <ListItem>Accessories</ListItem>
                    <ListItem>My Account</ListItem>
                    <ListItem>Order Tracking</ListItem>
                    <ListItem>Wishlist</ListItem>
                    <ListItem>Wishlist</ListItem>
                    <ListItem>Terms</ListItem>
                </List>
            </Center>
            <Right>
                <Title>Contact</Title>
                <ContactItem>
                    <Room /> South Korea, Seoul
                </ContactItem>
                <ContactItem>
                    <Phone /> +82 234 56 78
                </ContactItem>
                <ContactItem>
                    <MailOutline /> dudnfsla1@naver.com
                </ContactItem>
                <Payment src="https://i.ibb.co/Qfvn4z6/payment.png" />
            </Right>
        </Container>
    )
}

export default Footer;

 

반응형