La plupart des concepts CSS correspondent aux concepts de style de Roblox. Les exemples suivants montrent comment le CSS et le HTML s’alignent avec Luau et les classes/propriétés de Roblox.
Pour tester chacun des exemples de script Luau suivants :
Dans l'Explorateur, créez ce qui suit :

- Instance StyleSheet à l'intérieur de ReplicatedStorage.
- Conteneur ScreenGui dans StarterGui.
- Instance LocalScript à l'intérieur de ScreenGui.
Dans le LocalScript, collez le code de support suivant :
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 = coreSheetPour chaque exemple ci-dessous, collez les lignes de code Luau suivant les lignes de support 1–7.
Sélecteurs
La propriété Selector d'un StyleRule spécifie quelles instances la règle doit affecter. Les types de sélecteurs suivants mappent du CSS au Luau et peuvent être utilisés avec des combinateurs.
Élément
L'équivalent des sélecteurs d'élément CSS sont les sélecteurs de classe de Roblox qui sélectionnent toutes les instances d'une classe GuiObject donnée, par exemple Frame, ImageLabel, TextButton, etc.
buton {
background-color: #335FFF;
color: #E1E1E1;
width: 15%;
height: 40px;
border: none;
}<button>Menu Principal</button>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "TextButton" -- Sélecteur de classe 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 Principal"
button.Parent = screenGuiClasse
L'équivalent de Roblox aux sélecteurs de classe CSS sont les sélecteurs d'étiquette qui utilisent des étiquettes appliquées par CollectionService.
.button-primary {
background-color: #335FFF;
color: #E1E1E1;
}<button class="button-primary">Menu Principal</button>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = ".ButtonPrimary" -- Sélecteur d'étiquette Roblox
rule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
AutomaticSize = Enum.AutomaticSize.XY
})
local button = Instance.new("TextButton")
button.Text = "Menu Principal"
button.Parent = screenGui
-- Appliquer l'étiquette au bouton
CollectionService:AddTag(button, "ButtonPrimary")Identifiant
La comparaison Roblox la plus proche du CSS id est le sélecteur #[name] qui sélectionne en fonction de la valeur de Instance.Name. Contrairement à la spécification W3C de l'attribut id, les noms ne sont pas censés être uniques.
#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" -- Sélecteur de nom d'instance
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
-- Renommer le cadre pour correspondre au sélecteur
frame.Name = "ModalFrame"Combinateurs
Les combinateurs vous permettent de mélanger des sélecteurs de base pour correspondre à des relations hiérarchiques plus profondes.
Enfant
Le sélecteur enfant de > est identique entre CSS et Roblox.
.menu-container {
width: 25%;
}
.menu-container > button {
background-color: #335FFF;
color: #E1E1E1;
width: 80%;
height: 40px;
border: none;
}<div class="menu-container">
<button>Options</button>
</div>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = ".MenuContainer > TextButton" -- Sélecteur enfant
rule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.8, 0, 0, 40),
BorderSizePixel = 0
})
-- Créer un conteneur de menu
local menuContainer = Instance.new("Frame")
menuContainer.Size = UDim2.new(0.25, 0, 0, 0)
menuContainer.AutomaticSize = Enum.AutomaticSize.Y
menuContainer.Parent = screenGui
-- Appliquer l'étiquette
CollectionService:AddTag(menuContainer, "MenuContainer")
-- Créer un bouton
local button = Instance.new("TextButton")
button.Text = "Options"
-- Définir le conteneur de menu comme parent du bouton
button.Parent = menuContainerDescendant
Contrairement à la syntaxe d'espace CSS, par exemple .menu-container button vue ici, Roblox utilise le combinator >> pour indiquer une relation de descendance.
.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>Options</button>
</div>
</div>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = ".MenuContainer >> TextButton" -- Sélecteur descendant
rule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.8, 0, 0, 40),
BorderSizePixel = 0
})
-- Créer un conteneur de menu
local menuContainer = Instance.new("Frame")
menuContainer.Size = UDim2.new(0.25, 0, 0, 0)
menuContainer.AutomaticSize = Enum.AutomaticSize.Y
menuContainer.Parent = screenGui
-- Appliquer l'étiquette
CollectionService:AddTag(menuContainer, "MenuContainer")
-- Créer un sous-conteneur
local subContainer = Instance.new("Frame")
subContainer.Size = UDim2.new(0.75, 0, 0, 0)
subContainer.AutomaticSize = Enum.AutomaticSize.Y
-- Définir le conteneur de menu comme parent du sous-conteneur
subContainer.Parent = menuContainer
-- Créer un bouton
local button = Instance.new("TextButton")
button.Text = "Options"
-- Définir le sous-conteneur comme parent du bouton
button.Parent = subContainerListe des sélecteurs
Plusieurs sélecteurs (y compris les sélecteurs avec des combinateurs) peuvent être déclarés avec le même bloc de propriétés, séparés par des virgules, pour réduire la redondance.
img, p {
background-color: #FF0033;
}<img src="gear.png" width="100" height="100">
<p>Menu Principal</p>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "ImageLabel, TextLabel" -- Sélecteur pour les étiquettes d'image ET les étiquettes de texte
rule:SetProperty("BackgroundColor3", Color3.fromHex("ff0033"))
-- Créer une étiquette d'image
local imageLabel = Instance.new("ImageLabel")
imageLabel.Image = "rbxassetid://104919049969988"
imageLabel.Size = UDim2.new(0, 100, 0, 100)
imageLabel.Parent = screenGui
-- Créer une étiquette de texte
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 Principal"
textLabel.Parent = screenGuiPseudo-classes
L'équivalent Roblox aux sélecteurs de pseudo-classes CSS sont les sélecteurs d'état qui correspondent à l'une des quatre valeurs Enum.GuiState telles que Hover ou 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" -- Sélecteur d'état
rule:SetProperty("ImageTransparency", 0.5)
-- Créer une étiquette d'image
local imageLabel = Instance.new("ImageLabel")
imageLabel.Image = "rbxassetid://104919049969988"
imageLabel.Size = UDim2.new(0, 100, 0, 100)
imageLabel.BackgroundTransparency = 1
imageLabel.Parent = screenGuiPseudo-instances
De la même manière que les pseudo-éléments CSS peuvent modifier des parties spécifiques d'un élément, Roblox peut créer des UIComponents fantômes par le biais de la propriété Selector d'une règle de style. Par exemple, la règle suivante crée effectivement un modificateur UICorner sous chaque Frame étiqueté RoundedCorner20 et définit le CornerRadius de chaque modificateur à 20 pixels.
local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
rule.Selector = "Frame.RoundedCorner20::UICorner" -- Sélecteur de composant UI
rule:SetProperty("CornerRadius", UDim.new(0, 20))
-- Créer un cadre
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0.4, 0, 0.2, 0)
frame.Parent = screenGui
-- Appliquer l'étiquette au cadre
CollectionService:AddTag(frame, "RoundedCorner20")Requêtes
Les requêtes de style de Roblox comblent le fossé entre les media queries CSS et les container queries. En utilisant le préfixe @, vous pouvez basculer les styles en fonction des dimensions parentales, des types de dispositifs d'entrée ou des paramètres d'accessibilité utilisateur.
Dans le CSS, @container applique des styles en fonction de la taille d'un élément parent. Dans Roblox, vous définissez une requête de pseudo-instance en utilisant ::StyleQuery suivie d'un identifiant pour la propriété Selector de la condition, par exemple "::StyleQuery #WideContainer", accompagné d'un nom de condition de StyleQuery comme "MinSize" pour évaluer le GuiObject.AbsoluteSize du parent. Ensuite, pour appliquer des styles à l'instance ou à ses enfants lorsque la requête est active, créez une StyleRule avec le préfixe @[identifier] en tant que Selector, par exemple @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 Principal</button>
</div>-- Règle de conteneur
local containerRule = Instance.new("StyleRule")
containerRule.Selector = "Frame" -- Sélecteur de classe Roblox
containerRule:SetProperties({
BackgroundColor3 = Color3.fromRGB(0, 0, 34),
BackgroundTransparency = 0.5,
BorderSizePixel = 0
})
containerRule.Parent = coreSheet
-- Règle de bouton
local buttonRule = Instance.new("StyleRule")
buttonRule.Selector = "TextButton" -- Sélecteur de classe Roblox
buttonRule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.75, 0, 0, 40),
BorderSizePixel = 0
})
buttonRule.Parent = containerRule -- Enfant de la règle de conteneur
-- Condition de requête (#WideContainer)
local queryCondition = Instance.new("StyleRule")
queryCondition.Selector = "::StyleQuery #WideContainer"
queryCondition:SetProperty("MinSize", Vector2.new(400, 0))
queryCondition.Parent = containerRule -- Enfant de la règle de conteneur
-- Règle qui s'applique lorsque la condition est active (@WideContainer)
local queryStyle = Instance.new("StyleRule")
queryStyle.Selector = "@WideContainer Frame > TextButton" -- Sélecteur enfant
queryStyle:SetProperty("BackgroundColor3", Color3.fromHex("CC0033"))
queryStyle.Parent = containerRule -- Enfant de la règle de conteneur
-- Créer des instances
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 Principal"
button.Parent = containerRoblox fournit également des requêtes intégrées qui correspondent directement à des états globaux tels que ViewportDisplaySize ou ReducedMotionEnabled. Celles-ci ne nécessitent pas de définition ::StyleQuery et peuvent être utilisées directement avec un préfixe @.
| Fonctionnalité de média CSS | Sélecteur de requête de style 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>-- Règle de conteneur
local containerRule = Instance.new("StyleRule")
containerRule.Selector = "Frame" -- Sélecteur de classe Roblox
containerRule:SetProperties({
BackgroundColor3 = Color3.fromRGB(0, 0, 34),
BackgroundTransparency = 0.5,
BorderSizePixel = 0
})
containerRule.Parent = coreSheet
-- Requête intégrée
local motionRule = Instance.new("StyleRule")
motionRule.Selector = "@ReducedMotionEnabledTrue Frame"
motionRule:SetProperty("BackgroundTransparency", 0)
motionRule.Parent = containerRule -- Enfant de la règle de conteneur
-- Créer des instances
local container = Instance.new("Frame")
container.Size = UDim2.new(0.8, 0, 0, 200)
container.Parent = screenGuiVariables
Le CSS vous permet de déclarer et de référencer des variables dans tout un système de style. Roblox y parvient grâce aux jetons et au système d'attributs d'instance. En utilisant $ comme préfixe, vous pouvez référencer des attributs déclarés dans une chaîne d'héritage StyleRule ou StyleSheet lors de la définition des propriétés de style.
:root {
--button-bg-color: #335FFF;
--button-text-color: #E1E1E1;
}
button {
background-color: var(--button-bg-color);
color: var(--button-text-color);
}<button>Menu Principal</button>local rule = Instance.new("StyleRule")
rule.Parent = coreSheet
-- Définir les jetons de la feuille de style à l'aide des attributs
coreSheet:SetAttribute("ButtonBgColor", Color3.fromHex("335FFF"))
coreSheet:SetAttribute("ButtonTextColor", Color3.fromHex("E1E1E1"))
rule.Selector = "TextButton" -- Sélecteur de classe
rule:SetProperties({
BackgroundColor3 = "$ButtonBgColor",
TextColor3 = "$ButtonTextColor"
})
-- Créer un bouton
local button = Instance.new("TextButton")
button.AutomaticSize = Enum.AutomaticSize.XY
button.Text = "Menu Principal"
button.Parent = screenGuiTransitions
Les transitions CSS vous permettent d'animer les valeurs de propriétés sur une durée déterminée. Vous pouvez réaliser cela dans Roblox en définissant des transitions de propriété sur une StyleRule via SetPropertyTransition() (unique) ou SetPropertyTransitions() (multiple).
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 Principal</button>-- Règle de bouton
local buttonRule = Instance.new("StyleRule")
buttonRule.Selector = "TextButton" -- Sélecteur de classe Roblox
buttonRule:SetProperties({
BackgroundColor3 = Color3.fromHex("335FFF"),
TextColor3 = Color3.fromHex("E1E1E1"),
Size = UDim2.new(0.15, 0, 0, 40),
BorderSizePixel = 0
})
-- Définir les comportements de transition de propriété
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
-- Règle de survol de bouton
local hoverRule = Instance.new("StyleRule")
hoverRule.Selector = "TextButton:Hover" -- Sélecteur d'état
hoverRule:SetProperties({
AutoButtonColor = false,
BackgroundColor3 = Color3.fromHex("33AAFF"),
Rotation = -5
})
hoverRule.Parent = coreSheet
-- Créer un bouton de texte
local button = Instance.new("TextButton")
button.Text = "Menu Principal"
button.Parent = screenGuiImbrication et fusion
Empruntant un concept de SCSS, les StyleRules peuvent être imbriquées ensemble et leurs sélecteurs fusionneront.
#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>Charms</button>
<button>Mana</button>
<button>Scrolls</button>
</div>-- Règle du cadre de 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
-- Règle de mise en page du 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 -- Définir comme parent de la règle du cadre de menu
-- Règle du bouton
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 -- Définir comme parent de la règle de mise en page du menu
-- Règle de survol du bouton
local buttonHoverRule = Instance.new("StyleRule")
buttonHoverRule.Selector = ":Hover"
buttonHoverRule:SetProperties({
AutoButtonColor = false,
BackgroundTransparency = 0.5,
TextTransparency = 0.5
})
buttonHoverRule.Parent = buttonRule -- Définir comme parent de la règle du bouton
-- Créer le cadre parent
local menuFrame = Instance.new("Frame")
menuFrame.Name = "MenuFrame"
menuFrame.Parent = screenGui
-- Créer des boutons à l'intérieur du cadre
local button1 = Instance.new("TextButton")
button1.Text = "Charms"
button1.Parent = menuFrame
local button2 = Instance.new("TextButton")
button2.Text = "Mana"
button2.Parent = menuFrame
local button3 = Instance.new("TextButton")
button3.Text = "Scrolls"
button3.Parent = menuFrame