대부분의 CSS 개념은 Roblox 스타일링 개념에 매핑됩니다. 다음 예시는 CSS와 HTML이 Luau 및 Roblox 클래스/속성에 어떻게 정렬되는지를 보여줍니다.
다음 Luau 스크립트 예제를 테스트하려면:
Explorer에서 다음을 생성합니다:

- StyleSheet 인스턴스를 ReplicatedStorage 안에 생성합니다.
- ScreenGui 컨테이너를 StarterGui 안에 생성합니다.
- LocalScript 인스턴스를 ScreenGui 안에 생성합니다.
LocalScript에 다음 지원 코드를 붙여넣습니다:
LocalScriptlocal CollectionService = game:GetService("CollectionService")local ReplicatedStorage = game:GetService("ReplicatedStorage")local coreSheet = ReplicatedStorage:FindFirstChildWhichIsA("StyleSheet")local screenGui = script.Parentlocal styleLink = screenGui:FindFirstChildWhichIsA("StyleLink")styleLink.StyleSheet = coreSheet아래 각 예제에 대해 지원 라인 1-7을 따르는 Luau 코드 라인을 붙여넣습니다.
선택자
Selector 속성의 StyleRule은 규칙이 적용될 인스턴스를 지정합니다. 다음 선택자 유형은 CSS에서 Luau로 매핑되며 조합자와 함께 사용할 수 있습니다.
요소
CSS 요소 선택자와 동등한 Roblox 클래스 선택자는 특정 GuiObject 클래스의 모든 인스턴스를 선택합니다. 예를 들어 Frame, ImageLabel, TextButton 등이 있습니다.
CSSbutton {background-color: #335FFF;color: #E1E1E1;width: 15%;height: 40px;border: none;}
HTML<button>메인 메뉴</button>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "TextButton" -- Roblox 클래스 선택자rule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.15, 0, 0, 40),BorderSizePixel = 0})local button = Instance.new("TextButton")button.Text = "메인 메뉴"button.Parent = screenGui
클래스
CSS class 선택자에 대한 Roblox의 동등한 개념은 태그 선택자이며, CollectionService를 통해 적용된 태그를 활용합니다.
CSS.button-primary {background-color: #335FFF;color: #E1E1E1;}
HTML<button class="button-primary">메인 메뉴</button>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = ".ButtonPrimary" -- Roblox 태그 선택자rule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),AutomaticSize = Enum.AutomaticSize.XY})local button = Instance.new("TextButton")button.Text = "메인 메뉴"button.Parent = screenGui-- 버튼에 태그 적용CollectionService:AddTag(button, "ButtonPrimary")
식별자
CSS id에 가장 가까운 Roblox의 비교는 #[name] 선택자입니다. 이 선택자는 Instance.Name의 값에 따라 선택합니다. W3C 명세의 id 속성과 달리 이름은 고유할 필요가 없습니다.
CSS#modal-frame {background-color: #000022;opacity: 0.5;width: 50%;min-height: 100px;}
HTML<div id="modal-frame"></div>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "#ModalFrame" -- 인스턴스 이름 선택자rule:SetProperties({BackgroundColor3 = Color3.fromHex("000022"),BackgroundTransparency = 0.5,Size = UDim2.new(0.5, 0, 0, 100),AutomaticSize = Enum.AutomaticSize.Y})local frame = Instance.new("Frame")frame.Parent = screenGui-- 선택자와 일치하도록 프레임 이름 변경frame.Name = "ModalFrame"
조합자
조합자를 통해 기본 선택자를 혼합하여 더 깊은 계층 관계를 일치시킬 수 있습니다.
자식
> 자식 선택자는 CSS와 Roblox에서 동일합니다.
CSS.menu-container {width: 25%;}.menu-container > button {background-color: #335FFF;color: #E1E1E1;width: 80%;height: 40px;border: none;}
HTML<div class="menu-container"><button>옵션</button></div>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = ".MenuContainer > TextButton" -- 자식 선택자rule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.8, 0, 0, 40),BorderSizePixel = 0})-- 메뉴 컨테이너 생성local menuContainer = Instance.new("Frame")menuContainer.Size = UDim2.new(0.25, 0, 0, 0)menuContainer.AutomaticSize = Enum.AutomaticSize.YmenuContainer.Parent = screenGui-- 태그 적용CollectionService:AddTag(menuContainer, "MenuContainer")-- 버튼 생성local button = Instance.new("TextButton")button.Text = "옵션"-- 버튼의 부모를 메뉴 컨테이너로 설정button.Parent = menuContainer
자손
CSS 공백 구문과 달리, 예를 들어 <Typography noWrap>.menu-container button과 같이, Roblox는 자손 관계를 나타내기 위해 >>` 조합자를 사용합니다.
CSS.menu-container {width: 25%;}.sub-container {width: 75%;}.menu-container button {background-color: #335FFF;color: #E1E1E1;width: 80%;height: 40px;border: none;}
HTML<div class="menu-container"><div class="sub-container"><button>옵션</button></div></div>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = ".MenuContainer >> TextButton" -- 자손 선택자rule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.8, 0, 0, 40),BorderSizePixel = 0})-- 메뉴 컨테이너 생성local menuContainer = Instance.new("Frame")menuContainer.Size = UDim2.new(0.25, 0, 0, 0)menuContainer.AutomaticSize = Enum.AutomaticSize.YmenuContainer.Parent = screenGui-- 태그 적용CollectionService:AddTag(menuContainer, "MenuContainer")-- 서브 컨테이너 생성local subContainer = Instance.new("Frame")subContainer.Size = UDim2.new(0.75, 0, 0, 0)subContainer.AutomaticSize = Enum.AutomaticSize.Y-- 메뉴 컨테이너를 서브 컨테이너의 부모로 설정subContainer.Parent = menuContainer-- 버튼 생성local button = Instance.new("TextButton")button.Text = "옵션"-- 서브 컨테이너를 버튼의 부모로 설정button.Parent = subContainer
선택자 목록
여러 선택자(조합자와 함께 포함됨)는 동일한 속성 블록으로 선언할 수 있으며, 쉼표로 구분하여 중복성을 줄일 수 있습니다.
CSSimg, p {background-color: #FF0033;}
HTML<img src="gear.png" width="100" height="100"><p>메인 메뉴</p>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "ImageLabel, TextLabel" -- 이미지 레이블 및 텍스트 레이블에 대한 선택자rule:SetProperty("BackgroundColor3", Color3.fromHex("ff0033"))-- 이미지 레이블 생성local imageLabel = Instance.new("ImageLabel")imageLabel.Image = "rbxassetid://104919049969988"imageLabel.Size = UDim2.new(0, 100, 0, 100)imageLabel.Parent = screenGui-- 텍스트 레이블 생성local textLabel = Instance.new("TextLabel")textLabel.Size = UDim2.new(1, 0, 0, 0)textLabel.AutomaticSize = Enum.AutomaticSize.YtextLabel.TextXAlignment = Enum.TextXAlignment.LefttextLabel.TextYAlignment = Enum.TextYAlignment.ToptextLabel.Text = "메인 메뉴"textLabel.Parent = screenGui
의사 클래스
Roblox의 CSS 의사 클래스 선택자는 상태 선택자로, Hover 또는 Press와 같은 네 가지 Enum.GuiState 값 중 하나에 해당합니다.
CSSimg:hover {opacity: 0.5;}
HTML<img src="gear.png" width="100" height="100">
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "ImageLabel:Hover" -- 상태 선택자rule:SetProperty("ImageTransparency", 0.5)-- 이미지 레이블 생성local imageLabel = Instance.new("ImageLabel")imageLabel.Image = "rbxassetid://104919049969988"imageLabel.Size = UDim2.new(0, 100, 0, 100)imageLabel.BackgroundTransparency = 1imageLabel.Parent = screenGui
의사 인스턴스
CSS 의사 엘리먼트가 요소의 특정 부분을 수정할 수 있는 것처럼, Roblox는 스타일 규칙의 Selector 속성을 통해 유령 UIComponents를 생성할 수 있습니다. 예를 들어, 다음 규칙은 RoundedCorner20로 태그된 모든 Frame 아래에 UICorner 수정자를 효과적으로 생성하고 각 수정자의 CornerRadius를 20픽셀로 설정합니다.
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "Frame.RoundedCorner20::UICorner" -- UI 컴포넌트 선택자rule:SetProperty("CornerRadius", UDim.new(0, 20))-- 프레임 생성local frame = Instance.new("Frame")frame.Size = UDim2.new(0.4, 0, 0.2, 0)frame.Parent = screenGui-- 프레임에 태그 적용CollectionService:AddTag(frame, "RoundedCorner20")
쿼리
Roblox 스타일 쿼리는 CSS 미디어 쿼리 및 컨테이너 쿼리 사이의 격차를 메워줍니다. @ 접두사를 사용하여 부모 치수, 입력 장치 유형 또는 사용자 접근성 설정에 따라 스타일을 전환할 수 있습니다.
CSS의 경우, @container는 상위 요소의 크기에 따라 스타일을 적용합니다. Roblox에서는 ::StyleQuery 다음에 조건의 Selector 속성에 대한 식별자를 사용하여 유사 인스턴스 쿼리를 정의합니다. 예를 들어 "::StyleQuery #WideContainer"와 함께 조건 이름인 "MinSize"를 사용하여 부모의 GuiObject.AbsoluteSize를 평가합니다. 그런 다음 쿼리가 활성화되면 인스턴스 또는 해당 자식에 스타일을 적용하려면 @[identifier] 접두사가 있는 StyleRule를 생성합니다. 예를 들어 @WideContainer가 있습니다.
CSS.container {container-type: inline-size;background-color: rgba(0, 0, 34, 0.5);}button {background-color: #335FFF;color: #E1E1E1;width: 75%;height: 40px;border: none;}@container (min-width: 400px) {button {background-color: #cc0033;}}
HTML<div class="container" style="width: 80%; height: 200px;"><button>메인 메뉴</button></div>
Luau-- 컨테이너 규칙local containerRule = Instance.new("StyleRule")containerRule.Selector = "Frame" -- Roblox 클래스 선택자containerRule:SetProperties({BackgroundColor3 = Color3.fromRGB(0, 0, 34),BackgroundTransparency = 0.5,BorderSizePixel = 0})containerRule.Parent = coreSheet-- 버튼 규칙local buttonRule = Instance.new("StyleRule")buttonRule.Selector = "TextButton" -- Roblox 클래스 선택자buttonRule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.75, 0, 0, 40),BorderSizePixel = 0})buttonRule.Parent = containerRule -- 컨테이너 규칙의 자식-- 쿼리 조건 (#WideContainer)local queryCondition = Instance.new("StyleRule")queryCondition.Selector = "::StyleQuery #WideContainer"queryCondition:SetProperty("MinSize", Vector2.new(400, 0))queryCondition.Parent = containerRule -- 컨테이너 규칙의 자식-- 조건이 활성화될 때 적용되는 규칙 (@WideContainer)local queryStyle = Instance.new("StyleRule")queryStyle.Selector = "@WideContainer Frame > TextButton" -- 자식 선택자queryStyle:SetProperty("BackgroundColor3", Color3.fromHex("CC0033"))queryStyle.Parent = containerRule -- 컨테이너 규칙의 자식-- 인스턴스 생성local container = Instance.new("Frame")container.Size = UDim2.new(0.8, 0, 0, 200)container.Parent = screenGuilocal button = Instance.new("TextButton")button.Text = "메인 메뉴"button.Parent = container
Roblox는 또한 ViewportDisplaySize 또는 ReducedMotionEnabled와 같은 글로벌 환경 상태에 직접 매핑되는 내장 쿼리를 제공합니다. 이러한 쿼리는 ::StyleQuery 정의가 필요 없으며 @ 접두사와 함께 직접 사용할 수 있습니다.
| CSS 미디어 기능 | Roblox 스타일 쿼리 선택자 |
|---|---|
| (max-width: 600px) | @ViewportDisplaySizeSmall |
| (min-width: 601px) and (max-width: 1200px) | @ViewportDisplaySizeMedium |
| (min-width: 1201px) | @ViewportDisplaySizeLarge |
| (pointer: fine) | @PreferredInputKeyboardAndMouse |
| (pointer: coarse) | @PreferredInputTouch |
| (any-pointer: coarse) | @PreferredInputGamepad |
| (prefers-reduced-motion: reduce) | @ReducedMotionEnabledTrue |
| (prefers-reduced-motion: no-preference) | @ReducedMotionEnabledFalse |
CSS.container {container-type: inline-size;background-color: rgba(0, 0, 34, 0.5);}@media (prefers-reduced-motion: reduce) {.container {background-color: rgba(0, 0, 34, 1);}}
HTML<div class="container" style="width: 80%; height: 200px;"></div>
Luau-- 컨테이너 규칙local containerRule = Instance.new("StyleRule")containerRule.Selector = "Frame" -- Roblox 클래스 선택자containerRule:SetProperties({BackgroundColor3 = Color3.fromRGB(0, 0, 34),BackgroundTransparency = 0.5,BorderSizePixel = 0})containerRule.Parent = coreSheet-- 내장 쿼리local motionRule = Instance.new("StyleRule")motionRule.Selector = "@ReducedMotionEnabledTrue Frame"motionRule:SetProperty("BackgroundTransparency", 0)motionRule.Parent = containerRule -- 컨테이너 규칙의 자식-- 인스턴스 생성local container = Instance.new("Frame")container.Size = UDim2.new(0.8, 0, 0, 200)container.Parent = screenGui
변수
CSS는 스타일 시스템 전반에 걸쳐 변수를 선언하고 참조할 수 있습니다. Roblox는 이를 통해 토큰 및 인스턴스 속성 시스템을 이용합니다. $를 접두사로 사용하면 스타일 속성을 설정할 때 StyleRule 또는 StyleSheet 상속 체인에서 선언된 속성을 참조할 수 있습니다.
CSS:root {--button-bg-color: #335FFF;--button-text-color: #E1E1E1;}button {background-color: var(--button-bg-color);color: var(--button-text-color);}
HTML<button>메인 메뉴</button>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheet-- 속성을 사용하여 스타일 시트 토큰 설정coreSheet:SetAttribute("ButtonBgColor", Color3.fromHex("335FFF"))coreSheet:SetAttribute("ButtonTextColor", Color3.fromHex("E1E1E1"))rule.Selector = "TextButton" -- 클래스 선택자rule:SetProperties({BackgroundColor3 = "$ButtonBgColor",TextColor3 = "$ButtonTextColor"})-- 버튼 생성local button = Instance.new("TextButton")button.AutomaticSize = Enum.AutomaticSize.XYbutton.Text = "메인 메뉴"button.Parent = screenGui
전환
CSS 전환은 속성 값을 설정된 지속 시간 동안 트윈할 수 있게 해줍니다. Roblox에서는 StyleRule의 SetPropertyTransition() (단일) 또는 SetPropertyTransitions() (여러 개)를 통해 속성 전환을 설정하여 이를 이룰 수 있습니다.
CSSbutton {background-color: #335FFF;color: #E1E1E1;width: 15%;height: 40px;border: none;transition:background-color 1s ease-out,transform 1.25s ease-out}button:hover {background-color: #33AAFF;transform: rotate(-5deg);}
HTML<button>메인 메뉴</button>
Luau-- 버튼 규칙local buttonRule = Instance.new("StyleRule")buttonRule.Selector = "TextButton" -- Roblox 클래스 선택자buttonRule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.15, 0, 0, 40),BorderSizePixel = 0})-- 속성 전환 동작 설정buttonRule:SetPropertyTransitions({BackgroundColor3 = TweenInfo.new(1, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out),Rotation = TweenInfo.new(1.25, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out)})buttonRule.Parent = coreSheet-- 버튼 호버 규칙local hoverRule = Instance.new("StyleRule")hoverRule.Selector = "TextButton:Hover" -- 상태 선택자hoverRule:SetProperties({AutoButtonColor = false,BackgroundColor3 = Color3.fromHex("33AAFF"),Rotation = -5})hoverRule.Parent = coreSheet-- 텍스트 버튼 생성local button = Instance.new("TextButton")button.Text = "메인 메뉴"button.Parent = screenGui
중첩 및 병합
SCSS 개념을 차용하여 StyleRules는 함께 중첩될 수 있으며 그 선택자는 병합됩니다.
SCSS#menu-frame {background-color: #000022;width: 25%;min-height: 200px;display: flex;flex-direction: column;justify-content: space-evenly;align-items: center;> button {background-color: #335FFF;color: #E1E1E1;width: 80%;height: 40px;border: none;&:hover {opacity: 0.5;}}}
HTML<div id="menu-frame"><button>매력</button><button>마나</button><button>스크롤</button></div>
Luau-- 메뉴 프레임 규칙local menuFrameRule = Instance.new("StyleRule")menuFrameRule.Selector = "#MenuFrame"menuFrameRule:SetProperties({BackgroundColor3 = Color3.fromHex("000022"),Size = UDim2.new(0.25, 0, 0, 200),AutomaticSize = Enum.AutomaticSize.Y})menuFrameRule.Parent = coreSheet-- 메뉴 레이아웃 규칙local menuLayoutRule = Instance.new("StyleRule")menuLayoutRule.Selector = "::UIListLayout"menuLayoutRule:SetProperties({FillDirection = Enum.FillDirection.Vertical,VerticalFlex = Enum.UIFlexAlignment.SpaceEvenly,HorizontalAlignment = Enum.HorizontalAlignment.Center})menuLayoutRule.Parent = menuFrameRule -- 메뉴 프레임 규칙을 부모로 설정-- 버튼 규칙local buttonRule = Instance.new("StyleRule")buttonRule.Selector = "> TextButton"buttonRule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.8, 0, 0, 40),BorderSizePixel = 0})buttonRule.Parent = menuFrameRule -- 메뉴 레이아웃 규칙을 부모로 설정-- 버튼 호버 규칙local buttonHoverRule = Instance.new("StyleRule")buttonHoverRule.Selector = ":Hover"buttonHoverRule:SetProperties({AutoButtonColor = false,BackgroundTransparency = 0.5,TextTransparency = 0.5})buttonHoverRule.Parent = buttonRule -- 버튼 규칙을 부모로 설정-- 부모 프레임 생성local menuFrame = Instance.new("Frame")menuFrame.Name = "MenuFrame"menuFrame.Parent = screenGui-- 프레임 내 버튼 생성local button1 = Instance.new("TextButton")button1.Text = "매력"button1.Parent = menuFramelocal button2 = Instance.new("TextButton")button2.Text = "마나"button2.Parent = menuFramelocal button3 = Instance.new("TextButton")button3.Text = "스크롤"button3.Parent = menuFrame