La mayoría de los conceptos de CSS se mapean a los conceptos de estilo de Roblox. Los siguientes ejemplos muestran cómo CSS y HTML se alinean con Luau y las clases/properties de Roblox.
Para probar cada uno de los siguientes ejemplos de script de Luau:
En el Explorer, crea lo siguiente:

- Instancia StyleSheet dentro de ReplicatedStorage.
- Contenedor ScreenGui en StarterGui.
- Instancia LocalScript dentro de ScreenGui.
En LocalScript, pega el siguiente código de soporte:
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 = coreSheetPara cada ejemplo a continuación, pega las líneas de código Luau después de las líneas de soporte 1-7.
Selectores
La propiedad Selector de StyleRule especifica qué instancias debe afectar la regla. Los siguientes tipos de selectores se mapean de CSS a Luau y se pueden utilizar con combinadores.
Elemento
Equivalentes a los selectores de elementos CSS son los selectores de clase de Roblox que seleccionan todas las instancias de una clase dada GuiObject, por ejemplo Frame, ImageLabel, TextButton, etc.
CSSbotón {background-color: #335FFF;color: #E1E1E1;width: 15%;height: 40px;border: none;}
HTML<button>Menú Principal</button>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "TextButton" -- Selector de clase de Robloxrule: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 = "Menú Principal"button.Parent = screenGui
Clase
El equivalente de Roblox a los selectores de clase CSS son los selectores de etiqueta que utilizan etiquetas aplicadas a través de CollectionService.
CSS.boton-primario {background-color: #335FFF;color: #E1E1E1;}
HTML<button class="boton-primario">Menú Principal</button>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = ".ButtonPrimary" -- Selector de etiqueta de Robloxrule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),AutomaticSize = Enum.AutomaticSize.XY})local button = Instance.new("TextButton")button.Text = "Menú Principal"button.Parent = screenGui-- Aplicar etiqueta al botónCollectionService:AddTag(button, "ButtonPrimary")
Identificador
La comparación más cercana de Roblox al id de CSS es el selector #[nombre] que selecciona de acuerdo con el valor de Instance.Name. A diferencia de la especificación W3C del atributo id, no se espera que los nombres sean únicos.
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" -- Selector de nombre de instanciarule: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-- Renombrar marco para que coincida con el selectorframe.Name = "ModalFrame"
Combinadores
Los combinadores te permiten mezclar selectores básicos para coincidir con relaciones jerárquicas más profundas.
Hijo
El selector de hijo > es idéntico entre CSS y Roblox.
CSS.container-del-menu {width: 25%;}.container-del-menu > button {background-color: #335FFF;color: #E1E1E1;width: 80%;height: 40px;border: none;}
HTML<div class="container-del-menu"><button>Opciones</button></div>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = ".MenuContainer > TextButton" -- Selector hijorule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.8, 0, 0, 40),BorderSizePixel = 0})-- Crear contenedor del menúlocal menuContainer = Instance.new("Frame")menuContainer.Size = UDim2.new(0.25, 0, 0, 0)menuContainer.AutomaticSize = Enum.AutomaticSize.YmenuContainer.Parent = screenGui-- Aplicar etiquetaCollectionService:AddTag(menuContainer, "MenuContainer")-- Crear botónlocal button = Instance.new("TextButton")button.Text = "Opciones"-- Establecer el contenedor del menú como padre del botónbutton.Parent = menuContainer
Descendiente
A diferencia de la sintaxis de espacio en blanco de CSS, por ejemplo .menu-container button que se observa aquí, Roblox utiliza el combinador >> para indicar una relación de descendencia.
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>Opciones</button></div></div>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = ".MenuContainer >> TextButton" -- Selector de descendienterule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.8, 0, 0, 40),BorderSizePixel = 0})-- Crear contenedor del menúlocal menuContainer = Instance.new("Frame")menuContainer.Size = UDim2.new(0.25, 0, 0, 0)menuContainer.AutomaticSize = Enum.AutomaticSize.YmenuContainer.Parent = screenGui-- Aplicar etiquetaCollectionService:AddTag(menuContainer, "MenuContainer")-- Crear sub-contenedorlocal subContainer = Instance.new("Frame")subContainer.Size = UDim2.new(0.75, 0, 0, 0)subContainer.AutomaticSize = Enum.AutomaticSize.Y-- Establecer el contenedor del menú como padre del sub-contenedorsubContainer.Parent = menuContainer-- Crear botónlocal button = Instance.new("TextButton")button.Text = "Opciones"-- Establecer el sub-contenedor como padre del botónbutton.Parent = subContainer
Lista de selectores
Múltiples selectores (incluyendo selectores con combinadores) se pueden declarar con el mismo bloque de propiedades, separados por comas, para reducir redundancia.
CSSimg, p {background-color: #FF0033;}
HTML<img src="gear.png" width="100" height="100"><p>Menú Principal</p>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "ImageLabel, TextLabel" -- Selector para etiquetas de imagen Y etiquetas de textorule:SetProperty("BackgroundColor3", Color3.fromHex("ff0033"))-- Crear etiqueta de imagenlocal imageLabel = Instance.new("ImageLabel")imageLabel.Image = "rbxassetid://104919049969988"imageLabel.Size = UDim2.new(0, 100, 0, 100)imageLabel.Parent = screenGui-- Crear etiqueta de textolocal 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 = "Menú Principal"textLabel.Parent = screenGui
Pseudo-clases
El equivalente de Roblox a los selectores pseudo-clase de CSS son los selectores de estado que corresponden a uno de los cuatro valores de Enum.GuiState, como Hover o Press.
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" -- Selector de estadorule:SetProperty("ImageTransparency", 0.5)-- Crear etiqueta de imagenlocal imageLabel = Instance.new("ImageLabel")imageLabel.Image = "rbxassetid://104919049969988"imageLabel.Size = UDim2.new(0, 100, 0, 100)imageLabel.BackgroundTransparency = 1imageLabel.Parent = screenGui
Pseudo-instancias
De manera similar a cómo los pseudo-elementos de CSS pueden modificar partes específicas de un elemento, Roblox puede crear "fantasmas" UIComponents a través de la propiedad Selector de una regla de estilo. Por ejemplo, la siguiente regla crea efectivamente un modificador UICorner bajo cada Frame etiquetado con RoundedCorner20 y establece el CornerRadius de cada modificador a 20 píxeles.
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheetrule.Selector = "Frame.RoundedCorner20::UICorner" -- Selector de componente de UIrule:SetProperty("CornerRadius", UDim.new(0, 20))-- Crear marcolocal frame = Instance.new("Frame")frame.Size = UDim2.new(0.4, 0, 0.2, 0)frame.Parent = screenGui-- Aplicar etiqueta al marcoCollectionService:AddTag(frame, "RoundedCorner20")
Consultas
Las consultas de estilo de Roblox conectan la brecha entre las consultas de medios CSS y las consultas de contenedor. Usando el prefijo @, puedes alternar estilos basados en dimensiones de padre, tipos de dispositivos de entrada, o configuraciones de accesibilidad del usuario.
En CSS, @container aplica estilos basados en el tamaño de un elemento padre. En Roblox, defines una consulta pseudo‑instancia usando ::StyleQuery seguido de un identificador para la propiedad Selector de la condición, por ejemplo "::StyleQuery #WideContainer", junto con un nombre de condición de StyleQuery como "MinSize" para evaluar el GuiObject.AbsoluteSize del padre. Luego, para aplicar estilos a la instancia o a sus hijos cuando la consulta está activa, crea un StyleRule con el prefijo @[identifier] como su Selector, por ejemplo @WideContainer.
CSS.container {container-type: inline-size;background-color: rgba(0, 0, 34, 0.5);}botón {background-color: #335FFF;color: #E1E1E1;width: 75%;height: 40px;border: none;}@container (min-width: 400px) {botón {background-color: #cc0033;}}
HTML<div class="container" style="width: 80%; height: 200px;"><button>Menú Principal</button></div>
Luau-- Regla de contenedorlocal containerRule = Instance.new("StyleRule")containerRule.Selector = "Frame" -- Selector de clase de RobloxcontainerRule:SetProperties({BackgroundColor3 = Color3.fromRGB(0, 0, 34),BackgroundTransparency = 0.5,BorderSizePixel = 0})containerRule.Parent = coreSheet-- Regla de botónlocal buttonRule = Instance.new("StyleRule")buttonRule.Selector = "TextButton" -- Selector de clase de RobloxbuttonRule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.75, 0, 0, 40),BorderSizePixel = 0})buttonRule.Parent = containerRule -- Hijo de la regla del contenedor-- Condición de consulta (#WideContainer)local queryCondition = Instance.new("StyleRule")queryCondition.Selector = "::StyleQuery #WideContainer"queryCondition:SetProperty("MinSize", Vector2.new(400, 0))queryCondition.Parent = containerRule -- Hijo de la regla del contenedor-- Regla que se aplica cuando la condición está activa (@WideContainer)local queryStyle = Instance.new("StyleRule")queryStyle.Selector = "@WideContainer Frame > TextButton" -- Selector hijoqueryStyle:SetProperty("BackgroundColor3", Color3.fromHex("CC0033"))queryStyle.Parent = containerRule -- Hijo de la regla del contenedor-- Crear instanciaslocal container = Instance.new("Frame")container.Size = UDim2.new(0.8, 0, 0, 200)container.Parent = screenGuilocal button = Instance.new("TextButton")button.Text = "Menú Principal"button.Parent = container
Roblox también proporciona consultas integradas que se mapean directamente a estados globales del entorno como ViewportDisplaySize o ReducedMotionEnabled. Estas no requieren una definición de ::StyleQuery y se pueden usar directamente con un prefijo @.
| Característica de Medios CSS | Selector de Consulta de Estilo 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-- Regla de contenedorlocal containerRule = Instance.new("StyleRule")containerRule.Selector = "Frame" -- Selector de clase de RobloxcontainerRule:SetProperties({BackgroundColor3 = Color3.fromRGB(0, 0, 34),BackgroundTransparency = 0.5,BorderSizePixel = 0})containerRule.Parent = coreSheet-- Consulta integradalocal motionRule = Instance.new("StyleRule")motionRule.Selector = "@ReducedMotionEnabledTrue Frame"motionRule:SetProperty("BackgroundTransparency", 0)motionRule.Parent = containerRule -- Hijo de la regla del contenedor-- Crear instanciaslocal container = Instance.new("Frame")container.Size = UDim2.new(0.8, 0, 0, 200)container.Parent = screenGui
Variables
CSS te permite declarar y hacer referencia a variables en todo un sistema de estilos. Roblox logra esto a través de tokens y el sistema de atributos de instancia. Usando $ como prefijo, puedes hacer referencia a atributos declarados en una cadena de herencia de StyleRule o StyleSheet al establecer propiedades de estilo.
CSS:root {--button-bg-color: #335FFF;--button-text-color: #E1E1E1;}botón {background-color: var(--button-bg-color);color: var(--button-text-color);}
HTML<button>Menú Principal</button>
Luaulocal rule = Instance.new("StyleRule")rule.Parent = coreSheet-- Establecer tokens de hoja de estilo utilizando atributoscoreSheet:SetAttribute("ButtonBgColor", Color3.fromHex("335FFF"))coreSheet:SetAttribute("ButtonTextColor", Color3.fromHex("E1E1E1"))rule.Selector = "TextButton" -- Selector de claserule:SetProperties({BackgroundColor3 = "$ButtonBgColor",TextColor3 = "$ButtonTextColor"})-- Crear botónlocal button = Instance.new("TextButton")button.AutomaticSize = Enum.AutomaticSize.XYbutton.Text = "Menú Principal"button.Parent = screenGui
Transiciones
Las transiciones de CSS te permiten interpolar valores de propiedad durante un tiempo determinado. Puedes lograr esto en Roblox estableciendo transiciones de propiedad en una StyleRule a través de SetPropertyTransition() (único) o SetPropertyTransitions() (múltiples).
CSSbotón {background-color: #335FFF;color: #E1E1E1;width: 15%;height: 40px;border: none;transition:background-color 1s ease-out,transform 1.25s ease-out}botón:hover {background-color: #33AAFF;transform: rotate(-5deg);}
HTML<button>Menú Principal</button>
Luau-- Regla del botónlocal buttonRule = Instance.new("StyleRule")buttonRule.Selector = "TextButton" -- Selector de clase de RobloxbuttonRule:SetProperties({BackgroundColor3 = Color3.fromHex("335FFF"),TextColor3 = Color3.fromHex("E1E1E1"),Size = UDim2.new(0.15, 0, 0, 40),BorderSizePixel = 0})-- Establecer comportamientos de transición de propiedadesbuttonRule: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-- Regla para el hover del botónlocal hoverRule = Instance.new("StyleRule")hoverRule.Selector = "TextButton:Hover" -- Selector de estadohoverRule:SetProperties({AutoButtonColor = false,BackgroundColor3 = Color3.fromHex("33AAFF"),Rotation = -5})hoverRule.Parent = coreSheet-- Crear botón de textolocal button = Instance.new("TextButton")button.Text = "Menú Principal"button.Parent = screenGui
Anidación y fusión
Tomando un concepto de SCSS, StyleRules se pueden anidar y sus selectores se fusionarán.
SCSS#menu-frame {background-color: #000022;width: 25%;min-height: 200px;display: flex;flex-direction: column;justify-content: space-evenly;align-items: center;> botón {background-color: #335FFF;color: #E1E1E1;width: 80%;height: 40px;border: none;&:hover {opacity: 0.5;}}}
HTML<div id="menu-frame"><button>Encantos</button><button>Maná</button><button>Rollos</button></div>
Luau-- Regla del marco de menú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-- Regla del diseño del menú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 -- Establecer la regla del marco de menú como padre-- Regla del botónlocal 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 -- Establecer la regla del marco de menú como padre-- Regla de hover del botónlocal buttonHoverRule = Instance.new("StyleRule")buttonHoverRule.Selector = ":Hover"buttonHoverRule:SetProperties({AutoButtonColor = false,BackgroundTransparency = 0.5,TextTransparency = 0.5})buttonHoverRule.Parent = buttonRule -- Establecer la regla del botón como padre-- Crear marco padrelocal menuFrame = Instance.new("Frame")menuFrame.Name = "MenuFrame"menuFrame.Parent = screenGui-- Crear botones dentro del marcolocal button1 = Instance.new("TextButton")button1.Text = "Encantos"button1.Parent = menuFramelocal button2 = Instance.new("TextButton")button2.Text = "Maná"button2.Parent = menuFramelocal button3 = Instance.new("TextButton")button3.Text = "Rollos"button3.Parent = menuFrame