Większość koncepcji CSS odpowiada koncepcjom stylizacji w Robloxie. Poniższe przykłady pokazują, jak CSS i HTML są zgodne z klasami/właściwościami Luau i Roblox.
Aby przetestować każdy z poniższych przykładów skryptów Luau:
W Eksploratorze utwórz następujące elementy:

- instancję StyleSheet wewnątrz ReplicatedStorage.
- kontener ScreenGui w StarterGui.
- instancję LocalScript wewnątrz ScreenGui.
W LocalScript wklej następujący kod wspierający:
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 = coreSheetDla każdego przykładu poniżej wklej linie kodu Luau po liniach wspierających 1–7.
Selektory
Właściwość Selector klasy StyleRule określa, które instancje reguła powinna dotyczyć. Poniższe typy selektorów odpowiadają CSS w Luau i mogą być używane z kombinatorami.
Element
Odpowiednikiem selektorów elementów CSS są selektory klas Roblox, które wybierają wszystkie instancje danej klasy GuiObject, na przykład Frame, ImageLabel, TextButton itd.
button {
background-color: #335FFF;
color: #E1E1E1;
width: 15%;
height: 40px;
border: none;
}<button>Menu główne</button>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "TextButton" -- selektor klasy 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 = "Menu główne"
button.Parent = screenGuiKlasa
Odpowiednikiem selektorów class CSS w Robloxie są selektory tagów, które wykorzystują tagi stosowane przez CollectionService.
.button-primary {
background-color: #335FFF;
color: #E1E1E1;
}<button class="button-primary">Menu główne</button>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = ".ButtonPrimary" -- selektor tagu Roblox
rule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
AutomaticSize = Enum.AutomaticSize.XY
})
local button = Instance.new("TextButton")
button.Text = "Menu główne"
button.Parent = screenGui
-- Zastosuj tag do przycisku
CollectionService:AddTag(button, "ButtonPrimary")Identyfikator
Najbliższym porównaniem Roblox do CSS id jest selektor #[name], który wybiera zgodnie z wartością Instance.Name. W przeciwieństwie do specyfikacji W3C atrybutu id, nazwy nie muszą być unikalne.
#modal-frame {
background-color: #000022;
opacity: 0.5;
width: 50%;
min-height: 100px;
}<div id="modal-frame"></div>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "#ModalFrame" -- selektor nazwy instancji
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
-- Zmień nazwę ramki, aby pasowała do selektora
frame.Name = "ModalFrame"Kombinatory
Kombinatory pozwalają na mieszanie podstawowych selektorów, aby dopasować głębsze relacje hierarchiczne.
Dziecko
Selektor dziecka > jest identyczny w CSS i Robloxie.
.menu-container {
width: 25%;
}
.menu-container > button {
background-color: #335FFF;
color: #E1E1E1;
width: 80%;
height: 40px;
border: none;
}<div class="menu-container">
<button>Opcje</button>
</div>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = ".MenuContainer > TextButton" -- selektor dziecka
rule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.8, 0, 0, 40),
BorderSizePixel = 0
})
-- Utwórz kontener menu
local menuContainer = Instance.new("Frame")
menuContainer.Size = UDim2.new(0.25, 0, 0, 0)
menuContainer.AutomaticSize = Enum.AutomaticSize.Y
menuContainer.Parent = screenGui
-- Zastosuj tag
CollectionService:AddTag(menuContainer, "MenuContainer")
-- Utwórz przycisk
local button = Instance.new("TextButton")
button.Text = "Opcje"
-- Ustaw kontener menu jako rodzica przycisku
button.Parent = menuContainerPotomek
W przeciwieństwie do składni białych znaków CSS, na przykład .menu-container button widocznej tutaj, Roblox używa kombinatora >>, aby wskazać relację potomka.
.menu-container {
width: 25%;
}
.sub-container {
width: 75%;
}
.menu-container button {
background-color: #335FFF;
color: #E1E1E1;
width: 80%;
height: 40px;
border: none;
}<div class="menu-container">
<div class="sub-container">
<button>Opcje</button>
</div>
</div>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = ".MenuContainer >> TextButton" -- selektor potomka
rule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.8, 0, 0, 40),
BorderSizePixel = 0
})
-- Utwórz kontener menu
local menuContainer = Instance.new("Frame")
menuContainer.Size = UDim2.new(0.25, 0, 0, 0)
menuContainer.AutomaticSize = Enum.AutomaticSize.Y
menuContainer.Parent = screenGui
-- Zastosuj tag
CollectionService:AddTag(menuContainer, "MenuContainer")
-- Utwórz podkontener
local subContainer = Instance.new("Frame")
subContainer.Size = UDim2.new(0.75, 0, 0, 0)
subContainer.AutomaticSize = Enum.AutomaticSize.Y
-- Ustaw kontener menu jako rodzica podkontenera
subContainer.Parent = menuContainer
-- Utwórz przycisk
local button = Instance.new("TextButton")
button.Text = "Opcje"
-- Ustaw podkontener jako rodzica przycisku
button.Parent = subContainerLista selektorów
Wiele selektorów (w tym selektory z kombinatorami) można zadeklarować z tym samym blokiem właściwości, oddzielonym przecinkami, aby zredukować redundancję.
img, p {
background-color: #FF0033;
}<img src="gear.png" width="100" height="100">
<p>Menu główne</p>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "ImageLabel, TextLabel" -- selektor dla etykiet obrazów I etykiet tekstowych
rule:SetProperty("BackgroundColor3", Color3.fromHex("ff0033"))
-- Utwórz etykietę obrazu
local imageLabel = Instance.new("ImageLabel")
imageLabel.Image = "rbxassetid://104919049969988"
imageLabel.Size = UDim2.new(0, 100, 0, 100)
imageLabel.Parent = screenGui
-- Utwórz etykietę tekstową
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(1, 0, 0, 0)
textLabel.AutomaticSize = Enum.AutomaticSize.Y
textLabel.TextXAlignment = Enum.TextXAlignment.Left
textLabel.TextYAlignment = Enum.TextYAlignment.Top
textLabel.Text = "Menu główne"
textLabel.Parent = screenGuiPseudo-klasy
Odpowiednikiem selektorów pseudo-klas CSS w Robloxie są selektory stanów, które odpowiadają jednej z czterech wartości Enum.GuiState, takich jak Hover lub Press.
img:hover {
opacity: 0.5;
}<img src="gear.png" width="100" height="100">local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "ImageLabel:Hover" -- selektor stanu
rule:SetProperty("ImageTransparency", 0.5)
-- Utwórz etykietę obrazu
local imageLabel = Instance.new("ImageLabel")
imageLabel.Image = "rbxassetid://104919049969988"
imageLabel.Size = UDim2.new(0, 100, 0, 100)
imageLabel.BackgroundTransparency = 1
imageLabel.Parent = screenGuiPseudo-instancje
Podobnie jak w przypadku pseudo-elementów CSS, które mogą modyfikować konkretne części elementu, Roblox może tworzyć fantomowe UIComponents poprzez właściwość Selector reguły stylu. Na przykład, poniższa reguła skutecznie tworzy modyfikator UICorner pod każdą Frame oznaczoną RoundedCorner20 i ustawia promień każdego modyfikatora CornerRadius na 20 pikseli.
local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "Frame.RoundedCorner20::UICorner" -- selektor komponentu UI
rule:SetProperty("CornerRadius", UDim.new(0, 20))
-- Utwórz ramkę
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0.4, 0, 0.2, 0)
frame.Parent = screenGui
-- Zastosuj tag do ramki
CollectionService:AddTag(frame, "RoundedCorner20")Zapytania
Roblox zapytania stylów łączą CSS zapytania mediów i zapytania kontenerów. Używając prefiksu @, możesz przełączać style w zależności od wymiarów rodzica, typów urządzeń wejściowych lub ustawień dostępności użytkownika.
W CSS @container stosuje style w zależności od rozmiaru elementu rodzica. W Robloxie definiujesz zapytanie pseudo-instancji używając ::StyleQuery po którym następuje identyfikator dla właściwości Selector warunku, na przykład "::StyleQuery #WideContainer", wraz z nazwą warunku StyleQuery taką jak "MinSize", aby ocenić GuiObject.AbsoluteSize rodzica. Następnie, aby zastosować style do instancji lub jej dzieci, gdy zapytanie jest aktywne, tworzysz StyleRule z prefiksem @[identifier] jako Selector, na przykład @WideContainer.
.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;
}
}<div class="container" style="width: 80%; height: 200px;">
<button>Menu główne</button>
</div>-- Reguła kontenera
local containerRule = Instance.new("StyleRule")
containerRule.Selector = "Frame" -- selektor klasy Roblox
containerRule:SetProperties({
BackgroundColor3 = Color3.fromRGB(0, 0, 34),
BackgroundTransparency = 0.5,
BorderSizePixel = 0
})
containerRule.Parent = coreSheet
-- Reguła przycisku
local buttonRule = Instance.new("StyleRule")
buttonRule.Selector = "TextButton" -- selektor klasy Roblox
buttonRule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.75, 0, 0, 40),
BorderSizePixel = 0
})
buttonRule.Parent = containerRule -- Dziecko reguły kontenera
-- Warunek zapytania (#WideContainer)
local queryCondition = Instance.new("StyleRule")
queryCondition.Selector = "::StyleQuery #WideContainer"
queryCondition:SetProperty("MinSize", Vector2.new(400, 0))
queryCondition.Parent = containerRule -- Dziecko reguły kontenera
-- Reguła, która stosuje się, gdy warunek jest aktywny (@WideContainer)
local queryStyle = Instance.new("StyleRule")
queryStyle.Selector = "@WideContainer Frame > TextButton" -- selektor dziecka
queryStyle:SetProperty("BackgroundColor3", Color3.fromHex("CC0033"))
queryStyle.Parent = containerRule -- Dziecko reguły kontenera
-- Utwórz instancje
local container = Instance.new("Frame")
container.Size = UDim2.new(0.8, 0, 0, 200)
container.Parent = screenGui
local button = Instance.new("TextButton")
button.Text = "Menu główne"
button.Parent = containerRoblox zapewnia również wbudowane zapytania, które odpowiadają globalnym stanom środowiska, takim jak ViewportDisplaySize lub ReducedMotionEnabled. Nie wymagają one definicji ::StyleQuery i mogą być używane bezpośrednio z prefiksem @.
| Cecha mediów CSS | Selektor zapytania stylu 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 |
.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);
}
}<div class="container" style="width: 80%; height: 200px;">
</div>-- Reguła kontenera
local containerRule = Instance.new("StyleRule")
containerRule.Selector = "Frame" -- selektor klasy Roblox
containerRule:SetProperties({
BackgroundColor3 = Color3.fromRGB(0, 0, 34),
BackgroundTransparency = 0.5,
BorderSizePixel = 0
})
containerRule.Parent = coreSheet
-- Wbudowane zapytanie
local motionRule = Instance.new("StyleRule")
motionRule.Selector = "@ReducedMotionEnabledTrue Frame"
motionRule:SetProperty("BackgroundTransparency", 0)
motionRule.Parent = containerRule -- Dziecko reguły kontenera
-- Utwórz instancje
local container = Instance.new("Frame")
container.Size = UDim2.new(0.8, 0, 0, 200)
container.Parent = screenGuiZmienne
CSS pozwala na deklarowanie i odniesienie się do zmiennych w całym systemie stylów. Roblox osiąga to poprzez tokeny i system atrybutów instancji. Używając $ jako prefiksu, możesz odwoływać się do atrybutów zadeklarowanych w łańcuchu dziedziczenia StyleRule lub StyleSheet, gdy ustawiasz właściwości stylu.
:root {
--button-bg-color: #335FFF;
--button-text-color: #E1E1E1;
}
button {
background-color: var(--button-bg-color);
color: var(--button-text-color);
}<button>Menu główne</button>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
-- Ustaw tokeny arkusza stylów za pomocą atrybutów
coreSheet:SetAttribute("ButtonBgColor", Color3.fromHex("335FFF"))
coreSheet:SetAttribute("ButtonTextColor", Color3.fromHex("E1E1E1"))
rule.Selector = "TextButton" -- selektor klasy
rule:SetProperties({
BackgroundColor3 = "$ButtonBgColor",
TextColor3 = "$ButtonTextColor"
})
-- Utwórz przycisk
local button = Instance.new("TextButton")
button.AutomaticSize = Enum.AutomaticSize.XY
button.Text = "Menu główne"
button.Parent = screenGuiPrzejścia
CSS przejścia pozwalają na animowanie wartości właściwości przez określony czas. Możesz to osiągnąć w Robloxie, ustawiając przejścia właściwości w StyleRule za pomocą SetPropertyTransition() (pojedyncze) lub SetPropertyTransitions() (wiele).
button {
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);
}<button>Menu główne</button>-- Reguła przycisku
local buttonRule = Instance.new("StyleRule")
buttonRule.Selector = "TextButton" -- selektor klasy Roblox
buttonRule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.15, 0, 0, 40),
BorderSizePixel = 0
})
-- Ustaw zachowania przejścia właściwości
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
-- Reguła najechania przycisku
local hoverRule = Instance.new("StyleRule")
hoverRule.Selector = "TextButton:Hover" -- selektor stanu
hoverRule:SetProperties({
AutoButtonColor = false,
BackgroundColor3 = Color3.fromHex("33AAFF"),
Rotation = -5
})
hoverRule.Parent = coreSheet
-- Utwórz przycisk tekstowy
local button = Instance.new("TextButton")
button.Text = "Menu główne"
button.Parent = screenGuiZagnieżdżanie i łączenie
Zapożyczając koncepcję z SCSS, StyleRules mogą być zagnieżdżane razem, a ich selektory będą łączyć się.
#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;
}
}
}<div id="menu-frame">
<button>Urok</button>
<button>Mana</button>
<button>Zwój</button>
</div>-- Reguła ramki menu
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
-- Reguła układu menu
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 -- Ustaw regułę ramki menu jako rodzica
-- Reguła przycisku
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 -- Ustaw regułę układu menu jako rodzica
-- Reguła najechania przycisku
local buttonHoverRule = Instance.new("StyleRule")
buttonHoverRule.Selector = ":Hover"
buttonHoverRule:SetProperties({
AutoButtonColor = false,
BackgroundTransparency = 0.5,
TextTransparency = 0.5
})
buttonHoverRule.Parent = buttonRule -- Ustaw regułę przycisku jako rodzica
-- Utwórz ramkę rodzica
local menuFrame = Instance.new("Frame")
menuFrame.Name = "MenuFrame"
menuFrame.Parent = screenGui
-- Utwórz przyciski wewnątrz ramki
local button1 = Instance.new("TextButton")
button1.Text = "Urok"
button1.Parent = menuFrame
local button2 = Instance.new("TextButton")
button2.Text = "Mana"
button2.Parent = menuFrame
local button3 = Instance.new("TextButton")
button3.Text = "Zwój"
button3.Parent = menuFrame