Ch 03. bslib으로 테마 적용하기
기본 Shiny 앱은 회색과 흰색이 주를 이루는 다소 밋밋한 모습입니다. bslib 패키지를 쓰면 Bootstrap 테마를 코드 몇 줄로 바꿀 수 있습니다. 색상과 폰트를 세밀하게 조정하거나, 이미 완성된 Bootswatch 테마를 그대로 가져와 입힐 수도 있습니다.
bslib 설치와 기본 사용
install.packages("bslib")
bslib는 theme 인수를 통해 fluidPage(), navbarPage() 등 최상위 UI 함수에 적용합니다.
library(shiny)
library(bslib)
ui <- fluidPage(
theme = bs_theme(version = 5), # Bootstrap 5 적용
titlePanel("테마 적용 예제"),
p("bslib으로 Bootstrap 5가 적용된 앱입니다.")
)
version = 5로 Bootstrap 5를 씁니다. 기본값은 Bootstrap 3이므로 명시적으로 버전을 지정하는 것이 좋습니다.
bs_theme로 색상과 폰트 커스터마이징
bs_theme()의 인수로 Bootstrap의 핵심 변수를 덮어쓸 수 있습니다.
library(shiny)
library(bslib)
my_theme <- bs_theme(
version = 5,
bg = "#FFFFFF", # 배경색
fg = "#212529", # 텍스트색
primary = "#0d6efd", # 주 강조색 (버튼, 링크 등)
secondary = "#6c757d", # 보조색
success = "#198754", # 성공 색상
danger = "#dc3545", # 위험/삭제 색상
base_font = font_google("Noto Sans KR"), # 구글 폰트 사용
heading_font = font_google("Noto Serif KR") # 제목용 폰트
)
ui <- fluidPage(
theme = my_theme,
titlePanel("커스텀 테마"),
sidebarLayout(
sidebarPanel(
actionButton("btn1", "Primary", class = "btn-primary"),
actionButton("btn2", "Success", class = "btn-success"),
actionButton("btn3", "Danger", class = "btn-danger")
),
mainPanel(
plotOutput("demo_plot")
)
)
)
server <- function(input, output, session) {
output$demo_plot <- renderPlot({
hist(rnorm(500), col = "#0d6efd", border = "white",
main = "Primary 색상으로 그린 히스토그램",
xlab = "값")
})
}
shinyApp(ui, server)
font_google()은 구글 폰트를 자동으로 로드합니다. 인터넷 연결이 필요하므로, 오프라인 환경에서는 font_face()로 로컬 폰트를 지정합니다.
Bootswatch 테마 적용
Bootswatch(https://bootswatch.com)는 Bootstrap 기반의 무료 테마 모음입니다. bs_theme(bootswatch = "테마명")으로 바로 적용할 수 있습니다.
# 사용 가능한 Bootswatch 테마 목록 확인
bslib::bootswatch_themes()
# [1] "cerulean" "cosmo" "cyborg" "darkly" "flatly" "journal"
# [7] "litera" "lumen" "lux" "materia" "minty" "morph"
# ...
ui <- fluidPage(
theme = bs_theme(
version = 5,
bootswatch = "flatly" # 인기 있는 플랫 디자인 테마
),
titlePanel("Flatly 테마"),
sidebarLayout(
sidebarPanel(
sliderInput("n", "데이터 수", 10, 200, 50),
selectInput("dist", "분포 종류",
choices = c("정규" = "norm",
"균등" = "unif",
"지수" = "exp"))
),
mainPanel(
plotOutput("hist")
)
)
)
자주 쓰이는 Bootswatch 테마를 정리하면 다음과 같습니다.
| 테마명 | 특징 |
|---|---|
flatly |
청록색 계열, 깔끔한 플랫 디자인 |
cosmo |
모던하고 미니멀한 스타일 |
lux |
세련된 다크 네이비 + 골드 |
minty |
민트 초록 계열, 상쾌한 느낌 |
darkly |
다크 모드 계열 |
cyborg |
짙은 다크 + 강렬한 강조색 |
morph |
부드러운 뉴모피즘 스타일 |
다크 모드
bs_theme()의 bg와 fg를 어두운 색으로 지정하거나, 다크 계열 Bootswatch 테마를 쓰면 다크 모드가 됩니다. darkly와 cyborg가 대표적입니다.
dark_theme <- bs_theme(
version = 5,
bg = "#1a1a2e", # 어두운 배경
fg = "#eaeaea", # 밝은 텍스트
primary = "#e94560" # 강렬한 포인트 색
)
ui <- fluidPage(
theme = dark_theme,
titlePanel("다크 모드 앱"),
p("눈이 편안한 다크 테마입니다.")
)
실시간 테마 미리보기
개발 중에는 bs_themer()를 서버에 추가하면 앱 오른쪽에 테마 조절 패널이 뜹니다. 슬라이더와 색상 선택기로 색상, 폰트, 배경 등을 실시간으로 바꿔보고 마음에 드는 설정을 코드로 복사할 수 있습니다.
server <- function(input, output, session) {
bs_themer() # 개발 시에만 사용, 배포 전 제거
# ... 나머지 서버 코드
}
bs_theme와 navbarPage 조합
navbarPage()에도 같은 방식으로 테마를 적용합니다.
ui <- navbarPage(
title = "분석 대시보드",
theme = bs_theme(
version = 5,
bootswatch = "lux",
primary = "#1a73e8"
),
tabPanel("홈", p("홈 탭")),
tabPanel("분석", plotOutput("plot1")),
tabPanel("보고서", tableOutput("tbl1"))
)
추가 스타일: 카드 레이아웃
bslib는 Bootstrap 5의 카드 컴포넌트도 지원합니다. card() 함수로 내용을 카드 형태의 박스에 담을 수 있습니다.
library(bslib)
ui <- fluidPage(
theme = bs_theme(version = 5, bootswatch = "flatly"),
layout_columns(
col_widths = c(4, 4, 4),
card(
card_header("요약 통계"),
card_body(verbatimTextOutput("stats"))
),
card(
card_header("주요 지표"),
card_body(tableOutput("metrics"))
),
card(
card_header("차트"),
card_body(plotOutput("chart", height = "200px"))
)
)
)
layout_columns()과 card()는 bslib 0.5 이상에서 사용 가능합니다. 대시보드를 구성할 때 fluidRow() + column() 대신 더 세련된 방법입니다.