부트스트랩 css 수정 - buteuseuteulaeb css sujeong

HTML 파일을 다음과 같이 시작한다.

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
        integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
        crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
        integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
        crossorigin="anonymous"></script>

    <title>타이틀</title>
</head>

<body>
    <h2>제목</h2>
</body>

</html>

부트스트랩을 사용하기 위해 CSS 링크와 javascript 링크를 넣어준 것이다.

CSS 파일을 따로 만들어주고 HTML에 연결하듯이 인터넷 상에 있는 부트스트랩 CSS 파일을 연결해주는 것이다. 

https://getbootstrap.com/docs/4.0/components/alerts/

Alerts

Provide contextual feedback messages for typical user actions with the handful of available and flexible alert messages.

getbootstrap.com

부트스트랩 css 수정 - buteuseuteulaeb css sujeong

위의 부트스트랩 사이트에서 원하는 디자인을 고르고 해당 코드를 복사해 원하는 위치에 붙여넣어준다.

부트스트랩 디자인에서 나만의 디자인을 추가하고 싶을 때 style을 따로 작성하여 class 이름을 하나 더 추가하면 된다.

<button type="button" class="btn btn-primary">Primary</button>

예를 들어 위와 같은 부트스트랩에서 가져온 버튼을 생성할 때,

나만의 디자인을 작성해 놓은 mybtn을 추가하고 싶다면

<button type="button" class="btn btn-primary mybtn">Primary</button>

class 이름에 mybtn을 추가해주면 된다.

책 '점프 투 플라스크'를 공부하면서 정리한 내용입니다.
출처 : https://wikidocs.net/book/4542

웹 페이지에 CSS 적용하기

웹 페이지에 디자인을 적용하기 위해 CSS를 사용한다. CSS를 파이보에 적용하려면 CSS 파일이 pybo/static 디렉토리에 있어야 한다. 이때 CSS 파일은 플라스크에서 정적(static) 파일로 분류한다. 정적 파일은 주로 이미지(.png, .jpg)나 자바스크립트(.js), 스타일시트(.css)와 같은 파일을 의미한다.

  1. static 디렉토리 만들고 스타일시트 작성하기

정적 파일을 저장할 디렉토리는 템플릿 디렉토리와 마찬가지로 플라스크가 앱으로 지정한 모듈 아래에 static이라는 이름으로 생성하면 된다. 우리가 사용한 플라스크 앱은 pybo 모듈이므로 pybo 디렉토리 아래에 static 디렉토리를 생성한다.

그 후 style.css 파일을 작성한다. 답변을 등록할 때 사용하는 텍스트 창(textarea)의 너비를 100%로 넓히고(웹 브라우저 너비 기준), <답변등록> 버튼 위에 마진을 10px 추가한다.

textarea {
    width:100%;
}
input[type=submit] {
    margin-top:10px;
}
  1. 질문 상세 페이지에 스타일 시트 적용

스타일시트를 질문 상세 조회 템플릿에 적용하기 위해 question_detail.html 파일에 다음 코드를 추가한다.

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

부트스트랩

  1. 부트스트랩 설치

부트스트랩 설치 후 bootstrap.min.css 파일만 복사해서 pybo/static 디렉터리에 저장

  1. 부트스트랩 적용

질문 목록 조회 템플릿에 부트스트랩 적용
question_list.html 파일 맨 위에 있는 bootstrap.min.css 파일을 연결하는 것을 시작으로 전체를 수정해야 한다.

<link rel="stylesheet" \
      href="{{ url_for('static', filename='bootstrap.min.css') }}">
<div class="container my-3">
    <table class="table">
        <thead>
        <tr class="thead-dark">
            <th>번호</th>
            <th>제목</th>
            <th>작성일시</th>
        </tr>
        </thead>
        <tbody>
        {% if question_list %}
        {% for question in question_list %}
        <tr>
            <td>{{ loop.index }}</td>
            <td>
                <a href="{{ url_for('question.detail', \
                question_id=question.id) }}">{{ question.subject }}</a>
            </td>
            <td>{{ question.create_date }}</td>
        </tr>
        {% endfor %}
        {% else %}
        <tr>
            <td colspan="3">질문이 없습니다.</td>
        </tr>
        {% endif %}
        </tbody>
    </table>
</div>

ul 엘리먼트로 표시한 기존 질문 목록을 table 엘리먼트로 표현하고, table 엘리먼트와 하위 엘리먼트에 부트스트랩을 적용했다. (부트스트랩이 제공하는 클래스 이용)

  1. 질문 상세 조회 템플릿에 부트스트랩 적용
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap.min.css') }}">
<div class="container my-3">
    <h2 class="border-bottom py-2">{{ question.subject }}</h2>
    <div class="card my-3">
        <div class="card-body">
            <div class="card-text" style="white-space: pre-line;">{{ question.content }}</div>
            <div class="d-flex justify-content-end">
                <div class="badge badge-light p-2">
                    {{ question.create_date }}
                </div>
            </div>
        </div>
    </div>
    <h5 class="border-bottom my-3 py-2">{{ question.answer_set|length }}개의 답변이 있습니다.</h5>
    {% for answer in question.answer_set %}
    <div class="card my-3">
        <div class="card-body">
            <div class="card-text" style="white-space: pre-line;">{{ answer.content }}</div>
            <div class="d-flex justify-content-end">
                <div class="badge badge-light p-2">
                    {{ answer.create_date }}
                </div>
            </div>
        </div>
    </div>
    {% endfor %}
    <form action="{{ url_for('answer.create', question_id=question.id) }}" method="post" class="my-3">
        <div class="form-group">
            <textarea name="content" id="content" class="form-control" rows="10"></textarea>
        </div>
        <input type="submit" value="답변등록" class="btn btn-primary">
    </form>
</div>

질문과 답변은 부트스트랩의 card 컴포넌트를 이용해 카드에 담았다. card 컴포넌트는 게시물 1개를 담기에 적절하다.

  • 부트스트랩 클래스
    my-3 : 위아래(m은 margin, y는 y축을 의미) 방향으로 부트스트랩 기준 3 정도의 마진
    py-2 : 위아래 방향으로 부트스트랩 기준 2 정도의 패딩
    p-2 : 상하좌우 방향으로 부트스트랩 기준 2 정도의 패딩
    d-flex justify-content-end : 컴포넌트 오른쪽 정렬
    style=”white-space: pre-line;” : 스타일을 지정해 글 내용의 줄 바꿈

표준 HTML과 템플릿 상속 사용해보기

지금까지 작성한 템플릿 파일은 표준 HTML 구조가 아니다. 어떤 운영체제나 브라우저를 사용하더라도 웹 페이지가 동일하게 보이고 정상적으로 동작하게 하려면 반드시 웹 표준을 지키는 HTML 문서를 작성해야 한다.

표준 HTML의 구조

html, head, bodoy 엘리먼트가 있어야 하고 CSS 파일은 head 엘리먼트 안에 있어야 한다. 또한 head 엘리먼트 안에는 meta, title 엘리먼트 등이 포함되어야 한다.

템플릿을 표준 HTML 구조로 바꾸기

모든 템플릿 파일을 앞에서 본 표준 HTML 구조로 변경하면 body 엘리먼트 바깥 부분은 모두 같은 내용이 중복되고, CSS 파일 이름이 변경되거나 추가되면 head 엘리먼트으 ㅣ내용을 수정하려고 일일히 찾아다녀야 하는 불편함이 있다.

플라스크에서는 이런 불편함을 해소하기 위해 템플릿 상속(extends) 기능을 제공한다. 단순히 템플릿을 표준 HTML 구조로 바꿀 뿐 아니라 템플릿 상속 기능까지 사용한다.

  1. 템플릿 파일의 기본 틀
    base.html 템플릿 작성(모든 템플릿에서 공통으로 입력할 내용)
<!doctype html>
<html lang="ko">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="{{ url_for('static', filename='bootstrap.min.css') }}">
    <!-- pybo CSS -->
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    <title>Hello, pybo!</title>
</head>
<body>
<!-- 기본 템플릿 안에 삽입될 내용 Start -->
{% block content %}
{% endblock %}
<!-- 기본 템플릿 안에 삽입될 내용 End -->
</body>
</html>

body 엘리먼트에 {% block content %}와 {% endblock %} 템플릿 태그 부분이 base.html 템플릿 파일을 상속한 파일에서 구현할 영역이다.

  1. 질문 목록, 상세 조회 템플릿 파일 수정
{% extends 'base.html' %}
{% block content %}

        (... 생략 ...)

{% endblock %}

기존 코드 생략

  1. 기존 스타일 파일 내용 비우기
    부트스트랩을 사용하게 되었으므로 style.css 파일의 내용을 비운다. 이후 부트스트랩으로 표현할 수 없는 스타일을 위해 사용할 것이므로 삭제하지 않고 비워만 둔다.