La plupart des concepts CSS se traduisent par des concepts de style Roblox. Les exemples suivants montrent comment CSS et HTML s'alignent avec Luau et les classes/propriétés 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 après les lignes de support 1–7.
Sélecteurs
La propriété Selector d'une StyleRule spécifie quelles instances la règle doit affecter. Les types de sélecteurs suivants se traduisent de CSS à Luau et peuvent être utilisés avec des combinateurs.
Élément
L'équivalent des sélecteurs d'éléments CSS sont les sélecteurs de classe Roblox qui sélectionnent toutes les instances d'une classe GuiObject donnée, par exemple Frame, ImageLabel, TextButton, etc.
bouton {
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 Roblox des sélecteurs class CSS sont les sélecteurs de balise qui utilisent des balises appliquées via CollectionService.
.bouton-primaire {
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 de balise 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 la balise au bouton
CollectionService:AddTag(button, "ButtonPrimary")Identifiant
La comparaison la plus proche de Roblox avec le id CSS est le sélecteur #[name] qui sélectionne selon 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"Combinators
Les combinators 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 le 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 la balise
CollectionService:AddTag(menuContainer, "MenuContainer")
-- Créer le 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 descendant.
.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 le 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 la balise
CollectionService:AddTag(menuContainer, "MenuContainer")
-- Créer le 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 le bouton
local button = Instance.new("TextButton")
button.Text = "Options"
-- Définir le sous-conteneur comme parent du bouton
button.Parent = subContainerListe de sélecteurs
Plusieurs sélecteurs (y compris les sélecteurs avec des combinators) 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 l'é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 l'é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 des sélecteurs 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 l'é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 via 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é avec 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 le cadre
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0.4, 0, 0.2, 0)
frame.Parent = screenGui
-- Appliquer la balise au cadre
CollectionService:AddTag(frame, "RoundedCorner20")Requêtes
Les requêtes de style Roblox comblent le fossé entre les requêtes média CSS et les requêtes de conteneur. En utilisant le préfixe @, vous pouvez basculer les styles en fonction des dimensions des parents, des types de dispositifs d'entrée ou des paramètres d'accessibilité de l'utilisateur.
En 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 suivi d'un identifiant pour la propriété Selector de la condition, par exemple "::StyleQuery #WideContainer", accompagnée d'un nom de condition StyleQuery comme "MinSize" pour évaluer la 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] comme 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 se traduisent directement par des états d'environnement 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é 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
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 tokens 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 tokens de la feuille de style en utilisant 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 le 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 des propriétés sur une durée définie. Vous pouvez réaliser cela dans Roblox en définissant des transitions de propriété sur une StyleRule via SetPropertyTransition() (unique) ou SetPropertyTransitions() (multiple).
bouton {
background-color: #335FFF;
color: #E1E1E1;
width: 15%;
height: 40px;
border: none;
transition:
background-color 1s ease-out,
transform 1.25s ease-out
}
bouton: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 le 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 de 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 de 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 la règle de cadre de menu comme parent
-- Règle de 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 la règle de mise en page de menu comme parent
-- Règle de survol de bouton
local buttonHoverRule = Instance.new("StyleRule")
buttonHoverRule.Selector = ":Hover"
buttonHoverRule:SetProperties({
AutoButtonColor = false,
BackgroundTransparency = 0.5,
TextTransparency = 0.5
})
buttonHoverRule.Parent = buttonRule -- Définir la règle de bouton comme parent
-- 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