sketch

Table of Contents


Internals

Sketch tries to be to CSS what the VDOM is to the DOM: the ultimate pain-free tool to manage the state of your CSS styles, without having to worry with CSS while leveraging CSS skills.

I don’t know anything about Sketch!

This documentation focuses on internal and how is working Sketch under-the-hood. No worry though, just heads up to the README to get an overview of Sketch, and to get it work with your favorite framework!

Lifecycle

To do this, Sketch tries to maintain a cache of styles, that can be updated between every render of the DOM, and will update the correct StyleSheet in DOM. Sketch has a lifecycle to make it work. After having created a Cache, you have to call prepare before every repaint, and render after every repaint.

                            +--------------+
                            | Create Cache |
                            +--------------+
                                   |
                                   |
                                   |
                                   v
                    +-------------------------------+
                    | Before paint, setup the cache |  <-------+
                    +-------------------------------+          |
                                   |                           |
                                   |                           |
                                   |                           |
                                   v                           |
              +-------------------------------------------+    |
              |                                           |    |
              |      framework paints to the DOM          |    |
              |   and calls class and dynamic functions   |    |
              |            provided by sketch             |    |
              |                                           |    |
              +-------------------------------------------+    |
                                   |                           |
                                   |                           |
                                   |                           |
                                   v                           |
                    +-------------------------------+          |
                    | After paint, render the cache |  --------+
                    +-------------------------------+

Some notes on side-effects

Unfortunately, and because of the nature of the different frameworks and of CSS, Sketch is doing some side-effects in background, to collect the styles and to push them in the browser. Maybe it could be removed in the future, but it would involve work with different maintainers of different packages, and it would take a lot of time and energy. It’s not on plan right now, but rather to focus on correct UX and to find good ways of doing things. When the dust will settle and that API will be stable, then we could take some time to figure out how to get rid of side-effects. In the meantime, if you plan to integrate Sketch in your framework, and need some access to underlying and internals, open an issue with your use case, I’d more than happy to help on that point and reduce side-effects.

Types

Manages the styles. Can be instanciated with create_cache.

pub opaque type Cache

Represents a CSS class, compiled.

pub opaque type Class

No direct usage, used for type-checking and to cancel impossible states.

pub opaque type Media

No direct usage, used for type-checking and to cancel impossible states.

pub opaque type NoMedia

No direct usage, used for type-checking and to cancel impossible states.

pub opaque type NoPseudoSelector

No direct usage, used for type-checking and to cancel impossible states.

pub opaque type PseudoSelector

Represents a Style. It can be a class composition, a media query with its sub-properties, a pseudo-selector with its sub-properties or a property directly. It’s not possible to put a media query in a media query, and a pseudo-selector in a pseudo-selector.

pub opaque type Style(media, pseudo)

Functions

pub fn active(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn align_content(align: String) -> Style(a, b)
pub fn align_items(align: String) -> Style(a, b)
pub fn align_self(align: String) -> Style(a, b)
pub fn align_tracks(align: String) -> Style(a, b)
pub fn animation(animation: String) -> Style(a, b)
pub fn animation_delay(animation: String) -> Style(a, b)
pub fn animation_direction(animation: String) -> Style(a, b)
pub fn animation_duration(animation: String) -> Style(a, b)
pub fn animation_fill_mode(animation: String) -> Style(a, b)
pub fn animation_iteration_count(
  animation: String,
) -> Style(a, b)
pub fn animation_name(animation: String) -> Style(a, b)
pub fn animation_play_state(animation: String) -> Style(a, b)
pub fn animation_timing_function(
  animation: String,
) -> Style(a, b)
pub fn appearance(appearance: String) -> Style(a, b)
pub fn aspect_ratio(aspect_ratio: String) -> Style(a, b)
pub fn background(background: String) -> Style(a, b)
pub fn blank(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn border(border: String) -> Style(a, b)
pub fn border_bottom(border_bottom: String) -> Style(a, b)
pub fn border_bottom_left_radius(
  border_bottom_left_radius: Size,
) -> Style(a, b)
pub fn border_bottom_left_radius_(
  border_bottom_left_radius: String,
) -> Style(a, b)
pub fn border_bottom_right_radius(
  border_bottom_right_radius: Size,
) -> Style(a, b)
pub fn border_bottom_right_radius_(
  border_bottom_right_radius: String,
) -> Style(a, b)
pub fn border_left(border_left: String) -> Style(a, b)
pub fn border_radius(border_radius: Size) -> Style(a, b)
pub fn border_radius_(border_radius: String) -> Style(a, b)
pub fn border_right(border_right: String) -> Style(a, b)
pub fn border_top(border_top: String) -> Style(a, b)
pub fn border_top_left_radius(
  border_top_left_radius: Size,
) -> Style(a, b)
pub fn border_top_left_radius_(
  border_top_left_radius: String,
) -> Style(a, b)
pub fn border_top_right_radius(
  border_top_right_radius: Size,
) -> Style(a, b)
pub fn border_top_right_radius_(
  border_top_right_radius: String,
) -> Style(a, b)
pub fn bottom(size: Size) -> Style(a, b)
pub fn bottom_(size: String) -> Style(a, b)
pub fn box_shadow(box_shadow: String) -> Style(a, b)
pub fn box_sizing(box_sizing: String) -> Style(a, b)
pub fn checked(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn class(styles: List(Style(a, b))) -> Class

Compiles a static class, and memoizes it. Don’t use dynamic styles with it, use dynamic instead.

pub fn color(color: String) -> Style(a, b)
pub fn column_gap(column_gap: Size) -> Style(a, b)
pub fn compose(class: Class) -> Style(a, b)

Compose styles by inheriting class, and later overrides them. Works similarly to composes property in CSS modules.

pub fn create_cache(
  options: Options,
) -> Result(Cache, SketchError)

Create a cache manager, managing the styles for every repaint. You can instanciate as much cache manager that you want, if you want to use multiple render lifecycle. You can output the styles directly in a node style in the DOM, or by pushing them directly in a CSSStyleSheet, at the document level. The choice is up to you at the initialization of the Cache. If you’re using Lustre, you shouldn’t have to worry about it, and consider it as internal low-level.

pub fn cursor(cursor: String) -> Style(a, b)
pub fn direction(direction: String) -> Style(a, b)
pub fn disabled(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn display(display: String) -> Style(a, b)
pub fn dynamic(id: String, styles: List(Style(a, b))) -> Class

Compiles a dynamic class, and not memoizing it. It means at every render, the class will be re-computed, and a new version will be pushed in the browser. Be careful to add a unique ID: right now, it’s not possible to push a dynamic class in the browser without defining an ID. The ID should be unique to the computed class, otherwise you could end up with some classes overlap.

pub fn enabled(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn filter(filter: String) -> Style(a, b)
pub fn first_child(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn first_of_type(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn flex(flex: String) -> Style(a, b)
pub fn flex_basis(flex_basis: String) -> Style(a, b)
pub fn flex_direction(flex_direction: String) -> Style(a, b)
pub fn flex_grow(flex_grow: String) -> Style(a, b)
pub fn focus(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn focus_visible(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn focus_within(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn font_family(font_family: String) -> Style(a, b)
pub fn font_size(font_size: Size) -> Style(a, b)
pub fn font_size_(font_size: String) -> Style(a, b)
pub fn font_style(font_style: String) -> Style(a, b)
pub fn font_weight(font_weight: String) -> Style(a, b)
pub fn gap(gap: Size) -> Style(a, b)
pub fn gap_(gap: String) -> Style(a, b)
pub fn grid_area(grid_area: String) -> Style(a, b)
pub fn grid_auto_columns(
  grid_auto_columns: String,
) -> Style(a, b)
pub fn grid_auto_flow(grid_auto_flow: String) -> Style(a, b)
pub fn grid_auto_rows(grid_auto_rows: String) -> Style(a, b)
pub fn grid_column(grid_column: String) -> Style(a, b)
pub fn grid_row(grid_row: String) -> Style(a, b)
pub fn grid_template(grid_template: String) -> Style(a, b)
pub fn grid_template_areas(
  grid_template_areas: String,
) -> Style(a, b)
pub fn grid_template_columns(
  grid_template_columns: String,
) -> Style(a, b)
pub fn grid_template_rows(
  grid_template_rows: String,
) -> Style(a, b)
pub fn height(height: Size) -> Style(a, b)
pub fn height_(height: String) -> Style(a, b)
pub fn hover(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn important(style: Style(a, b)) -> Style(a, b)

Add an !important flag to any CSS property. It won’t have any effect on non-property style, like media, etc. It will then act as the identity function.

pub fn invalid(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn justify_content(justify: String) -> Style(a, b)
pub fn justify_items(justify: String) -> Style(a, b)
pub fn justify_self(justify: String) -> Style(a, b)
pub fn justify_tracks(justify: String) -> Style(a, b)
pub fn last_child(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn last_of_type(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn left(size: Size) -> Style(a, b)
pub fn left_(size: String) -> Style(a, b)
pub fn letter_spacing(letter_spacing: String) -> Style(a, b)
pub fn line_break(line_break: String) -> Style(a, b)
pub fn line_height(line_height: String) -> Style(a, b)
pub fn link(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn list_style(list_style: String) -> Style(a, b)
pub fn list_style_image(list_style_image: String) -> Style(a, b)
pub fn list_style_position(
  list_style_position: String,
) -> Style(a, b)
pub fn list_style_type(list_style_type: String) -> Style(a, b)
pub fn lustre_setup(
  options: Options,
) -> Result(fn(fn(a) -> b) -> fn(a) -> b, SketchError)

Deprecated: Use sketch/lustre.{setup, compose} instead.

pub fn margin(margin: Size) -> Style(a, b)
pub fn margin_(margin: String) -> Style(a, b)
pub fn margin_bottom(margin: Size) -> Style(a, b)
pub fn margin_left(margin: Size) -> Style(a, b)
pub fn margin_right(margin: Size) -> Style(a, b)
pub fn margin_top(margin: Size) -> Style(a, b)
pub fn max_height(height: Size) -> Style(a, b)
pub fn max_height_(height: String) -> Style(a, b)
pub fn max_width(width: Size) -> Style(a, b)
pub fn max_width_(width: String) -> Style(a, b)
pub fn media(
  query: Query,
  styles: List(Style(NoMedia, PseudoSelector)),
) -> Style(Media, a)
pub fn min_height(height: Size) -> Style(a, b)
pub fn min_height_(height: String) -> Style(a, b)
pub fn min_width(width: Size) -> Style(a, b)
pub fn min_width_(width: String) -> Style(a, b)
pub fn nth_child(
  selector: String,
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn nth_last_child(
  selector: String,
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn nth_last_of_type(
  selector: String,
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn nth_of_type(
  selector: String,
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn object_fit(object_fit: String) -> Style(a, b)
pub fn object_position(object_position: String) -> Style(a, b)
pub fn offset(offset: String) -> Style(a, b)
pub fn offset_anchor(offset_anchor: String) -> Style(a, b)
pub fn offset_distance(offset_distance: String) -> Style(a, b)
pub fn offset_path(offset_path: String) -> Style(a, b)
pub fn offset_position(offset_position: String) -> Style(a, b)
pub fn offset_rotate(offset_rotate: String) -> Style(a, b)
pub fn only_child(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn only_of_type(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn opacity(opacity: Float) -> Style(a, b)
pub fn optional(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn outline(outline: String) -> Style(a, b)
pub fn outline_color(outline_color: String) -> Style(a, b)
pub fn outline_offset(outline_offset: String) -> Style(a, b)
pub fn outline_style(outline_style: String) -> Style(a, b)
pub fn outline_width(outline_width: String) -> Style(a, b)
pub fn overflow(overflow: String) -> Style(a, b)
pub fn overflow_x(overflow_x: String) -> Style(a, b)
pub fn overflow_y(overflow_y: String) -> Style(a, b)
pub fn padding(padding: Size) -> Style(a, b)
pub fn padding_(padding: String) -> Style(a, b)
pub fn padding_bottom(padding: Size) -> Style(a, b)
pub fn padding_left(padding: Size) -> Style(a, b)
pub fn padding_right(padding: Size) -> Style(a, b)
pub fn padding_top(padding: Size) -> Style(a, b)
pub fn place_content(place: String) -> Style(a, b)
pub fn place_items(place: String) -> Style(a, b)
pub fn place_self(place: String) -> Style(a, b)
pub fn placeholder(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn pointer_events(pointer_events: String) -> Style(a, b)
pub fn position(position: String) -> Style(a, b)
pub fn prepare(cache: Cache) -> Nil

Lifecycle function — not side-effect free prepare should be called before your repaint, and before the different calls to class and dynamic functions. This setups the cache to prepare for a new paint, and will allow for diffing the styles. As long as you don’t call prepare, the stylesheet output by sketch will not diff, and you’ll use the stylesheet as append-only. This could be done at will. Be careful, the styles computed by class and dynamic will be pushed in the last cache called by prepare, due to the styles handling (and some side-effects under-the-hood for performance purposes).

pub fn property(field: String, content: String) -> Style(a, b)
pub fn read_only(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn read_write(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn render(cache: Cache) -> Nil

Lifecycle function — not side-effect free render takes a Cache, and render its content to the stylesheet, according to the choice of the Cache. render is idempotent, and can be called as much as you want

pub fn required(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn right(size: Size) -> Style(a, b)
pub fn right_(size: String) -> Style(a, b)
pub fn row_gap(row_gap: Size) -> Style(a, b)
pub fn target(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn text_align(text_align: String) -> Style(a, b)
pub fn text_decoration(text_decoration: String) -> Style(a, b)
pub fn text_justify(text_justify: String) -> Style(a, b)
pub fn text_overflow(text_overflow: String) -> Style(a, b)
pub fn text_transform(text_transform: String) -> Style(a, b)
pub fn to_class_name(class: Class) -> String

Convert a Class to its proper class name, to use it anywhere in your application. It can have the form class1 or class1 class2 in case of classes composition.

pub fn to_lustre(class: Class) -> Attribute(a)

Convert a Class to its equivalent lustre attribute. Use it in your view functions. I.e. html.div([sketch.to_lustre(class())], []).

pub fn top(size: Size) -> Style(a, b)
pub fn top_(size: String) -> Style(a, b)
pub fn transform(transform: String) -> Style(a, b)
pub fn transform_box(transform_box: String) -> Style(a, b)
pub fn transform_origin(transform_origin: String) -> Style(a, b)
pub fn transform_style(transform_style: String) -> Style(a, b)
pub fn transition(transition: String) -> Style(a, b)
pub fn translate(translate: String) -> Style(a, b)
pub fn user_select(user_select: String) -> Style(a, b)
pub fn valid(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn visibility(visibility: String) -> Style(a, b)
pub fn visited(
  styles: List(Style(NoMedia, NoPseudoSelector)),
) -> Style(a, PseudoSelector)
pub fn white_space(white_space: String) -> Style(a, b)
pub fn white_space_collapse(
  white_space_collapse: String,
) -> Style(a, b)
pub fn width(width: Size) -> Style(a, b)
pub fn width_(width: String) -> Style(a, b)
pub fn word_break(word_break: String) -> Style(a, b)
pub fn word_spacing(word_spacing: String) -> Style(a, b)
pub fn word_wrap(word_wrap: String) -> Style(a, b)
pub fn z_index(z_index: Int) -> Style(a, b)
Search Document