8.  수정 - 제목, 내용만

  • DAO에 수정하는 updateOne() 메서드 작성
  • 테스트 코드 작성 후 테스트
  • Service 작업
  • 컨트롤러에 modify 추가
  • modify.jsp 작성
public interface BoardMapper {

    void insert(BoardVO boardVO); // DB 저장하는 메소드

    List<BoardVO> selectAll();

    BoardVO selectOne(Integer no);

    void updateHit(Integer no);

    void updateOne(BoardVO boardVO);
}
    <update id="updateOne">
        UPDATE tbl_board SET title = #{title}, content= #{content} WHERE no = #{no}
    </update>
    @Test
    public void updateOne() {
        Integer no = 8;
        BoardVO boardVO = BoardVO.builder()
                .no(no)
                .title("수정")
                .content("수정된 내용...")
                .build();

        boardMapper.updateOne(boardVO);
        log.info(boardMapper.selectOne(no));
    }

public interface BoardService {

    void register(BoardDTO boardDTO);

    List<BoardDTO> getAll();

    BoardDTO getOne(Integer no);

    void updateOne(BoardDTO boardDTO);
}
    @Override
    public void updateOne(BoardDTO boardDTO) {
        log.info("update...");

        BoardVO boardVO = modelMapper.map(boardDTO, BoardVO.class);
        log.info(boardVO);
        boardMapper.updateOne(boardVO);

    }
    @PostMapping("/modify")
    public String modify(@Valid BoardDTO boardDTO,
                         BindingResult bindingResult,
                         RedirectAttributes redirectAttributes) {

        if (bindingResult.hasErrors()) {
            // 유효성 검사 결과 에러가 있으면 수정 페이지로 돌아감
            log.info("has error");

            redirectAttributes.addFlashAttribute("errors", bindingResult.getAllErrors());
            redirectAttributes.addAttribute("no", boardDTO.getNo());
            return "redirect:/board/modify";
        }
        boardService.updateOne(boardDTO);
        return "redirect:/board/read?no=" + boardDTO.getNo();
    }
<div class="card-body">
    <form action="/board/modify" method="post">
    <input type="hidden" name="no" value="${dto.no}">
    <br>
    <div class="input-group">
        <span class="input-group-text">Title</span>
            <input type="text" name="title" class="form-control" value="${dto.title}">
    </div><br>
    <div class="input-group">
        <span class="input-group-text">Content</span>
        <textarea name="content" class="form-control">${dto.content}</textarea>
    </div><br>
    <div class="input-group">
        <span class="input-group-text">Writer</span>
        <input type="text" name="writer" class="form-control" value="${dto.writer}" readonly>
    </div><br>
    <div class="input-group">
        <span class="input-group-text">Date</span>
        <input type="date" name="dueDate" class="form-control" value="${dto.addDate}" readonly>
    </div><br>
    <div class="my-4">
        <div class="float-end">
            <button type="button" class="btn btn-danger">Remove</button>
            <button type="button" class="btn btn-primary">Modify</button>
            <button type="button" class="btn btn-secondary">List</button>
        </div>
    </div>
    </form>
    
    <script>
        const serverValidResult = {};
        <c:forEach items="${errors}" var="error">
            serverValidResult['${error.getField()}'] = '${error.defaultMessage}';
        </c:forEach>
        console.log(serverValidResult);
    </script>
                    
    <script>
        const frmModify = document.querySelector('form');
        document.querySelector('.btn-danger').addEventListener('click', function () {
            frmModify.action = '/board/remove';
            frmModify.method = 'post';
            frmModify.submit();
        });
        document.querySelector('.btn-primary').addEventListener('click', function () {
            frmModify.action = '/board/modify';
            frmModify.method = 'post';
            frmModify.submit();
        });
        document.querySelector('.btn-secondary').addEventListener('click', function (e) {
            self.location = `/board/list?${boardDTO.link}`;
        });
    </script>
</div>

 


 

9.  삭제

  • DAO에 삭제하는 deleteOne() 메서드 작성
  • 테스트 코드 작성 후 테스트
  • Service 작업
  • 컨트롤러에 remove 추가
public interface BoardMapper {

    void insert(BoardVO boardVO); // DB 저장하는 메소드

    List<BoardVO> selectAll();

    BoardVO selectOne(Integer no);

    void updateHit(Integer no);

    void updateOne(BoardVO boardVO);

    void deleteOne(Integer no);
}
    <delete id="deleteOne">
        DELETE FROM tbl_board WHERE no = #{no}
    </delete>
    @Test
    public void deleteOne() {
        Integer no = 8;
        BoardVO boardVO = boardMapper.selectOne(no);
        log.info(boardVO);

        boardMapper.deleteOne(no); // 삭제

        boardVO = boardMapper.selectOne(no);
        log.info(boardVO);
    }

public interface BoardService {

    void register(BoardDTO boardDTO);

    List<BoardDTO> getAll();

    BoardDTO getOne(Integer no);

    void updateOne(BoardDTO boardDTO);

    void deleteOne(Integer no);

}
    @Override
    public void deleteOne(Integer no) {
        boardMapper.deleteOne(no);
    }
    @PostMapping("/remove")
    public String remove(Integer no, RedirectAttributes redirectAttributes) {
        log.info("-----remove----");
        log.info("no: " + no);

        boardService.deleteOne(no);
        return "redirect:/board/list";
    }

 

 


 

10.  비밀번호 확인

  • PasswdVO 작성
  • BoardMapper 인터페이스 작성
  • BoardMapperxml 작성
  • BoardMapperTest 클래스 작성
  • PasswdDTO 작성
  • BoardService 작성
  • BoardServiceImpl 작성
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class PasswdVO {
    private int no;
    private String passwd;
}
public interface BoardMapper {

    ...

    BoardVO selectOneByPasswd(PasswdVO passwdVO);
}
    <select id="selectOneByPasswd" resultType="com.example.spring_ex_01_2404.domain.BoardVO">
        SELECT * FROM tbl_board WHERE no = #{no} AND passwd = SHA2(#{passwd}, 256)
    </select>
    @Test
    public void selectOneByPasswd() {
        PasswdVO passwdVO = PasswdVO.builder()
                .no(12)
                .passwd("1234").build();
        BoardVO boardVO = boardMapper.selectOneByPasswd(passwdVO);

        log.info(boardVO);
    }

@ToString
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PasswdDTO {
    private Integer no;
    private String passwd;
}
public interface BoardService {
    ...
    
    boolean isCurrentPasswd(PasswdDTO passwdDTO);
}
 @Override
    public boolean isCurrentPasswd(PasswdDTO passwdDTO) {
        PasswdVO passwdVO = modelMapper.map(passwdDTO, PasswdVO.class);

        return boardMapper.selectOneByPasswd(passwdVO) != null;
    }
    @Test
    public void isCurrentPasswd() {
        PasswdDTO passwdDTO = PasswdDTO.builder()
                .no(12)
                .passwd("1234").build();
        log.info(boardService.isCurrentPasswd(passwdDTO));
    }

 

JSP 코드 - 수정 or 삭제에 따라 버튼 내용 및 문구 타이틀 변경 추가
 <div class="card-body">
    <h3>${reason == "incorrect" ? "틀린 비밀번호 입니다." : "비밀번호를 입력해주세요!"}</h3>
    <form action="/board/passwd" method="post">
        <input type="hidden" name="no" value="${no}">
        <input type="hidden" name="mode" value="${mode}">
        <div class="input-group">
            <span class="input-group-text">Password</span>
            <input type="password" name="passwd" placeholder="비밀번호">
        </div><br>
        <div class="my-4">
            <div class="float-end">
                <button type="submit" class="btn btn-danger">${mode == "remove" ? "삭제" : "수정"}</button>
            </div>
        </div>
    </form>
</div>

 

Controller - 수정, 삭제 하기 전 비밀번호 확인 코드
    @GetMapping("/modify")
    public String modify(Integer no, Model model,
                       HttpServletRequest request,
                       RedirectAttributes redirectAttributes) {

        // 1. 세션에 저장된 비밀번호를 불러옴.
        HttpSession session = request.getSession();
        String passwd = (String) session.getAttribute("passwd");

        // 2. 비밀번호가 없으면 비밀번호 입력 페이지로 리다이렉트
        if (passwd == null || passwd.isEmpty()) {
            redirectAttributes.addAttribute("no", no);
            redirectAttributes.addAttribute("mode", "modify");
            return "redirect:/board/passwd";
        }

        // 3. 비밀번호가 틀리면 비밀번호 입력 페이지로 리다이렉트
        if (!boardService.isCurrentPasswd(PasswdDTO.builder().no(no).passwd(passwd).build())) {
            session.removeAttribute("passwd");
            redirectAttributes.addAttribute("no", no);
            redirectAttributes.addAttribute("mode", "modify");
            redirectAttributes.addFlashAttribute("reason", "incorrect");
            return "redirect:/board/passwd";
        }

        BoardDTO boardDTO = boardService.getOne(no);
        model.addAttribute("dto", boardDTO);
        
        return "/board/modify";
    }

    @RequestMapping("/remove")
    public String remove(Integer no, HttpServletRequest request, RedirectAttributes redirectAttributes) {

        // 1. 세션에 저장된 비밀번호를 불러옴.
        HttpSession session = request.getSession();
        String passwd = (String) session.getAttribute("passwd");

        // 2. 비밀번호가 없으면 비밀번호 입력 페이지로 리다이렉트
        if (passwd == null || passwd.isEmpty()) {
            redirectAttributes.addAttribute("no", no);
            redirectAttributes.addAttribute("mode", "remove");
            return "redirect:/board/passwd";
        }

        // 3. 비밀번호가 틀리면 비밀번호 입력 페이지로 리다이렉트
        if (!boardService.isCurrentPasswd(PasswdDTO.builder().no(no).passwd(passwd).build())) {
            session.removeAttribute("passwd");
            redirectAttributes.addAttribute("no", no);
            redirectAttributes.addAttribute("mode", "remove");
            redirectAttributes.addFlashAttribute("reason", "incorrect");
            
            return "redirect:/board/passwd";

        }

        // 4. 게시물 삭제
        log.info("-----remove----");
        boardService.deleteOne(no);

        // 5. 삭제 후 비밀번호 삭제
        session.removeAttribute("passwd");

        return "redirect:/board/list";
    }

    // 비밀번호 입력 페이지
    @GetMapping("/passwd")
    public void passwd(Integer no, String mode, Model model) {
        model.addAttribute("no", no);
        model.addAttribute("mode", mode);
    }

    @PostMapping("/passwd")
    public String passwdPost(Integer no, String mode, String passwd, HttpServletRequest request,
                             RedirectAttributes redirectAttributes) {
        log.info("...passwdPost()");
        log.info(mode);

        // 1. 전달받은 비밀번호를 세션에 저장
        HttpSession session = request.getSession();
        session.setAttribute("passwd", passwd);

        // 2. 해당 처리 페이지로 리다이렉트
        redirectAttributes.addAttribute("no", no);
        return "redirect:/board/" + mode;
    }

 

 

 

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

 


1.  프로젝트의 구현 목표와 준비

  • 검색과 필터링을 적용할 수 있는 화면을 구성하고 MyBatis의 동적 쿼리를 이용해서 상황에 맞는 Todo들을 검색
  • 새로운 Todo를 등록할 때 문자열, boolean, LocalDate를 자동으로 처리
  • 목록에서 조회 화면으로 이동할 때 모든 검색, 필터링, 페이징 조건을 유지하도록 구성
  • 조회 화면에서는 모든 조건을 유지한 채로 수정 / 삭제 화면으로 이동하도록 구성
  • 삭제 시에는 다시 목록 화면으로 이동
  • 수정 시에는 다시 조회 화면으로 이동하지만, 검색, 필터링, 페이징 조건은 초기화

(1) 프로젝트의 준비

build.gradle 설정 코드
    // 1. 스프링 관련
    // https://mvnrepository.com/artifact/org.springframework/spring-core
    implementation 'org.springframework:spring-core:5.3.30'
    implementation 'org.springframework:spring-context:5.3.30'
    implementation 'org.springframework:spring-test:5.3.30'
    implementation 'org.springframework:spring-webmvc:5.3.30'

    implementation 'org.springframework:spring-jdbc:5.3.30'
    implementation 'org.springframework:spring-tx:5.3.30'

 
    // 2. JSTL   
    // https://mvnrepository.com/artifact/javax.servlet/jstl
    implementation 'javax.servlet:jstl:1.2'


    // 3. MyBatis / MySQL / HikariCP 관련
    // https://mvnrepository.com/artifact/mysql/mysql-connector-java
    implementation 'mysql:mysql-connector-java:8.0.33'
    // https://mvnrepository.com/artifact/com.zaxxer/HikariCP
    implementation 'com.zaxxer:HikariCP:5.0.1'
    // https://mvnrepository.com/artifact/org.mybatis/mybatis
    implementation 'org.mybatis:mybatis:3.5.9'
    // https://mvnrepository.com/artifact/org.mybatis/mybatis-spring
    implementation 'org.mybatis:mybatis-spring:2.0.7'


    // 4. DTO와 VO의 변환을 위한 ModelMapper
    // https://mvnrepository.com/artifact/org.modelmapper/modelmapper
    implementation 'org.modelmapper:modelmapper:3.0.0'


    // 5. DTO 검증을 위한 validate 관련 라이브러리
    // https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator
    implementation 'org.hibernate.validator:hibernate-validator:6.2.1.Final'

 


 

(2) 프로젝트의 폴더 / 패키지 구조

테이블 생성
CREATE TABLE `tbl_todo` (
    `tno` int auto_increment PRIMARY KEY,
    `title` varchar(100) not null,
    `dueDate` date not null,
    `writer` varchar(50) not null,
    `finished` tinyint default 0
)

 

패키지 구조

 


 

(3) ModelMapper 설정과 @Configuration

👩🏻‍💻  프로젝트 개발에는 DTO를 VO로 변환하거나 VO를 DTO로 변환해야 하는 작업이 빈번하므로 이를 처리하기 위해서 ModelMapper를 스프링의 빈으로 등록해서 처리

  • config패키지에  ModelMapperConfig 클래스 생성
  • ModelMapperConfig는 @Configuration을 이용
  • @Configuration은 해당 클래스가 스프링 빈에 대한 설정을 하는 클래스임을 명시
@Configuration
public class ModelMapperConfig {
    @Bean
    public ModelMapper getMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
                .setFieldMatchingEnabled(true)
                .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
                .setMatchingStrategy(MatchingStrategies.STRICT);
        return modelMapper;
    }
}

 

  ✓  ModelMapperConfig 클래스 내에는 getMapper()라는 메서드가 ModelMapper를 반환하도록 설계
  ✓  getMapper() 선언부에 있는 @Bean 어노테이션은 해당 메서드의 실행 결과로 반환된 객체를 스프링의 빈으로 등록시키는 역할

 

  • ModelMapperConfig를 스프링 빈으로 인식할 수 있도록 root-context.xml에 config 패키지를 component-scan을 이용해서 추가
<context:component-scan base-package="com.example.spring_ex_01_2404.config"/>

 


2.  화면 디자인 - 부트 스트랩 적용

👩🏻‍💻   JSP 파일을 작성하기 전, 프로젝트의 시작 단계에서 화면 디자인을 결정하는 것이 좋음
         ✓
화면 디자인 없이 개발을 진행할 때는 나중에 코드를 다시 입혀야 하는 작업을 할 수도 있기 때문
👩🏻‍💻 
최근에는 부트스트랩 (bootstrap)이나 머터리얼(Material Design)과 같이 쉽게 웹 화면을 디자인할 수 있는 라이브러리들 덕분에 전문적인 웹 디자이너의 도움 없이도 어느정도 완성도가 있는 디자인 작업이 가능해 짐

 

https://elements.envato.com/web-templates/site-templates

 

HTML Website Templates - Envato Elements

Browse our Collection of fully customizable HTML templates. Get Unlimited Downloads with a subscription with Envato Elements.

elements.envato.com

 

📌  webapp의 resources 폴더에 test.html을 작성해서 부트스트랩을 적용하는 페이지를 작성

 

✓  부트스트랩의 화면 구성에는 container와 row를 이용


✓  Card 컴포넌트 적용하기

    부트스트랩에는 화면을 쉽게 제작할 수 있는 여러 종류의 컴포넌트를 제공
    이중에서 Card라는 컴포넌트를 적용해서 현재의 화면에서 Content라는 영역을 변경


✓  Navbar 컴포넌트의 적용
    화면 상단에는 간단한 메뉴를 보여줄 수 있는 Nav 혹은 Navbar 컴포넌트를 적용
    공식 문서의 Navbar의 예제를 선택해서 Header 라고 출력되는 부분에 적용


✓  Footer 처리
    맨 아래 <div class="row">에는 간단한 <footer>를 적용
    해당 <div>를 맨 아래쪽으로 고정하기 위해서 fixed-bottom을 적용
    내용이 많은 경우에는 Footer 영역으로 인해 가려질 수 있는 부분이 있으므로 z-index 값은 음수로 처리해서 가려질 수 있도록 구성

 

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

    <title>Hello, world!</title>
</head>

<body>
<div class="container-fluid">
    <div class="row">
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">Navbar</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
                    <div class="navbar-nav">
                        <a class="nav-link active" aria-current="page" href="#">Home</a>
                        <a class="nav-link" href="#">Features</a>
                        <a class="nav-link" href="#">Pricing</a>
                        <a class="nav-link disabled">Disabled</a>
                    </div>
                </div>
            </div>
        </nav>
        
        <div class="row content">
            <div class="col">
                <div class="card">
                    <div class="card-header">
                        Featured
                    </div>
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                        <a href="#" class="btn btn-primary">Go somewhere</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <div class="row content">
        <h1>Content</h1>
    </div>
    <div class="row footer">
        <div class="row fixed-bottom" style="z-index: -100">
            <footer class="py-1 my-1">
                <p class="tab-content text-muted">Footer</p>
            </footer>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
        crossorigin="anonymous"></script>

</body>
</html>

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  localStorage 객체

 

👾  웹 브라우저에 데이터를 저장하는 객체

👾  localStorage 객체 처럼 웹 브라우저가 제공해주는 기능을 웹 API 라고 부른다.

메소드 설명
localStorage.getItem(키) 저장된 값을 추출. 없으면 'null' 이 반환
localStorage.setItem(키, 값) 값을 저장
localStorage.removeItem(키) 특정 키의 값을 제거
localSorage.clear() 저장된 모든 값을 제거

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .hidden {
        display: none;
    }
</style>

<body>
<form id="login-form"> <!-- input 유효성 검사 작동 위해 form 안에 들어가 있어야 함 -->
    <input
            required
            maxlength="15"
            type="text"
            placeholder="What is your name?" />
    <input type="submit" value="Log In">
</form>
<h1 id="greeting" class="hidden"></h1>
<script src="app.js"></script>

</body>
</html>
const loginForm = document.querySelector('#login-form');
const loginInput = document.querySelector('#login-form input');
const greeting = document.querySelector("#greeting");

const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KYE = 'userName';
function onLoginSubmit(event) { // 방금 일어난 event에 대한 정보를 지닌 argument를 채워넣음
    // form을 submit 하면 브라우저는 기본적으로 페이지를 새로고침 함
    event.preventDefault(); // 브라우저 기본 동작 막음 (새로고침 x)
    const userName = loginInput.value; // 입력받은 값 변수에 저장
    loginForm.classList.add(HIDDEN_CLASSNAME); // 입력받은 후 폼 형태 숨기기
    localStorage.setItem(USERNAME_KYE, userName); // (키,값) 형태로 저장
    paintGreetings(userName); // h1 태그 안의 텍스트 불러옴
}

function paintGreetings (userName) { // h1 태그 안의 텍스트 불러오는 함수
    greeting.innerText = `Hello ${userName}`;
    greeting.classList.remove(HIDDEN_CLASSNAME); // 인사말 숨기는 속성 제거
}

const savedUsername = localStorage.getItem(USERNAME_KYE);

if (savedUsername === null) { // 이름이 저장되어 있지 않을 떄
    loginForm.classList.remove(HIDDEN_CLASSNAME); // 로그인 폼 숨기는 속성 제거
    loginForm.addEventListener('submit', onLoginSubmit);
} else { // 이름이 저장되어 있을 떄
    paintGreetings(savedUsername);
}

 

 

웹 API 관련 참고 사이트

https://developer.mozilla.org/ko/docs/Web/API 

 

Web API | MDN

웹 코드를 작성한다면 많은 API를 사용할 수 있습니다. 아래 목록은 웹 앱이나 웹 사이트를 만들 때 사용할 수 있는 모든 인터페이스(객체의 유형)입니다.

developer.mozilla.org

 

 

 

[ 내용 참고 : 책 '혼자 공부하는 자바스크립트' 및 노마드 코더 강의 ]


 

1.  목록 스타일

🍋  목록 태그에 스타일을 지정하는 방법으로 순서가 없는 항목(ul), 순서가 있는 항목(ol) 태그에 적용

 

1)   list-style-type 속성

 

  🥑  순서가 없는 항목 태그와 순서가 있는 항목 태그 앞에 나오는 블릿과 번호 스타일을 변경 

종류 설명 예시
disc 채운 원 모양
circle 빈 원 모양
square 채운 사각형 모양
decimal 1부터 시작하는 10진수 1, 2, 3...
decimal-leading-zero 앞에 0이 붙는 10진수 01, 02, 03...
lower-roman 로마 숫자 소문자 i, ii, iii ...
upper-roman 로마 숫자 대문자 I, II, III ...
lower-alpha 또는 lower-latin 알파벳 소문자 a, b, c...
upper-alpha 또는 upper-latin 알파벳 대문자 A, B, C...
none 불릿이나 숫자를 없앰  

 

순서 없는 태그 사용 예
<head>
    <style>
        .bullet_circle {
            list-style-type: circle; /* 빈 원으로 표시 */
        }
        .bullet_none {
            list-style-type: none; /* 블릿을 표시하지 않음 */
        }
    </style>
</head>
<body>
    <!--블릿 변경하기-->
    <ul class="bullet_circle">
        <li>회사소개</li>
        <li>생산설비</li>
        <li>제품소개</li>
        <li>온라인문의</li>
        <li>커뮤니티</li>
    </ul>
    <!--블릿 없애기-->
    <ul class="bullet_none">
        <li>회사소개</li>
        <li>생산설비</li>
        <li>제품소개</li>
        <li>온라인문의</li>
        <li>커뮤니티</li>
    </ul>
</body>

 

출력 결과


순서 있는 태그 사용 예
<head>
    <style>
        .style-num01 {
            list-style-type: lower-alpha; /* 알파벳 소문자 */
        }
        .style-num02 {
            list-style-type: upper-latin; /* 알파벳 대문자 */
        }
    </style>
</head>
<body>
    <!--블릿 변경하기-->
    <ol class="style-num01">
        <li>회사소개</li>
        <li>생산설비</li>
        <li>제품소개</li>
        <li>온라인문의</li>
        <li>커뮤니티</li>
    </ol>
    <!--블릿 없애기-->
    <ol class="style-num02">
        <li>회사소개</li>
        <li>생산설비</li>
        <li>제품소개</li>
        <li>온라인문의</li>
        <li>커뮤니티</li>
    </ol>
</body>

출력 결과


 

2) list-style-position 속성

 

list-style-position: inside | outside;

 

  🥑  전체 선택자(*)를 지정해서 마진과 패딩 값을 0으로 초기화하는 이유
         ▶️ 브라우저마다 기본 패딩값과 마진 값이 달라서 0으로 초기화 해서 사용

        ▶️ 이런 경우 블릿이나 번호타입을 지정해도 화면에 보이지 않음 

 

 🥑  list-style-position 속성 : 항목 번호가 보이지 않는 경우 들여쓰기 스타일 사용

  inside : 블릿이나 숫자를 안쪽으로 들여씀
  outside : 블릿이나 숫자를 밖으로 내어씀

 

<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .style-num01 {
            list-style-type: lower-alpha;
            list-style-position: inside;
        }

    </style>
</head>
<body>
    <ol class="style-num01">
        <li>회사소개</li>
        <li>생산설비</li>
        <li>제품소개</li>
        <li>온라인문의</li>
        <li>커뮤니티</li>
    </ol>

</body>

출력 결과


 

2.  표 스타일

1)  제목 위치를 정해주는 caption-side 속성

caption-side: top | bottom

 

top  :  캡션을 표 윗부분에 표시. 기본값
bottom :  캡션을 표 아랫부분에 표시.

 


 

2) 표 테두리를 그려 주는 border 속성

 

<head>    
    <style>
          table {
             caption-side: bottom;  /* 표 캡션 위치 */
             border:1px solid black;  /* 표 테두리는 검은 색 실선으로 */
          }
          td, th {
             border:1px dotted black;  /* 셀 테두리는 검은 색 점선으로 */
             padding:10px;  /* 셀 테두리와 내용 사이의 여백 */
             text-align:center;  /* 셀 내용 가운데 정렬 */
          }
       </style>
    </head>
    <body>    
       <h2>상품 구성</h2>
       <table>
          <caption>선물용과 가정용 상품 구성</caption>
          <thead>
             <tr>
                <th>용도</th>
                <th>중량</th>
                <th>갯수</t>
                <th>가격</th>
             </tr>
          </thead>
          <tbody>
             <tr>
                <td rowspan="2">선물용</td>
                <td>3kg</td>
                <td>11~16과</td>
                <td>35,000원</td>
             </tr>
             <tr>
                <td>5kg</td>
                <td>18~26과</td>
                <td>52,000원</td>
             </tr>
             <tr>
                <td rowspan="2">가정용</td>
                <td>3kg</td>
                <td>11~16과</td>
                <td>30,000원</td>
             </tr>   
             <tr>
                <td>5kg</td>
                <td>18~26과</td>
                <td>47,000원</td>
             </tr>
          </tbody>        
       </table>
    </body>

 


 

3)  셀 사이 여백을 지정하는 border-spacing 속성

 

🍯  table 태그와 border 속성을 사용했을 때 테두리와 셀들의 간격을 지정

border-spacing: 수평거리 수직거리

 

<head>
    <style>
        table {
            border: 2px solid black;
            border-spacing: 20px 40px;
        }
        td {
            padding: 15px;
            border: 1px dotted black;
            text-align: center;
        }
    </style>
</head>
<body>
    <table>
        <caption>표 스타일</caption>
        <tr>
            <td>시네마천국</td>
            <td>벤허</td>
        </tr>
        <tr>
            <td>11:00~14:30</td>
            <td>16:00~19:00</td>
        </tr>
    </table>
</body>

 

 

 


 

4)  표와 셀 테두리를 합쳐 주는 border-collapse 속성

 

🍯  표의 바깥 테두리와 셀의 각 테두리가 떨어져 있는 것을 합칠 것인지 그대로 둘 것인지 조정 가능
🍯  table과 td사이의 선값의 결합 유무를 결정하는 속성

collapse  :  표와 셀의 테두리를 합쳐 하나로 표시
separate  :  표와 셀 테두리를 따로 표시. 기본값 

 

<head>
    <style>
        table {
            border: 2px solid black;
            border-collapse: collapse;
        }
        td {
            padding: 15px;
            border: 1px dotted black;
            text-align: center;
        }
    </style>
</head>
<body>
    <table>
        <caption>표 스타일</caption>
        <tr>
            <td>시네마천국</td>
            <td>벤허</td>
        </tr>
        <tr>
            <td>11:00~14:30</td>
            <td>16:00~19:00</td>
        </tr>
    </table>
</body>

separate 인 경우
collapse 인 경우

 


 

5) empty-cells 속성 

 

🍯  table 태그에서 내용이 없는 빈 셀들의 표시 여부를 지정

 show : 빈 셀의 주위에 테두리를 표시하여 빈 셀을 나타냄. 기본값.
 hide : 빈 셀에 테두리를 그리지 않고 비워 둠
<head>
    <style>
        table {
            border: 2px solid black;
            empty-cells: hide;
        }
        td {
            padding: 15px;
            border: 1px dotted black;
            text-align: center;
        }
    </style>
</head>
<body>
    <table>
        <caption>표 스타일</caption>
        <tr>
            <td>시네마천국</td>
            <td>벤허</td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>11:00~14:30</td>
            <td>16:00~19:00</td>
        </tr>
    </table>
</body>

 

hide로 지정한 경우

 


 

6)  width, height
        

🍯  표의 넓이와 높이를 지정. 
🍯  셀 / 전체 표의 넓이에 스타일 지정 가능 ▶️ 높이와 넓이를 지정하지 않으면 셀의 내용만큼 차지


 

 7)  table-layout 속성


🍯  콘텐츠에 맞게 셀 넓이를 지정
🍯  셀의 width 값을 지정하면 해당 크기에 맞게 화면에 맞춰 표시
       ➡️  영문을 띄어쓰기 없이 길게 입력을 하면 셀의 width 값은 무시되고, 내용이 한줄로 표시 됨

 

fixed : 셀 넓이를 고정하여 셀 내용에 따라 셀의 넓이가 달라지지 않음
auto : 기본값. 셀의 내용에 따라 넓이가 달라짐

 

<head>
    <style>
        table {
            border: 2px solid black;
            border-collapse: collapse;
            width: 400px;
            table-layout: fixed;
            word-break: break-all; /* 셀의 내용이 벗어나지 않도록 함 */
        }
        td {
            width: 200px;
            height: 40px;
            padding: 15px;
            border: 1px dotted black;
            text-align: center;
        }
    </style>
</head>
<body>
    <table>
        <caption>표 스타일</caption>
        <tr>
            <td>cinemacinemacinemacinemacinemacinemacinema</td>
            <td>벤허벤허벤허벤허벤허벤허벤허벤허벤허벤허벤허벤허벤허</td>
        </tr>
        <tr>
            <td>11:00~14:30</td>
            <td>16:00~19:00</td>
        </tr>
    </table>

</body>

 

 

 

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 'Do it HTML+CSS+자바스크립트 웹 표준의 정석' ]


 

1.  글꼴 관련 스타일

font-family: <글꼴 이름> | [<글꼴 이름>, <글꼴 이름>]

 

🍒  font-family : 웹 문서에서 사용할 글꼴을 지정

        ➡️  2개 이상 지정할 때 이름 사이에 쉼표(,)를 넣어 구분

 


font-size: <절대 크기> | <상대 크기> | <크기> | <백분율>

 

🍒  font-size : 글자 크기 지정. 단위는 px(픽셀) 이나 pt(포인트) 등으로 지정할 수 있고 백분율도 가능

 

키워드 사용하여 글자 크기 지정
xx-small < x-small < small < medium < large < x-large < xx-large

 

단위 사용하여 글자 크기 지정
1em = 16px, 12pt
em   : 부모 요소에서 지정한 글꼴의 대문자 M의 너비를 기준(1em)으로 한 후 비율값을 지정
rem  :  문서 시작 부분에서 지정한 크기를 기준(1rem)으로 한 후 비율값을 지정
ex     :  해당 글꼴의 소문자 x의 높이를 기준(1ex)으로 한 후 비율값을 지정
px     :  모니터의 1픽셀을 기준(1px)으로 한 후 비율값을 지정
pt      :  포인트라고 하며, 일반 문서에 많이 사용

 


font-style: normal | italic | oblique

 

🍒  font-style : 글자를 이탤릭체로 표시할 때 사용

 


font-weight: normal | bold | bolder | lighter | 100 | ... | 900

 

🍒  font-weight : 글자 굵기를 지정. 100~900사이에서 400은 normal, 700은 bold에 해당

 


 

2.  웹 폰트 사용

 

웹 폰트 업로드하고 사용하기

 

  🍒  컴퓨터에서 사용하는 글꼴은 트루타입(TrueType)이고 파일 확장자는 *.ttf

          ▶️  파일 크기가 커서 웹에서 사용하기엔 적절하지 x

  🍒  웹에 적합한 글꼴 : EOT embedded open type / WOFF web open font format 

  

@font-face {
    font-family: <글꼴 이름>; <!-- 글꼴 파일 이름과 같은 이름으로 사용 -->
    src: <글꼴 파일>[<글꼴 파일>, <글꼴 파일>, ....]; <!-- 글꼴 파일의 경로 -->
    }

 

    ⚡️  local()문을 사용해서 사용자 시스템에 해당 글꼴이 있는지 먼저 확인해야 한다.

 

@import 방식
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&display=swap');

        h1 {
                font-family: "Nanum Pen Script", cursive;
                font-weight: 400;
                font-style: normal;
            }

    </style>
</head>
<body>

<h1>안녕하세요~</h1>

</body>

 

link 방식

 

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&display=swap" rel="stylesheet">
    <style>
        /* link 방식 적용. Nanum Brush Script 폰트 적용 */
        * {
            padding: 0;
            margin: 0;
        }

        p {
            margin: 40px;
        }

        .test {
            font-family: "Nanum Pen Script", cursive;
            font-weight: 400;
            font-style: normal;
        }

    </style>
</head>

 


 

3.  텍스트 관련 스타일

 

1) 글자색 지정하는 color 속성

 

color: <색상>

 

hsl과 hsla

   

    · hsl은 hue(색상), saturation(채도), lightness(명도)의 줄임말

    · hsla는 hsl에 alpha(불투명도)를 추가한 것을 의미

 

<style>
  h1 { 
    color:#0000ff;   /* 16진수 표기법 */
  } 
  p {
    color:green;  /* 색상 이름 */
  }
  .accent {
    color:hsl(0, 100%, 50%);  /* hsl 표기법 */
    font-weight:bold;
  }
</style>

 

 

rgb와 rgba로 표현하는 방법

 

     ·  rgb는 red, green, blue의 줄임말

     ·  하나도 섞이지 않았을 때는 0으로 표시, 가득 섞였을 때는 255로 표시

     ·  rgba에서 맨 끝의 a(alpha)는 불투명도 값을 나타내며 0~1의 값 중에서 사용할 수 있다.

<!--파란색 지정 -->
h1 { color: rgb(0, 0, 255); }

 


 

2) 텍스트 정렬하는 text-align 속성

 

text-align: start | end | left | right | center | justify | match-parent

 

종류 설명
start 현재 텍스트 줄의 시작 위치에 맞추어 문단 정렬
end 현재 텍스트 줄의 끝 위치에 맞추어 문단 정렬
left 왼쪽에 맞추어 문단 정렬
right 오른쪽에 맞추어 문단 정렬
center 가운데에 맞추어 문단 정렬
justify 양쪽에 맞추어 문단 정렬
match-parent 부모 요소를 따라 문단 정렬

🍒  왼쪽 정렬이 기본값. 양쪽 정렬과의 차이는 왼쪽 정렬에서는 오른쪽에 여백이 생기지만 양쪽 정렬에서는 여백이 없다.

 


 

4)  줄 간격을 조절하는 line-height 속성

 

🍒   line-height 속성을 이용하면 줄 간격을 원하는 만큼 조절할 수 있다.

🍒   텍스트를 세로 가운데 정렬할 때 height 값과 똑같이 추가하면 된다.

 

p { font-size: 12px; line-height: 24px; }
p { font-size: 12px; line-height: 2.0;; }
p { font-size: 12px; line-height: 200%; }

 


 

5) 텍스트의 줄을 표시하거나 없애 주는 text-decoration 속성

 

🍒  텍스트에 밑줄을 긋거나 취소선을 표시하는 속성

       ex. 하이퍼링크 적용하면 기본적으로 밑줄이 생김

<p style="text-decoration:none">none</p>
<p style="text-decoration:underline">underline</p>
<p style="text-decoration:overline">overline</p>

 


 

6) 텍스트에 그림자 효과를 추가하는 text-shadow 속성

text-shadow: none | <가로 거리> <세로 거리> <번짐 정도> <색상>

 

<가로 거리>  :  텍스트로부터 그림자까지의 가로 거리로 필수 속성.
                           양수값은 오른쪽, 음수값은 왼쪽
<세로 거리>  :  텍스트로부터 그림자까지의 세로 거리로 필수 속성.
                           양수값은 아래쪽, 음수값은 위쪽
<번짐 정도>  :  그림자가 번지는 정도. 양수값은 모든 방향으로 퍼짐, 음수값은 모든 방향으로 축소
<색상>          :  그림자 색상을 지정

 


 

7) 텍스트의 대소 문자를 변환하는 text-transform 속성

 

👾  capitalize : 첫 번째 글자를 대문자로 변환
👾  uppercase : 모든 글자를 대문자로 변환
👾  lowercase  : 모든 글자를 소문자로 변환
👾  full-with     : 가능한 한 모든 문자를 전각 문자로 변환

 


 

8) 글자 간격을 조절하는 letter-spacing, word-spacing 속성

 

🍒  letter-spacing 속성은 글자와 글자 사이의 간격을 조절

🍒  word-spacing 속성은 단어와 단어 사이 간격을 조절

 

<head>
  <style>  
    p {
      font-family:Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
      font-size:80px;
      text-shadow:3px 3px 1px #ccc;  /* 오른쪽 아래로 파란색 그림자 */
    }
    .spacing1 {
      letter-spacing:0.2em;  /* 글자 간격 0.2em */
    }
    .spacing2 {
      letter-spacing:0.5em;  /* 글자 간격 0.5em */
    }      
  </style>
</head>
<body>
  <p>CSS</p> 
  <p class="spacing1">CSS</p>
  <p class="spacing2">CSS</p>
</body>

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 'Do it HTML+CSS+자바스크립트 웹 표준의 정석' ]

 


 

1.  CSS 박스 모델

 

1) 블록 레벨 요소와 인라인 레벨 요소

 

🍒  블록 레벨 block-level 요소 

      -  화면의 가로(폭) 길이 (100%)를 차지, 뒤에 오는 요소는 줄 바꿈이 일어나며 

          여러 개의 <div> 태그를 나열하면 수직 방향으로 정렬이 됨

           ▶️  대표적인 태그 : div, p, h1~h6, ul, ol, form, table, blockquote~

<body>
    <div>HTML5-WEB</div>
    <div>HTML5-WEB</div>
    <div>HTML5-WEB</div>
    <div>HTML5-WEB</div>
    <div>HTML5-WEB</div>
</body>

출력 결과


 

🍒  인라인 레벨 inline-level 요소

    -  해당 태그의 컨텐츠 만큼 공간을 차지(폭이 컨텐츠의 양에 비례), 글자와 같이 옆으로 나열되며 나타남
    -  줄 바꿈이 일어나지 않기 때문에 <span></span> 이라고 나열하면 수평 방향으로 정렬
    -  width, height, margin-top, margin-bottom이 적용되지 않음
    -  태그 종류 : a, img, span, sub, sup, i, b, em(글자를 꾸미는 태그 종류), input

<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <span>SPAN-inline</span>
    <span>SPAN-inline</span>
    <span>SPAN-inline</span>
    <span>SPAN-inline</span>
    <span>SPAN-inline</span>

</body>

출력 결과

 


span에 margin 적용 시 margin-left, margin-right는 적용되어서 나오는 예시
<head>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        span {
            width: 100px;
            height: 100px;
            background-color: aqua;
            margin: 10px;
            float: left;
        }
    </style>
</head>
<body>
    <span> inline 성격의 태그</span>
    <span> inline 성격의 태그</span>
</body>

출력 결과

 


2)  박스 모델의 기본 구성

 

 

 

🍒  박스모델 box model 요소

     -  박스 형태인 요소를 말함

     -  콘텐츠 영역 ▶️ 패딩 padding ▶️ 테두리 border ▶️ 마진 margin 으로 구성

     -  마진이나 패딩은 웹 문서에서 다른 콘텐츠 사이의 간격이나 배치 등을 고려할 때 필요한 개념

 

 

💡  박스의 실제 넓이와 높이 공식
     - 한개의 박스에 margin + border + padding 값이 모두 적용되었다는 가정
     - width 속성과 height 속성은 텍스트가 들어가는 영역(contents)의 넓이와 높이를 지정

* 전체 넓이 : width + 2 * (margin + border + padding)
* 전체 높이 : height + 2 * (margin + border + padding)

 

3) 콘텐츠 영역의 크기를 지정하는 width, height 속성

 

종류 설명
<크기> 너비나 높이의 값을 px이나 em 단위로 지정
<백분율> 박스 모델을 포함하는 부모 요소를 기준으로 너빗값이나 높잇값을 백분율(%) 로 지정
auto 박스 모델의 너빗값과 높잇값이 콘텐츠 양에 따라 자동으로 결정된다. 기본값.

🍒  넓이 / width : 크기 | 백분율 | auto
🍒  높이 / height : 크기 | 백분율 | auto

 

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .box1 {
            width: 300px; /* 고정 넓이 */
            height: 100px; /* 고정 높이 */
            background-color: blue;
        }
        #box2 {
            width: 50%; /* 가변 넓이 - 현재 브라우저 창 너비의 50%를 유지 */
            height: 100px; /* 고정 높이 */
            background-color: green;
        }
      
    </style>
</head>
<body>
    <div class="box1">BOX-1</div>
    <div id="box2">BOX-2</div>
</body>

 

전체 창 출력
브라우저 창 크기를 줄였을 때

 


 

4) box-sizing 속성

 

🍒  width 속성과 height 속성은 콘텐츠 주변의 여백이나 테두리를 뺀 콘텐츠 영역의 크기를 가리킨다

🍒  웹 문서에 여러 가지 요소를 배치할 때 실제 박스 모델이 차지하는 크기는 콘텐츠와 테두리 사이의 여백, 테두리 두께까지 계산해야 함

 

  💡 box-sizing은 박스 모델의 크기를 쉽게 계산하기 위해 지정하는 속성

종류 설명
boder-box 테두리까지 포함해서 너빗값을 지정
content-box 콘텐츠 영역만 너빗값을 지정. 기본값.
<head>
    <style>
        div {
            width: 300px;
            height: 300px;
            border: 10px solid black; /* 테두리 스타일 */
            padding: 30px; /* 안쪽 여백 공통 지정 */
        }
        .box1 {
            box-sizing: border-box;
            /* 박스의 테두리와 여백을 박스의 넓이와 높이에 포함. 넓이가 300px */
        }
        .box2 {
            box-sizing: content-box;
            /* 기본값과 동일. 넓이: 300 + 20 + 60 = 380px */
        }
    </style>
</head>
<body>
    <div class="box1">01</div>
    <div class="box2">02</div>

</body>

출력 결과


 

5)  box-shadow 속성

 

🍒  사진 주변에 그림자를 추가하는 속성

🍒  수평 거리와 수직 거리는 필수로 지정 ▶️  그림자의 위치는 수평 거리와 수직 거리의 값에 따라 움직이기 때문

box-shadow: <수평거리> <수직거리> <흐림 정도> <번짐 정도> <색상> inset

 

종류 설명
<수평 거리> 그림자가 가로로 얼마나 떨어져 있는지 나타냄.
양수는 오른쪽 / 음수는 왼쪽
<수직 거리> 그림자가 세로로 얼마나 떨어져 있는지 나타냄.
양수는 아래쪽 / 음수는 위쪽
<흐림 정도> 생략하면 0을 기본값으로 하여 진한 그림자를 표시.
값이 커질수록 부드러운 그림자를 표시하며 음수는 사용불가.
<번짐 정도> 양수는 모든 방향으로 그림자가 퍼져 박스보다 그림자가 크게 표시.
음수는 모든 방향으로 그림자가 축소되어 보임.
기본값은 0
<색상> 한 가지만 지정할 수도, 공백으로 구분해서 여러 개 색상 지정 가능
기본값은 검정색
inset 이 키워드를 함께 표시하면 안쪽 그림자로 그린다.

 

2.  테두리 스타일 지정

 

1) 박스 모델의 방향

 

🍒  박스 모델은 상하좌우 4개의 방향이 있어 테두리나 마진, 패딩 등을 지정할 때 한꺼번에 똑같이 지정하거나

      모두 다르게 지정할 수도 있다.

🍒  맨 윗 부분은 top ▶️ 오른쪽은 right ▶️ 아래쪽은 bottom ▶️ 왼쪽은 left  (시계 방향)

       

 


 

2) 테두리 스타일을 지정하는 border-style 속성

 

종류 설명
none 기본값. 테두리가 없다.
hidden 테두리를 감춘다. 표에서 border-collapse: collapse일 경우 다른 테두리도 표시되지 않는다.
solid 테두리를 실선으로 표시
dotted 테두리를 도트형태의 점선으로 표시
dashed 테두리를 직선형태의 점선으로 표시
double 테두리를 이중선으로 표시. 두 선 사이의 간격이 border-width값이 된다.
groove 테두리를 창에 조각한 것처럼 표시. 홈이 파인 듯 입체 느낌이 난다.
inset 표에서 border-collapse: seperate일 경우 전체 박스 테두리가 창에 박혀 있는 것처럼 표시
표에서 border-collapse: collapse일 경우 groove와 똑같이 표시
outset 표에서 border-collapse: seperate일 경우 전체 박스 테두리가 창에서 튀어나온 것처럼 표시
표에서 border-collapse: collapse일 경우 ridge와 똑같이 표시
ridge 테두리를 창에서 튀어나온 것처럼 표시
<style>
    #box1 { border-style:solid; }  /* 실선 */
	#box2 { border-style:dotted; }  /* 점선 */
    #box3 { border-style:dashed; }  /* 짧은 직선 */
</style>


 

3) 테두리 두께를 지정하는 border-width 속성

 

border-width: <크기> | thin | medium | thick

 

🍒  속성 값이 1개  ▶️  4개 방향 테두리 모두 같은 값 적용

🍒  속성 값이 2개  ▶️  첫 번째 값은 top, bottom 테두리 / 두 번째 값은 left, right 테두리 적용

🍒  속성 값이 3개  ▶️  top, right, bottom 순으로 적용 / left 값은 마주보는 right 속성값과 똑같이 적용

🍒  속성 값이 4개  ▶️  top, right, bottom, left 순으로 적용


 

4) 테두리 색상을 지정하는 border-color 속성

 

🍒  테두리 색상을 지정

      ➡️  border-color 사용해서 4개 방향의 테두리 색상 한꺼번에 지정

      ➡️  border-top-color 처럼 테두리 방향을 넣어주면 색상을 하나씩 지정 가능


 

5) 테두리 스타일 묶어 지정하는 border 속성

 

🍒  테두리 스타일과 두께, 색상의 속성을 따로 사용하면 소스 길이가 길어짐

       ▶️  3가지를 한꺼번에 표현하는 방법이 border 속성을 사용하는 것 ( 속성 값 순서는 상관 없다 )

<style>
    * {
        margin: 0;
        padding: 0;
    }
    .box1 {
        width: 300px; /* 고정 넓이 */
        height: 100px; /* 고정 높이 */
        border: green 2px solid; /* 테두리 굵기는 2px, 테두리 스타일 solid, 테두리 색상 green */
    }
    .box2 {
        width: 300px;
        height: 100px;
        border: red dashed;
        border-width: 1px 5px 10px 12px; /* 12시 부터 시계 방향으로 */
    }
    .box3 {
        width: 300px;
        height: 100px;
        border: blue 1px dotted;
        border-bottom-width: 5px; /* 아래 테두리만 따로 지정 */
    }
    .box4 {
        width: 300px;
        height: 100px;
        border: pink dashed;
        border-width: 5px 10px; /* (12시 6시) (3시 9시) */
    }
     </style>
</head>
<body>
    <div class="box1">BOX-1</div>
    <div class="box2">BOX-2</div>
    <div class="box3">BOX-3</div>
    <div class="box4">BOX-4</div>
</body>


 

6) 둥근 테두리를 만드는 border-radius 속성

 

border-radius: <크기> | <백분율>

 

🍒  border-radius 속성을 사용하면 꼭짓점 부분에 원이 있다고 가정해서 둥글게 처리

      ▶️  이 때 원의 반지름을 이용하면 둥근 정도를 나타낼 수 있다

🍒  라운드 지정하는 순서는 top-left, top-right, bottom-right, bottom-left
🍒  원 형태로 만들고 싶다면 border-radius 반지름값을 너비나 높이의 50%로 지정하면 된다.

 

 

<head>  
    <style>
        div {
            width: 300px;
            height: 100px;
            border: green 10px solid;
            margin: 10px;
        }
        .box1 {
            border-radius: 30px ; /* 전체 모서리를 30px로 라운드 지정 */
        }
        .box2 {
            border-radius: 10px 20px 30px 40px;
            /* top-left: 10px, top-right: 20px; bottom-right: 30px, bottom-left: 40px 라운드 지정 */
        }
        .box3 {
            border-radius: 10px 40px;
            /* top-left: 10px, top-right: 40px; bottom-right: 10px, bottom-left: 40px 라운드 지정 */
        }
        .box4 {
            width: 100px; height: 100px; border-radius: 100px; /* 원모양 */
        }
      
    </style>
</head>
<body>
    <div class="box1">BOX-1</div>
    <div class="box2">BOX-2</div>
    <div class="box3">BOX-3</div>
    <div class="box4">BOX-4</div>
</body>

 

출력 결과

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 'Do it HTML+CSS+자바스크립트 웹 표준의 정석' ]

+ Recent posts