Baike.dev
All toolsTrendingOpen sourceNewsSubmit
Log in
< 返回工具列表
C

clay

> 编程语言
开源

High performance UI layout library in C.

17.7K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

High performance UI layout library in C.

Clay, A UI Layout Library

Clay (short for C Layout) is a high performance 2D UI layout library.

Major Features

  • Microsecond layout performance
  • Flex-box like layout model for complex, responsive layouts including text wrapping, scrolling containers and aspect ratio scaling
  • Transition API for easy layout animations
  • Single 4.8k LOC clay.h file with zero dependencies (including no standard library linking)
  • Wasm support: compile with clang to a 15kb uncompressed .wasm file for use in the browser
  • Static arena based memory use with no malloc / free, and low total memory overhead (e.g. ~3.5mb for 8192 layout elements).
  • React-like nested declarative syntax
  • Renderer agnostic: outputs a sorted list of rendering primitives that can be easily composited in any 3D engine, and even compiled to HTML (examples provided)

Take a look at the clay website for an example of clay compiled to wasm and running in the browser, or others in the examples directory.

You can also watch the introduction video for an overview of the motivation behind Clay's development and a short demo of its usage.

An example GUI application built with clay

Quick Start

Download or clone clay.h and include it after defining CLAY_IMPLEMENTATION in one file.

…

The above example, rendered correctly will look something like the following:

In summary, the general order of steps is:

  1. Clay_SetLayoutDimensions(dimensions)
  2. Clay_SetPointerState(pointerPosition, isPointerDown)
  3. Clay_UpdateScrollContainers(enableDragScrolling, scrollDelta, deltaTime)
  4. Clay_BeginLayout()
  5. Declare your layout with the provided Element Macros
  6. Clay_EndLayout()
  7. Render the results using the outputted Clay_RenderCommandArray

For help starting out or to discuss clay, considering joining the discord server.

Summary

  • High Level Documentation
    • Building UI Hierarchies
    • Configuring Layout and Styling UI Elements
    • Element IDs
    • Mouse, Touch and Pointer Interactions
    • Scrolling Elements
    • Floating Elements ("Absolute" Positioning)
    • Laying Out Your Own Custom Elements
    • Transitions
    • Retained Mode Rendering
    • Visibility Culling
    • Preprocessor Directives
    • Bindings for non C
    • Other implementations
    • Debug Tools
    • Running more than one Clay instance
  • API
    • Naming Conventions
    • Public Functions
      • Lifecycle for public functions
      • Clay_MinMemorySize
      • Clay_CreateArenaWithCapacityAndMemory
      • Clay_SetMeasureTextFunction
      • Clay_ResetMeasureTextCache
      • Clay_SetMaxElementCount
      • Clay_SetMaxMeasureTextCacheWordCount
      • Clay_Initialize
      • Clay_SetCurrentContext
      • Clay_GetCurrentContext
      • Clay_SetLayoutDimensions
      • Clay_SetPointerState
      • Clay_UpdateScrollContainers
      • Clay_GetScrollOffset
      • Clay_BeginLayout
      • Clay_EndLayout
      • Clay_Hovered
      • Clay_OnHover
      • Clay_PointerOver
      • Clay_GetOpenElementId
      • Clay_GetScrollContainerData
      • Clay_GetElementData
      • Clay_GetElementId
    • Element Macros
      • CLAY()
      • CLAY_AUTO_ID()
      • CLAY_TEXT()
      • CLAY_ID()
      • CLAY_SID()
      • CLAY_IDI()
      • CLAY_SIDI()
      • CLAY_ID_LOCAL()
      • CLAY_SID_LOCAL()
      • CLAY_IDI_LOCAL()
      • CLAY_SIDI_LOCAL()
    • Data Structures & Definitions
      • Clay_ElementDeclaration
      • Clay_LayoutConfig
      • Clay_ImageElementConfig
      • Clay_AspectRatioElementConfig
      • Clay_ImageElementConfig
      • Clay_ClipElementConfig
      • Clay_BorderElementConfig
      • Clay_FloatingElementConfig
      • Clay_CustomElementConfig
      • Clay_TransitionElementConfig
      • Clay_Color
      • Clay_String
      • Clay_ElementId
      • Clay_RenderCommandArray
      • Clay_RenderCommand
      • Clay_ScrollContainerData
      • Clay_ElementData
      • Clay_PointerData
      • Clay_ErrorHandler
      • Clay_ErrorData

High Level Documentation

Building UI Hierarchies

Clay UIs are built using the C macro CLAY(id, { configuration }). This macro creates a new empty element in the UI hierarchy, and supports modular customisation of layout, styling and functionality. The CLAY() macro can also be nested, similar to other declarative UI systems like HTML.

Child elements are added by opening a block: {} after calling the CLAY() macro (exactly like you would with an if statement or for loop), and declaring child components inside the braces.

// Parent element with 8px of padding
CLAY(CLAY_ID("parent"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
    // Child element 1
    CLAY_TEXT(CLAY_STRING("Hello World"), { .fontSize = 16 });
    // Child element 2 with red background
    CLAY((CLAY_ID("child"), { .backgroundColor = COLOR_RED }) {
        // etc
    }
}

However, unlike HTML and other declarative DSLs, this macro is just C. As a result, you can use arbitrary C code such as loops, functions and conditions inside your layout declaration code:

…

Configuring Layout and Styling UI Elements

The layout and style of clay elements is configured with the Clay_ElementDeclaration struct passed to the CLAY() macro.

CLAY(CLAY_ID("box"), { .layout = { .padding = { 8, 8, 8, 8 }, .layoutDirection = CLAY_TOP_TO_BOTTOM } }) {
    // Children are 8px inset into parent, and laid out top to bottom
}

This macro isn't magic - all it's doing is wrapping the standard designated initializer syntax. e.g. (Clay_ElementDeclaration) { .layout = { .padding = { .left = 8, .right = 8 } ....

See the Clay_ElementDeclaration API for the full list of options.

A Clay_ElementDeclaration struct can be defined in file scope or elsewhere, and reused.

// Define a style in the global / file scope
Clay_ElementDeclaration reuseableStyle = (Clay_ElementDeclaration) {
    .layout = { .padding = { .left = 12 } },
    .backgroundColor = { 120, 120, 120, 255 },
    .cornerRadius = { 12, 12, 12, 12 }
};

CLAY(CLAY_ID("box"), reuseableStyle) {
    // ...
}

Element IDs

The Clay macro by default accepts an ID as its first argument, which is usually provided by the CLAY_ID() convenience macro. Elements can also be created with auto generated IDs, by using the CLAY_AUTO_ID() macro.

// Will always produce the same ID from the same input string
CLAY(CLAY_ID("OuterContainer"), { ...configuration }) {}

// Generates a unique ID that may not be the same between two layout calls
CLAY_AUTO_ID({ ...configuration }) {}

Element IDs have two main use cases. Firstly, tagging an element with an ID allows you to query information about the element later, such as its mouseover state or dimensions.

Secondly, IDs are visually useful when attempting to read and modify UI code, as well as when using the built-in debug tools.

To avoid having to construct dynamic strings at runtime to differentiate ids in loops, clay provides the CLAY_IDI(string, index) macro to generate different ids from a single input string. Think of IDI as "ID + Index"

// This is the equivalent of calling CLAY_ID("Item0"), CLAY_ID("Item1") etc
for (int index = 0; index < items.length; index++) {
    CLAY(CLAY_IDI("Item", index), { ..configuration }) {}
}

This ID will be forwarded to the final Clay_RenderCommandArray for use in retained mode UIs. Using duplicate IDs may cause some functionality to misbehave (i.e. if you're trying to attach a floating container to a specific element with ID that is duplicated, it may not attach to the one you expect)

Mouse, Touch and Pointer Interactions

Clay provides several functions for handling mouse and pointer interactions.

All pointer interactions depend on the function void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) being called after each mouse position update and before any other clay functions.

During UI declaration

The function bool Clay_Hovered() can be called during element construction or in the body of an element, and returns true if the mouse / pointer is over the currently open element.

// An orange button that turns blue when hovered
CLAY(CLAY_ID("Button"), { .backgroundColor = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }) {
    bool buttonHovered = Clay_Hovered();
    CLAY_TEXT(buttonHovered ? CLAY_STRING("Hovered") : CLAY_STRING("Hover me!"), headerTextConfig);
}

The function void Clay_OnHover() allows you to attach a function pointer to the currently open element, which will be called if the mouse / pointer is over the element.

…

Before / After UI declaration

If you want to query mouse / pointer overlaps outside layout declarations, you can use the function bool Clay_PointerOver(Clay_ElementId id), which takes an element id and returns a bool representing whether the current pointer position is within its bounding box.

// Reminder: Clay_SetPointerState must be called before functions that rely on pointer position otherwise it will have no effect
Clay_Vector2 mousePosition = { x, y };
Clay_SetPointerState(mousePosition, mouseButtonDown(0));
// ...
// If profile picture was clicked
if (mouseButtonDown(0) && Clay_PointerOver(Clay_GetElementId("ProfilePicture"))) {
    // Handle profile picture clicked
}

Note that the bounding box queried by Clay_PointerOver is from the last frame. This generally shouldn't make a difference except in the case of animations that move at high speed. If this is an issue for you, performing layout twice per frame with the same data will give you the correct interaction the second time.

Scrolling Elements

Elements are configured as scrollable with the .clip configuration. Clipping instructs the renderer to not draw any pixels outside the clipped ele

核心特点

  • •Microsecond layout performance
  • •Flex-box like layout model for complex, responsive layouts including text wrapping, scrolling containers and aspect ratio scaling
  • •Transition API for easy layout animations
  • •Single 4.8k LOC clay.h file with zero dependencies (including no standard library linking)
  • •Wasm support: compile with clang to a 15kb uncompressed .wasm file for use in the browser
  • •Static arena based memory use with no malloc / free, and low total memory overhead (e.g. ~3.5mb for 8192 layout elements).
  • •React-like nested declarative syntax
  • •Renderer agnostic: outputs a sorted list of rendering primitives that can be easily composited in any 3D engine, and even compiled to HTML (examples provided)
  • •High Level Documentation
  • •Building UI Hierarchies

> 标签

Clayoutui

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月9日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言
Baike.dev

baike.dev helps you discover great languages, frameworks, databases, DevOps and cloud-native tools.

Quick links

  • Home
  • All tools
  • Trending
  • Open source

About

  • About us
  • Community
  • News

Contribute

Found a great developer tool? Share it with the community.

Submit a tool
© 2026 baike.dev Developer EncyclopediaUpdated daily · Discover great developer tools