카테고리 없음

스파르타 AI-8기 TIL(11/30)-Streamlit

kimjunki-8 2024. 11. 30. 20:07

오늘 스트림릿을 정식적으로 쓰면서 나의 코드를 강화해나갈 생각이다.

그런데 배경화면을 설정하고 싶다는 생각이 들어서 코드를 검색해보니 이렇게 나왔다.

import streamlit as st

# HTML과 CSS로 배경 이미지 설정
st.markdown(
    """
    <style>
    .stApp {
        background-image: url('https://example.com/your-image.jpg');
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
    }
    </style>
    """,
    unsafe_allow_html=True
)

st.write("전체 애플리케이션의 배경이 설정되었습니다.")
대충 스타일이 이렇다고 하니, 하나하나 알아봅시다.
먼저, st.markdown()을 사용하면 HTML과 CSS를 포함하여 다양한 스타일을 적용할 수 있습니다. 하지만 주의해야 할 점은 Streamlit이 기본적으로 HTML을 허용하고 있지만, CSS와 JavaScript를 삽입할 때는 unsafe_allow_html=True를 설정해줘야 한다는 점입니다.
마크다운 자체는 기본적으로 스타일링을 지원하지 않지만, HTML을 삽입하는 방식으로 배경 이미지나 다른 스타일을 적용할 수 있습니다.

그것이 바로 <style>입니다
<style> 태그는 HTML 내에서 CSS 스타일을 삽입하는 데 사용되는 태그입니다. CSS는 웹 페이지의 디자인과 레이아웃을 정의하는 언어이며, <style> 태그 안에 작성된 CSS 코드는 페이지의 요소에 적용됩니다.
Streamlit에서는 st.markdown()을 사용하여 HTML 코드와 CSS 스타일을 삽입할 수 있습니다. 이때, <style> 태그를 사용하여 배경 이미지, 글꼴, 색상 등 다양한 스타일을 지정할 수 있습니다.

Streamlit에서는 st.markdown()을 사용하여 마크다운과 HTML을 혼합하여 사용할 수 있습니다. 마크다운은 주로 텍스트를 구조화하고 간단하게 꾸미는 데 사용되며, HTML은 더 복잡한 스타일링과 레이아웃 변경을 지원합니다. 따라서 st.markdown()으로 HTML을 삽입할 수 있습니다.

두번째로 .stApp입니다
stApp은 Streamlit 애플리케이션의 최상위 DOM 요소에 해당하는 클래스입니다. 즉, Streamlit의 전체 애플리케이션을 감싸고 있는 HTML 요소의 클래스를 의미합니다. 이 클래스를 사용하여 애플리케이션의 배경, 크기, 레이아웃 등을 CSS로 스타일링할 수 있습니다.

stApp 클래스를 사용하는 이유
전체 애플리케이션 스타일링: stApp을 사용하면 페이지 전체의 스타일을 한 번에 설정할 수 있습니다. 예를 들어, 배경 이미지나 색상, 폰트 스타일 등을 설정할 때 유용합니다.

페이지의 기본 레이아웃을 변경: 예를 들어, stApp에 height, width, margin 등을 설정해서 애플리케이션의 기본 레이아웃을 변경할 수 있습니다.

하지만 stApp은 반드시 필요한 것은 아닙니다. stApp은 Streamlit 애플리케이션의 전체 레이아웃을 대상으로 스타일을 적용할 때 사용하는 클래스이므로, stApp 없이도 <style>을 사용하여 특정 요소에 스타일을 적용할 수 있습니다.
주요 Streamlit CSS 클래스 및 요소들
1. stApp
전체 애플리케이션의 스타일을 정의할 때 사용됩니다.
페이지 전체의 배경색, 이미지, 여백 등을 설정할 수 있습니다.
2. .stText
기본적으로 텍스트와 관련된 스타일을 정의할 때 사용됩니다.
st.write(), st.markdown(), st.text() 등으로 표시되는 텍스트에 적용됩니다.
3. .stSidebar
Streamlit 사이드바의 스타일을 제어하는 클래스입니다.
사이드바의 배경색, 여백, 텍스트 등을 변경할 때 사용됩니다.
4. .stButton
버튼을 스타일링할 때 사용됩니다.
st.button() 함수로 생성된 버튼에 적용됩니다.
5. .stMarkdown
마크다운 텍스트에 적용되는 클래스입니다.
st.markdown() 함수로 표시되는 마크다운 내용에 스타일을 지정할 때 사용됩니다.
6. .stSelectbox, .stMultiselect
st.selectbox()와 st.multiselect()에서 생성된 드롭다운 메뉴나 다중 선택 박스를 스타일링할 때 사용됩니다.
7. .stSlider
슬라이더 위젯에 관련된 스타일을 정의할 때 사용됩니다.
st.slider()로 생성된 슬라이더에 적용됩니다.
8. .stTable
테이블을 스타일링하는 클래스입니다.
st.write()나 st.dataframe()에서 데이터 테이블을 렌더링할 때 사용됩니다.
9. .stProgress
진행 상태 표시줄에 스타일을 적용할 때 사용됩니다.
st.progress()로 생성된 진행 표시줄에 스타일을 적용할 수 있습니다.
10. .stTextInput, .stTextArea
텍스트 입력 필드나 텍스트 영역을 스타일링할 때 사용됩니다.
st.text_input()이나 st.text_area()로 생성된 입력 필드에 적용됩니다.

Streamlit 내부적으로 사용되는 주요 CSS 클래스
11. .stAlert: 알림창과 관련된 스타일입니다. (예: st.warning(), st.success() 등)
12. .stFileUploader: 파일 업로더와 관련된 스타일입니다. (예: st.file_uploader() 위젯)
13. .stRadio: 라디오 버튼 스타일입니다. (예: st.radio() 위젯)
14. .stCheckbox: 체크박스 스타일입니다. (예: st.checkbox() 위젯)
15. .stTextArea: 텍스트 영역의 스타일입니다. (예: st.text_area() 위젯)
16. .stMetric: 메트릭 카드 스타일입니다. (예: st.metric() 위젯)
17. .stExpander: 확장 가능한 요소 스타일입니다. (예: st.expander() 위젯)

전체적으로 예제를 봅시다.


 

1. .stApp: 전체 애플리케이션 스타일링
설명: stApp은 전체 애플리케이션 영역에 대한 스타일을 제어합니다.
적용 가능한 스타일:
배경색, 배경 이미지, 여백, 패딩, 글꼴 스타일 등
import streamlit as st

# stApp 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stApp {
        background-image: url('https://example.com/your-image.jpg'); /* 배경 이미지 URL */
        background-size: cover;          /* 이미지 크기를 화면에 맞춤 */
        background-position: center;     /* 배경 이미지 위치 */
        background-repeat: no-repeat;    /* 이미지 반복 방지 */
        background-attachment: fixed;    /* 스크롤 시 이미지 고정 */
        color: white;                    /* 기본 텍스트 색상 */
        font-family: Arial, sans-serif;  /* 기본 글꼴 */
        padding: 20px;                   /* 전체 여백 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 애플리케이션 내용
st.write("배경 이미지가 적용된 Streamlit 애플리케이션입니다!")

2. .stText: 텍스트 스타일링
설명: 텍스트 구성 요소(st.write, st.text, st.markdown)의 스타일을 제어합니다.
적용 가능한 스타일:
텍스트 색상, 크기, 글꼴, 간격 등
import streamlit as st

# stText 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stText {
        color: #FF4500;           /* 텍스트 색상 */
        font-size: 24px;          /* 글꼴 크기 */
        font-weight: bold;        /* 글씨 굵기 */
        text-align: center;       /* 텍스트 정렬 */
        text-shadow: 2px 2px 4px rgba(0,0,0,0.3); /* 텍스트 그림자 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 텍스트 출력
st.write("🎉 Streamlit 텍스트 스타일링 예제 🎉")

3. .stSidebar: 사이드바 스타일링
설명: 사이드바 영역의 스타일을 제어합니다.
적용 가능한 스타일:
배경색, 여백, 글꼴 색상, 글꼴 크기 등
예제:
import streamlit as st

# stSidebar 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stSidebar {
        background-color: #F0F0F0;  /* 사이드바 배경색 */
        padding: 20px;             /* 내부 여백 */
        font-size: 18px;           /* 글꼴 크기 */
        color: #333;               /* 기본 텍스트 색상 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 사이드바 내용
st.sidebar.write("이 스타일은 사이드바에 적용됩니다.")
st.sidebar.button("Click Me!")

4. .stButton: 버튼 스타일링
설명: 버튼 요소(st.button)의 스타일을 제어합니다.
적용 가능한 스타일:
배경색, 텍스트 색상, 크기, 여백 등
예제:

import streamlit as st

# stButton 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stButton>button {
        background-color: #4CAF50; /* 버튼 배경색 */
        color: white;              /* 버튼 텍스트 색상 */
        border: none;              /* 테두리 제거 */
        padding: 15px 32px;        /* 버튼 내부 여백 */
        text-align: center;        /* 텍스트 정렬 */
        font-size: 16px;           /* 글꼴 크기 */
        cursor: pointer;           /* 커서 스타일 */
        border-radius: 5px;        /* 둥근 모서리 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 버튼 생성
st.button("클릭하세요!")​

5. .stMarkdown: 마크다운 텍스트 스타일링
설명: st.markdown으로 렌더링된 텍스트의 스타일을 제어합니다.
적용 가능한 스타일:
텍스트 색상, 글꼴, 간격, 테두리 등
예제:
import streamlit as st

# stMarkdown 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stMarkdown h1 {
        color: #FF6347;         /* 헤더 색상 */
        font-family: Georgia, serif; /* 글꼴 */
        border-bottom: 2px solid #333; /* 아래쪽 테두리 */
    }
    .stMarkdown p {
        color: #666;           /* 일반 텍스트 색상 */
        font-size: 18px;       /* 일반 텍스트 크기 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 마크다운 내용
st.markdown("# 마크다운 헤더\n이것은 일반 텍스트입니다.")

6. .stSelectbox: 셀렉트박스 스타일링
설명: 드롭다운 셀렉트박스(st.selectbox)의 스타일을 제어합니다.
적용 가능한 스타일:
드롭다운 메뉴 색상, 글꼴 크기, 테두리 등
예제:

import streamlit as st

# stSelectbox 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stSelectbox>div>div>div {
        background-color: #FFF;    /* 드롭다운 배경색 */
        color: #333;              /* 텍스트 색상 */
        border: 2px solid #4CAF50; /* 테두리 */
        padding: 10px;            /* 내부 여백 */
        border-radius: 5px;       /* 둥근 모서리 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 셀렉트박스 생성
option = st.selectbox("옵션을 선택하세요:", ["옵션 1", "옵션 2", "옵션 3"])
st.write(f"선택된 옵션: {option}")

6.1 .stMultiselect: 멀티 셀렉트 스타일
설명: 멀티 셀렉트 위젯(st.multiselect())의 스타일을 제어합니다. 여러 개의 옵션을 선택할 수 있는 드롭다운 형태의 위젯입니다.
적용 가능한 스타일:
배경색, 선택된 항목의 색상, 드롭다운 화살표 색상 등
예제:

import streamlit as st

# stMultiselect 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stMultiselect > div {
        background-color: #E3F2FD; /* 위젯 배경색 */
        border: 2px solid #2196F3; /* 테두리 색상 */
        border-radius: 8px;       /* 둥근 모서리 */
        color: #0D47A1;           /* 텍스트 색상 */
        font-size: 16px;          /* 텍스트 크기 */
        padding: 5px;             /* 내부 여백 */
    }
    .stMultiselect div[data-baseweb="select"] > div {
        background-color: #BBDEFB; /* 드롭다운 배경색 */
        color: #0D47A1;           /* 드롭다운 텍스트 색상 */
    }
    .stMultiselect div[data-baseweb="select"]:hover {
        border-color: #1976D2;   /* 호버 시 테두리 색상 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 멀티 셀렉트 생성
options = ["Python", "JavaScript", "Java", "C++", "Go"]
selected = st.multiselect("좋아하는 프로그래밍 언어를 선택하세요:", options)

# 선택된 옵션 출력
if selected:
    st.write("선택한 언어:", selected)

7. .stSlider: 슬라이더 스타일링
설명: st.slider와 관련된 슬라이더의 스타일을 제어합니다.
적용 가능한 스타일:
슬라이더 색상, 높이, 손잡이 스타일 등
예제:

import streamlit as st

# stSlider 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stSlider>div>div {
        background-color: #ddd;   /* 슬라이더 배경 */
        height: 8px;             /* 슬라이더 높이 */
    }
    .stSlider>div>div>div {
        background-color: #4CAF50; /* 활성 슬라이더 색상 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 슬라이더 생성
st.slider("슬라이더를 움직여보세요", 0, 100, 50)

8. .stTable: 테이블 스타일링
설명: st.write 또는 st.dataframe에서 생성된 테이블의 스타일을 제어합니다.
적용 가능한 스타일:
테이블 테두리, 배경색, 텍스트 색상 등
예제:

import pandas as pd
import streamlit as st

# stTable 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stTable {
        border: 1px solid #ddd;  /* 테이블 테두리 */
        border-radius: 5px;      /* 둥근 테두리 */
        background-color: #f9f9f9; /* 테이블 배경색 */
        font-size: 16px;         /* 텍스트 크기 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 테이블 데이터 출력
data = pd.DataFrame({
    "Name": ["Alice", "Bob", "Charlie"],
    "Age": [25, 30, 35],
    "City": ["New York", "San Francisco", "Los Angeles"]
})

st.write(data)

9. .stProgress: 프로그래스바 스타일링
설명: 진행 상태를 표시하는 프로그래스바(st.progress)의 스타일을 제어합니다.
적용 가능한 스타일:
진행 색상, 높이 등
예제: 

import time
import streamlit as st

# stProgress 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stProgress>div>div>div {
        background-color: #4CAF50; /* 진행 상태 색상 */
        height: 20px;             /* 진행 바 높이 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 프로그래스바 생성
progress = st.progress(0)
for i in range(101):
    time.sleep(0.05)
    progress.progress(i)

9.1. .stImage: 이미지 스타일링
설명: 이미지 요소(st.image)에 대한 스타일을 제어합니다.
적용 가능한 스타일:
이미지 크기, 정렬, 테두리, 그림자 등
예제:

import streamlit as st

# stImage 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stImage img {
        border-radius: 15px;         /* 둥근 모서리 */
        border: 2px solid #4CAF50;  /* 테두리 */
        box-shadow: 5px 5px 15px rgba(0,0,0,0.3); /* 그림자 효과 */
        max-width: 80%;             /* 최대 너비 제한 */
        margin: auto;               /* 이미지 중앙 정렬 */
        display: block;             /* 블록 요소로 변환 */
    }
    
    </style>
    """,
    unsafe_allow_html=True
)

# 이미지 출력
st.image(
    "https://via.placeholder.com/400",
    caption="이것은 예제 이미지입니다."
)


여기서 box-shadow: offset-x offset-y blur-radius spread-radius color;
offset-x (5px):
그림자의 수평 오프셋입니다.
예를 들어, 5px는 그림자가 요소의 오른쪽으로 5픽셀 이동하게 합니다.
offset-y (5px):
그림자의 수직 오프셋입니다.
예를 들어, 5px는 그림자가 요소의 아래로 5픽셀 이동하게 합니다.
blur-radius (15px):
그림자의 흐림 정도를 설정합니다.
예를 들어, 15px는 그림자가 비교적 부드럽게 흐려지도록 만듭니다.
spread-radius (0px in the example, but if included):
그림자의 확산 정도입니다.
예를 들어, -5px는 그림자가 작아지게 만들고, 5px는 그림자가 커지게 만듭니다.
color (rgba(0,0,0,0.5)):
그림자의 색상을 지정합니다.
rgba(0,0,0,0.5)는 반투명한 검은색을 의미합니다. (검정색이고 투명도가 50%인 색상)
rgba에서 (0, 0, 0)은 RGB 색상 값 (검정색)이며, 0.5는 투명도를 나타냅니다. 
(1은 불투명, 0은 완전히 투명)

9. .stInput: 입력 상자 스타일링
설명: 텍스트 입력 필드(st.text_input, st.text_area)의 스타일을 제어합니다.
적용 가능한 스타일:
입력 상자의 배경색, 테두리, 글꼴 스타일 등
예제:

import streamlit as st

# stInput 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stTextInput>div>input {
        background-color: #F9F9F9;  /* 배경색 */
        color: #333;               /* 텍스트 색상 */
        border: 2px solid #4CAF50; /* 테두리 */
        padding: 10px;             /* 내부 여백 */
        border-radius: 5px;        /* 둥근 모서리 */
        font-size: 16px;           /* 글꼴 크기 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 텍스트 입력 생성
user_input = st.text_input("당신의 이름은 무엇인가요?")
if user_input:
    st.write(f"안녕하세요, {user_input}님!")

10. .stTextInput: 텍스트 입력 필드 스타일
설명: 텍스트 입력 위젯(st.text_input())의 스타일을 제어합니다.
적용 가능한 스타일:
입력 필드 배경색, 테두리, 글꼴 크기, 텍스트 색상 등
예제:

import streamlit as st

# stTextInput 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stTextInput > div > div > input {
        background-color: #E8F5E9; /* 입력 필드 배경색 */
        border: 2px solid #4CAF50; /* 테두리 색상 */
        border-radius: 8px;       /* 둥근 모서리 */
        font-size: 16px;          /* 글꼴 크기 */
        color: #1B5E20;           /* 텍스트 색상 */
        padding: 10px;            /* 내부 여백 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 텍스트 입력 필드 생성
user_text = st.text_input("이름을 입력하세요:")
if user_text:
    st.write(f"안녕하세요, {user_text}님!")

10.1 .stTextArea: 텍스트 영역 스타일
설명: 텍스트 영역 위젯(st.text_area())의 스타일을 제어하는 클래스입니다. 텍스트 입력 필드와 유사하지만, 여러 줄 입력이 가능합니다.
적용 가능한 스타일:
배경색, 테두리, 글꼴 크기, 내부 여백 등
예제:

import streamlit as st

# stTextArea 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stTextArea textarea {
        background-color: #FFEBEE; /* 텍스트 영역 배경색 */
        border: 2px solid #F44336; /* 테두리 색상 */
        border-radius: 8px;       /* 둥근 모서리 */
        font-size: 16px;          /* 텍스트 크기 */
        color: #D32F2F;           /* 텍스트 색상 */
        padding: 10px;            /* 내부 여백 */
        line-height: 1.5;         /* 줄 간격 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 텍스트 영역 생성
user_text = st.text_area("의견을 입력하세요:", height=150)
if user_text:
    st.write("입력된 의견:")
    st.write(user_text)

11. .stAlert: 경고 메시지 스타일링
설명: 경고 메시지(st.warning, st.error, st.info, st.success)의 스타일을 제어합니다.

적용 가능한 스타일:
메시지 색상, 글꼴 크기, 테두리 등
예제:

import streamlit as st

# stAlert 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stAlert {
        background-color: #FFEBE6; /* 경고 메시지 배경색 */
        border-left: 5px solid #FF4500; /* 왼쪽 테두리 강조 */
        padding: 10px;           /* 내부 여백 */
        font-size: 18px;         /* 글꼴 크기 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 경고 메시지 출력
st.warning("이것은 경고 메시지입니다!")

12. .stFileUploader: 파일 업로더와 관련된 스타일
설명: 파일 업로드 위젯(st.file_uploader())의 스타일을 제어합니다.
적용 가능한 스타일:
배경색, 테두리, 글꼴 크기, 업로드 버튼 디자인 등
예제:

import streamlit as st

# stFileUploader 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stFileUploader {
        background-color: #f5f5f5;  /* 배경색 */
        border: 2px dashed #4CAF50; /* 점선 테두리 */
        padding: 15px;              /* 내부 여백 */
        border-radius: 10px;        /* 둥근 모서리 */
        text-align: center;         /* 텍스트 중앙 정렬 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 파일 업로드 위젯 생성
uploaded_file = st.file_uploader("파일을 업로드하세요")
if uploaded_file is not None:
    st.write(f"업로드된 파일 이름: {uploaded_file.name}")

13. .stRadio: 라디오 버튼 스타일링
설명: 라디오 버튼 요소(st.radio)의 스타일을 제어합니다.
적용 가능한 스타일:
버튼 크기, 색상, 간격 등
예제:

import streamlit as st

# stRadio 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stRadio>div {
        font-size: 16px;           /* 텍스트 크기 */
        color: #4CAF50;           /* 텍스트 색상 */
        margin-bottom: 15px;      /* 하단 여백 */
    }
    .stRadio>div>div>div {
        background-color: #FFF;   /* 버튼 배경색 */
        border: 2px solid #4CAF50; /* 버튼 테두리 */
        border-radius: 5px;       /* 둥근 모서리 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 라디오 버튼 생성
choice = st.radio("하나를 선택하세요:", ["옵션 A", "옵션 B", "옵션 C"])
st.write(f"선택된 옵션: {choice}")

14. .stCheckbox: 체크박스 스타일링
설명: 체크박스 요소(st.checkbox)의 스타일을 제어합니다.
적용 가능한 스타일:
체크박스 크기, 간격, 색상 등
예제:

import streamlit as st

# stCheckbox 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stCheckbox>div {
        font-size: 18px;            /* 체크박스 텍스트 크기 */
        color: #4CAF50;            /* 텍스트 색상 */
        margin-top: 10px;          /* 상단 여백 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 체크박스 생성
agree = st.checkbox("동의하시겠습니까?")
if agree:
    st.write("감사합니다! 동의하셨습니다.")

15. .stTextArea: 텍스트 영역 스타일
설명: 텍스트 영역 위젯(st.text_area())의 스타일을 제어합니다.
적용 가능한 스타일:
배경색, 테두리, 글꼴 크기 등
예제:

import streamlit as st

# stTextArea 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stTextArea textarea {
        background-color: #FFF3E0; /* 배경색 */
        border: 1px solid #FF5722; /* 테두리 색상 */
        border-radius: 5px;       /* 둥근 모서리 */
        font-size: 16px;          /* 텍스트 크기 */
        padding: 10px;            /* 내부 여백 */
        color: #333;              /* 텍스트 색상 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 텍스트 영역 생성
user_input = st.text_area("자유롭게 텍스트를 입력하세요:")
st.write(f"입력된 텍스트: {user_input}")

16. .stMetric: 메트릭 카드 스타일
설명: 메트릭 카드 위젯(st.metric())의 스타일을 제어합니다.
적용 가능한 스타일:
배경색, 글꼴 크기, 값의 색상 강조 등
예제:

import streamlit as st

# stMetric 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stMetric {
        background-color: #E3F2FD; /* 배경색 */
        border: 1px solid #2196F3; /* 테두리 */
        border-radius: 5px;       /* 둥근 모서리 */
        padding: 10px;            /* 내부 여백 */
        color: #1A237E;           /* 텍스트 색상 */
        font-size: 18px;          /* 글꼴 크기 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 메트릭 카드 생성
st.metric(label="매출", value="$10,000", delta="+5%")

17. .stExpander: 확장 가능한 요소 스타일
설명: 확장 가능한 요소 위젯(st.expander())의 스타일을 제어합니다.
적용 가능한 스타일:
확장 상태의 배경색, 테두리, 글꼴 크기 등
예제:

import streamlit as st

# stExpander 클래스에 스타일 적용
st.markdown(
    """
    <style>
    .stExpander>div>div {
        background-color: #FFEBEE; /* 확장 요소 배경색 */
        border: 1px solid #F44336; /* 테두리 */
        border-radius: 5px;       /* 둥근 모서리 */
        color: #880E4F;           /* 텍스트 색상 */
        font-size: 16px;          /* 텍스트 크기 */
    }
    </style>
    """,
    unsafe_allow_html=True
)

# 확장 가능한 요소 생성
with st.expander("자세히 보기"):
    st.write("이것은 확장 가능한 콘텐츠입니다.")

 

그런데 여기서 > div란 개념이 나옵니다. 하나가 아니라 여러개로....

저게 뭘까요?

> div 같은 CSS 선택자는 HTML 구조의 계층을 따라 정확히 특정 요소를 타겟팅하기 위해 사용됩니다. Streamlit 위젯은 여러 중첩된 <div> 태그를 사용하여 위젯을 렌더링하기 때문에, CSS 선택자에서 계층 구조를 따라야 원하는 요소에 스타일을 적용할 수 있습니다.

 

여기서 CSS 선택자라는 개념을 확실히 밟고 가야합니다.

CSS의 > 선택자란?
>는 직접적인 자식 요소만을 선택할 때 사용됩니다.
예:
.parent > .child {
    color: red;
}

위 코드는 .parent의 바로 아래 자식 요소 중 클래스가 .child인 것만 스타일링합니다.

Streamlit에서 > div가 왜 여러 단계로 필요한가?
Streamlit 위젯들은 HTML DOM(Document Object Model) 구조에서 여러 계층으로 중첩된 <div> 요소를 포함합니다. 예를 들어, st.multiselect 위젯의 구조를 보면:

<div class="stMultiselect">
    <div>
        <div data-baseweb="select">
            <div>...드롭다운 내용...</div>
        </div>
    </div>
</div>

여기서:
.stMultiselect: 최상위 컨테이너.
.stMultiselect > div: 첫 번째 자식 요소.
.stMultiselect > div > div[data-baseweb="select"]: 두 번째 레벨의 특정 자식 요소.
.stMultiselect > div > div[data-baseweb="select"] > div: 세 번째 레벨의 자식 요소로, 드롭다운 내부를 가리킴.

왜 여러 계층을 따라야 하나요?
HTML 구조에서 모든 요소에 동일한 클래스명이 부여되지 않기 때문입니다. 특정 스타일을 적용하려면 중첩된 요소를 정확히 찾아야 합니다.
예시: Streamlit의 멀티 셀렉트 구조

<div class="stMultiselect">
    <div>
        <div data-baseweb="select">
            <div>옵션 1</div>
            <div>옵션 2</div>
        </div>
    </div>
</div>

CSS 적용
.stMultiselect: 최상위 컨테이너에 스타일 적용.
.stMultiselect > div: 첫 번째 자식 컨테이너 스타일.
.stMultiselect > div > div[data-baseweb="select"]: 드롭다운 부분의 스타일.
.stMultiselect > div > div[data-baseweb="select"] > div: 개별 옵션의 스타일.

결론
> div가 필요한 이유: Streamlit 위젯의 구조가 중첩되어 있어 특정 요소를 타겟팅하려면 계층을 따라야 함.
CSS 선택자 사용법:
최상위 클래스를 기준으로 스타일 적용.
내부 계층 요소를 따라가며 특정 부분에 세부 스타일 적용.
실전 팁:
Streamlit 앱을 실행한 후 브라우저의 **개발자 도구(F12)**를 사용해 DOM 구조를 확인하면, 필요한 CSS 경로를 쉽게 찾을 수 있습니다.

혹시 어렵다고 느끼시면 더 쉽게 설명해보겠습니다.
CSS 선택자는 HTML에서 "어떤 걸 꾸밀지"를 골라주는 도구이며. 마치 방 안에 있는 장난감들 중에 "어떤 장난감만 꾸밀지" 정하는 것과 비슷합니다.

HTML 구조를 집안으로 비유하기
집 안 구조
우리가 꾸미려는 HTML은 마치 방과 방이 이어져 있는 집 같습니다.
예를 들어, 이런 집이 있다고 해보면:

집 (div1)
  ├ 거실 (div2)
  │   ├ 소파 (div3)
  │   ├ TV (div4)
  ├ 부엌 (div5)
      ├ 냉장고 (div6)

여기서 집(div1) 안에 거실(div2)과 부엌(div5)이 있고, 그리고 거실 안에는 소파(div3)와 TV(div4)가 있고, 부엌 안에는 냉장고(div6)가 있습니다.

CSS에서 > 선택자가 하는 일
> 선택자는 "바로 옆방에 있는 아이만 꾸며"라는 명령이며,
예를 들어, 이렇게 생긴 코드가 있다고 해보면:

<div class="집">
    <div class="거실">
        <div class="소파">소파</div>
        <div class="TV">TV</div>
    </div>
    <div class="부엌">
        <div class="냉장고">냉장고</div>
    </div>
</div>


만약 꾸민다고 하면,
1. 모두 꾸미기 (아무런 제한 없이)

.집 div {
    background-color: yellow; /* 집 안의 모든 방 배경을 노란색으로 */
}

결과: 거실, 소파, TV, 부엌, 냉장고 모두 노란색으로 칠해짐.

2. 직접 자식만 꾸미기 (>)

.집 > div {
    background-color: yellow; /* 바로 집 밑에 있는 방(거실, 부엌)만 */
}

결과: 거실과 부엌만 노란색이 되고, 소파, TV, 냉장고는 영향을 받지 않음.

Streamlit에서 왜 이렇게 복잡할까?
Streamlit에서 사용하는 HTML은 우리가 만드는 모든 위젯을 각각 방처럼 여러 계층으로 나눠서 저장하기 때문입니다.
예를 들어, 멀티 셀렉트 위젯의 HTML 구조는 다음과 같이 생겼습니다:

<div class="stMultiselect">
    <div> <!-- 부모 방 -->
        <div data-baseweb="select"> <!-- 자식 방 -->
            <div>옵션 1</div>
            <div>옵션 2</div>
        </div>
    </div>
</div>


예제: 멀티 셀렉트 위젯 꾸미기

.stMultiselect > div { 
    background-color: lightblue; /* 바로 아래 부모 방만 */
}
.stMultiselect > div > div[data-baseweb="select"] {
    background-color: lightgreen; /* 드롭다운(자식 방) */
}
.stMultiselect > div > div[data-baseweb="select"] > div {
    color: red; /* 드롭다운 안의 옵션들 */
}

.stMultiselect: 이건 "집" 전체입니다.
.stMultiselect > div: 집 안에 바로 있는 "거실과 부엌" 같은 방을 꾸밉니다.
.stMultiselect > div > div[data-baseweb="select"]: 방 안에 있는 "TV" 같은 물건을 꾸밉니다.
.stMultiselect > div > div[data-baseweb="select"] > div: TV 화면 속에 나오는 "그림" 같은 세부적인 부분을 꾸밉니다.

왜 이렇게 나눠서 쓰는 걸까?
다른 부분에 영향을 주지 않기 위해: 소파만 꾸미고 싶을 때, 거실 전체를 꾸미면 안될때.
세밀하게 꾸밀 수 있도록: TV도 꾸미고, TV 화면 속 그림도 따로 꾸밀 수 있어야 하기때문.

 

하지만 이건 뭘까요?
[data-baseweb="select"]
CSS에서 [data-baseweb="select"] 같은 속성 선택자를 쓰는 이유는 특정 HTML 요소를 더 정확히 타겟팅하기 위해서입니다. div만 쓰면 너무 포괄적이거나 원하는 요소와 다른 요소들까지 영향을 받을 수 있기 때문입니다.

들어가기전 드롭다운이 뭔지 살짝 예시로 알려드리겠습니다.
드롭다운(dropdown)은 웹 페이지에서 자주 사용되는 UI 요소 중 하나로, 선택 가능한 여러 항목을 숨기고, 사용자가 클릭하거나 터치하면 항목들이 나타나는 메뉴입니다.
[영어 ▼]
    - 영어
    - 한국어
    - 일본어
    - 스페인어
영어를 누르면 그 안 항복들이 보이게 됩니다!

왜 속성 선택자를 쓰는 걸까?
HTML 구조가 복잡해서 특정 요소만 골라야 할 때
Streamlit에서 모든 위젯은 여러 겹으로 중첩된 <div>로 만들어져 있습니다.
예를 들어, 이런 구조가 있다고 해보겠습니다:
<div class="stMultiselect">
    <div>
        <div data-baseweb="select"> <!-- 드롭다운 컨테이너 -->
            <div>옵션 1</div>
            <div>옵션 2</div>
        </div>
    </div>
</div>
여기서 data-baseweb="select"는 "이 드롭다운은 Select 컴포넌트다"라는 정보를 나타내요. 만약 우리가 단순히 div만 선택한다면: 
.stMultiselect div {
    background-color: yellow;
}

결과: 모든 div가 노란색이 됩니다.
문제: 드롭다운뿐만 아니라 옵션(옵션 1, 옵션 2)까지 영향을 받죠.


중요! 필터링해서 정확히 타겟팅하기 위해속성 선택자를 쓰면 특정 요소만 정확히 골라낼 수 있어요:
.stMultiselect div[data-baseweb="select"] {
    background-color: yellow; /* 드롭다운만 노란색으로 */
}

결과: 드롭다운 컨테이너만 영향을 받습니다.

속성 선택자의 역할
1. 특정 속성을 가진 요소만 선택

[속성명="값"] {
    스타일;
}

[data-baseweb="select"]: data-baseweb이라는 속성값이 "select"인 요소만 선택.

2. 다른 요소와 혼동을 방지
div만 쓰면 모든 div가 영향을 받을 수 있어요.
속성 선택자를 추가하면 특정 속성을 가진 div만 타겟팅할 수 있죠.

참고로 select 요소가 여러 개 있을 때, 부모 요소를 기준으로 스타일을 지정할 수 있습니다. 예를 들어, 하나의 select 요소는 div 안에 있고, 다른 하나는 form 안에 있을 때, 부모 요소를 기준으로 선택자를 작성할 수 있습니다. 

<div class="select-group">
    <div data-baseweb="select">Select 1</div>
</div>
<form>
    <div data-baseweb="select">Select 2</div>
</form>
/* .select-group 안에 있는 data-baseweb="select" 선택 */
.select-group div[data-baseweb="select"] {
    background-color: lightblue;
}

/* form 안에 있는 data-baseweb="select" 선택 */
form div[data-baseweb="select"] {
    background-color: lightgreen;
}



하지만 속성 선택자는 data-baseweb 외에도 다양한 속성들을 사용할 수 있습니다! 기본적으로 속성 선택자는 HTML 요소의 특정 속성(attribute)을 기준으로 해당 요소를 선택하는 방법입니다. data-baseweb은 Streamlit 같은 UI 프레임워크에서 사용하는 속성 중 하나일 뿐이며, HTML 요소에는 다양한 속성들이 존재합니다.
일단 스트림릿에는 data-baseweb을 주로 쓰며 이것만 알면 됩니다!

일단! 오늘은 여기까지...코드 적으러 가야지....