The full CSS toolkit surface, on the {:ok, :function_name, result} calling
convention shared with igniter_js.
Every function accepts either CSS content or a file path, selected by the
trailing type argument (:content, the default, or :path).
The mutating functions are diff-minimal: they patch byte ranges rather
than reprinting the stylesheet, so comments and formatting outside the edit
are preserved exactly. minify/2 and beautify/2 are the exception — they
rewrite the whole file, because that is what they are for. Do not point them
at a file a user maintains.
For new code prefer IgniterCss, which has a plainer {:ok, result} shape
and clearer option handling.
Summary
Functions
Add display: none to .hide-scrollbar, creating the class if it is absent.
Add an @import unless an equivalent one is already present.
Add vendor-prefixed copies of property_name beside every occurrence of it.
Statistics about a stylesheet, as a string-keyed map.
Pretty-print a stylesheet, keeping every comment. Rewrites the whole file.
Animations keyed by name, each holding "keyframes" and "used_by".
Colour-carrying declarations, keyed by selector.
Media queries keyed by condition, each holding a list of
%{"selector" => ..., "properties" => %{...}}.
Every top-level at-rule named name, as string-keyed maps.
The declarations of a selector as a %{property => value} map, or nil when
the selector is absent.
Concatenate stylesheets, dropping rules a later identical copy makes redundant.
Minify a stylesheet. Rewrites the whole file and drops comments by design.
Set a property value on a selector.
Remove declarations and rules that a later one makes redundant.
Remove @import rules pointing at import_url.
Remove a top-level selector and everything it owns.
Replace a rule's declarations wholesale.
Does a top-level rule with this selector exist?
Sort declarations alphabetically within each block, by moving whole lines.
Is this CSS understood well enough to patch?
Types
Functions
@spec add_hide_scrollbar_property(String.t(), type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Add display: none to .hide-scrollbar, creating the class if it is absent.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.add_hide_scrollbar_property("")
iex> css
".hide-scrollbar {\n display: none;\n}\n"
@spec add_import(String.t(), String.t(), String.t() | boolean() | nil, type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Add an @import unless an equivalent one is already present.
media_query may be a media query string, or false/nil for none.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.add_import("", "styles.css", false)
iex> css
~s|@import "styles.css";\n|
@spec add_vendor_prefixes(String.t(), String.t(), [String.t()], type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Add vendor-prefixed copies of property_name beside every occurrence of it.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.add_vendor_prefixes(
...> ".a { user-select: none; }", "user-select", ["-webkit-"])
iex> css
".a { -webkit-user-select: none; user-select: none; }"
Statistics about a stylesheet, as a string-keyed map.
Examples
iex> {:ok, _, stats} = IgniterCss.Parsers.Parser.analyze_css(".a { color: red; }")
iex> {stats["rules_count"], stats["declarations_count"]}
{1, 1}
Pretty-print a stylesheet, keeping every comment. Rewrites the whole file.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.beautify(".a{color:red}")
iex> css
".a {\n color: red;\n}\n"
Animations keyed by name, each holding "keyframes" and "used_by".
Examples
iex> css = "@keyframes fade {\n from { opacity: 0; }\n}\n.a { animation: fade 1s; }\n"
iex> {:ok, _, animations} = IgniterCss.Parsers.Parser.extract_animations(css)
iex> animations["fade"]["used_by"]
[".a"]
Colour-carrying declarations, keyed by selector.
Examples
iex> {:ok, _, colors} = IgniterCss.Parsers.Parser.extract_colors(".a { color: #333; }")
iex> colors
%{".a" => ["color: #333"]}
@spec extract_media_queries(String.t(), type()) :: {:ok, atom(), map()} | {:error, atom(), String.t()}
Media queries keyed by condition, each holding a list of
%{"selector" => ..., "properties" => %{...}}.
Examples
iex> css = "@media print {\n .a { display: none; }\n}\n"
iex> {:ok, _, queries} = IgniterCss.Parsers.Parser.extract_media_queries(css)
iex> queries
%{"print" => [%{"selector" => ".a", "properties" => %{"display" => "none"}}]}
@spec get_at_rules(String.t(), String.t(), String.t() | nil, type()) :: {:ok, atom(), [map()]} | {:error, atom(), String.t()}
Every top-level at-rule named name, as string-keyed maps.
Examples
iex> css = ~s|@plugin "daisyui" { prefix: "d-"; }|
iex> {:ok, _, [rule]} = IgniterCss.Parsers.Parser.get_at_rules(css, "plugin", "daisyui")
iex> rule["declarations"]
[{"prefix", ~s|"d-"|}]
@spec get_selector_properties(String.t(), String.t(), type()) :: {:ok, atom(), map() | nil} | {:error, atom(), String.t()}
The declarations of a selector as a %{property => value} map, or nil when
the selector is absent.
Examples
iex> {:ok, _, props} = IgniterCss.Parsers.Parser.get_selector_properties(
...> ".a { color: blue; font-size: 16px; }", ".a")
iex> props
%{"color" => "blue", "font-size" => "16px"}
Concatenate stylesheets, dropping rules a later identical copy makes redundant.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.merge_stylesheets([".a {}", ".b {}"])
iex> css
".a {}\n\n.b {}\n"
Minify a stylesheet. Rewrites the whole file and drops comments by design.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.minify(".a {\n color: red;\n}\n")
iex> css
".a{color:red}"
@spec modify_property( String.t(), String.t(), String.t(), String.t(), boolean(), type() ) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Set a property value on a selector.
Only the value bytes change when the property already exists, so an inline comment on that line survives.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.modify_property(
...> ".a { color: red; }", ".a", "color", "blue", false)
iex> css
".a { color: blue; }"
@spec remove_duplicates(String.t(), type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Remove declarations and rules that a later one makes redundant.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.remove_duplicates(
...> ".a {\n color: red;\n color: blue;\n}\n")
iex> css
".a {\n color: blue;\n}\n"
@spec remove_import(String.t(), String.t(), type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Remove @import rules pointing at import_url.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.remove_import(
...> ~s|@import "a.css";\n@import "b.css";\n|, "a.css")
iex> css
~s|@import "b.css";\n|
@spec remove_selector(String.t(), String.t(), type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Remove a top-level selector and everything it owns.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.remove_selector(
...> ".a {}\n.unused {}\n", ".unused")
iex> css
".a {}\n"
@spec replace_selector_rule(String.t(), String.t(), String.t(), type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Replace a rule's declarations wholesale.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.replace_selector_rule(
...> ".a { color: red; }", ".a", "color: blue; padding: 10px;")
iex> css
".a { color: blue; padding: 10px; }"
@spec selector_exists?(String.t(), String.t(), type()) :: {:ok, atom(), true} | {:error, atom(), false}
Does a top-level rule with this selector exist?
Examples
iex> IgniterCss.Parsers.Parser.selector_exists?(".a { color: red; }", ".a")
{:ok, :selector_exists?, true}
iex> IgniterCss.Parsers.Parser.selector_exists?(".a { color: red; }", "#nope")
{:error, :selector_exists?, false}
@spec sort_properties(String.t(), type()) :: {:ok, atom(), String.t()} | {:error, atom(), String.t()}
Sort declarations alphabetically within each block, by moving whole lines.
Examples
iex> {:ok, _, css} = IgniterCss.Parsers.Parser.sort_properties(
...> ".a {\n color: red;\n background: #fff;\n}\n")
iex> css
".a {\n background: #fff;\n color: red;\n}\n"
Is this CSS understood well enough to patch?
Returns {:ok, :validate_css, true} when it is, and
{:error, :validate_css, message} when it is not.
Examples
iex> IgniterCss.Parsers.Parser.validate_css(".a { color: red; }")
{:ok, :validate_css, true}