diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs
index 00eec162..4cc6d4dd 100644
--- a/bindings/python/src/lib.rs
+++ b/bindings/python/src/lib.rs
@@ -65,12 +65,12 @@ fn parse_url(url: Option<String>) -> PyResult<Option<url::Url>> {
     })
 }
 
-/// CSSInliner(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)
+/// CSSInliner(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, styles_as_attributes=False)
 ///
 /// Customizable CSS inliner.
 #[pyclass]
 #[pyo3(
-    text_signature = "(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)"
+    text_signature = "(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, styles_as_attributes=False)"
 )]
 struct CSSInliner {
     inner: rust_inline::CSSInliner<'static>,
@@ -85,6 +85,7 @@ impl CSSInliner {
         base_url: Option<String>,
         load_remote_stylesheets: Option<bool>,
         extra_css: Option<String>,
+        styles_as_attributes: Option<bool>,
     ) -> PyResult<Self> {
         let options = rust_inline::InlineOptions {
             inline_style_tags: inline_style_tags.unwrap_or(true),
@@ -92,6 +93,7 @@ impl CSSInliner {
             base_url: parse_url(base_url)?,
             load_remote_stylesheets: load_remote_stylesheets.unwrap_or(true),
             extra_css: extra_css.map(Cow::Owned),
+            styles_as_attributes: styles_as_attributes.unwrap_or(false),
         };
         Ok(CSSInliner {
             inner: rust_inline::CSSInliner::new(options),
@@ -115,12 +117,12 @@ impl CSSInliner {
     }
 }
 
-/// inline(html, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)
+/// inline(html, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, styles_as_attributes=False)
 ///
 /// Inline CSS in the given HTML document
 #[pyfunction]
 #[pyo3(
-    text_signature = "(html, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)"
+    text_signature = "(html, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, styles_as_attributes=False)"
 )]
 fn inline(
     html: &str,
@@ -129,6 +131,7 @@ fn inline(
     base_url: Option<String>,
     load_remote_stylesheets: Option<bool>,
     extra_css: Option<&str>,
+    styles_as_attributes: Option<bool>,
 ) -> PyResult<String> {
     let options = rust_inline::InlineOptions {
         inline_style_tags: inline_style_tags.unwrap_or(true),
@@ -136,17 +139,18 @@ fn inline(
         base_url: parse_url(base_url)?,
         load_remote_stylesheets: load_remote_stylesheets.unwrap_or(true),
         extra_css: extra_css.map(Cow::Borrowed),
+        styles_as_attributes: styles_as_attributes.unwrap_or(false),
     };
     let inliner = rust_inline::CSSInliner::new(options);
     Ok(inliner.inline(html).map_err(InlineErrorWrapper)?)
 }
 
-/// inline_many(htmls, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)
+/// inline_many(htmls, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, styles_as_attributes=False)
 ///
 /// Inline CSS in multiple HTML documents
 #[pyfunction]
 #[pyo3(
-    text_signature = "(htmls, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)"
+    text_signature = "(htmls, inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, styles_as_attributes=False)"
 )]
 fn inline_many(
     htmls: &PyList,
@@ -155,6 +159,7 @@ fn inline_many(
     base_url: Option<String>,
     load_remote_stylesheets: Option<bool>,
     extra_css: Option<&str>,
+    styles_as_attributes: Option<bool>,
 ) -> PyResult<Vec<String>> {
     let options = rust_inline::InlineOptions {
         inline_style_tags: inline_style_tags.unwrap_or(true),
@@ -162,6 +167,7 @@ fn inline_many(
         base_url: parse_url(base_url)?,
         load_remote_stylesheets: load_remote_stylesheets.unwrap_or(true),
         extra_css: extra_css.map(Cow::Borrowed),
+        styles_as_attributes: styles_as_attributes.unwrap_or(false),
     };
     let inliner = rust_inline::CSSInliner::new(options);
     inline_many_impl(&inliner, htmls)
diff --git a/bindings/python/tests-py/test_inlining.py b/bindings/python/tests-py/test_inlining.py
index 8f69f575..701d347e 100644
--- a/bindings/python/tests-py/test_inlining.py
+++ b/bindings/python/tests-py/test_inlining.py
@@ -89,6 +89,7 @@ def test_invalid_base_url():
     base_url=provisional.urls() | st.none(),
     load_remote_stylesheets=st.booleans() | st.none(),
     extra_css=st.text() | st.none(),
+    styles_as_attributes=st.booleans() | st.none(),
 )
 @settings(max_examples=1000)
 def test_random_input(
@@ -98,6 +99,7 @@ def test_random_input(
     base_url,
     load_remote_stylesheets,
     extra_css,
+    styles_as_attributes,
 ):
     with suppress(ValueError):
         inliner = css_inline.CSSInliner(
@@ -106,5 +108,6 @@ def test_random_input(
             base_url=base_url,
             load_remote_stylesheets=load_remote_stylesheets,
             extra_css=extra_css,
+            styles_as_attributes=styles_as_attributes,
         )
         inliner.inline(document)
diff --git a/bindings/wasm/src/lib.rs b/bindings/wasm/src/lib.rs
index 58c13a87..c16d0dc2 100644
--- a/bindings/wasm/src/lib.rs
+++ b/bindings/wasm/src/lib.rs
@@ -73,6 +73,7 @@ struct Options {
     base_url: Option<String>,
     load_remote_stylesheets: bool,
     extra_css: Option<String>,
+    styles_as_attributes: bool,
 }
 
 impl Default for Options {
@@ -83,6 +84,7 @@ impl Default for Options {
             base_url: None,
             load_remote_stylesheets: true,
             extra_css: None,
+            styles_as_attributes: false,
         }
     }
 }
@@ -105,6 +107,7 @@ impl TryFrom<Options> for rust_inline::InlineOptions<'_> {
             base_url: parse_url(value.base_url)?,
             load_remote_stylesheets: value.load_remote_stylesheets,
             extra_css: value.extra_css.map(Cow::Owned),
+            styles_as_attributes: value.styles_as_attributes,
         })
     }
 }
@@ -129,6 +132,7 @@ interface InlineOptions {
     base_url?: string,
     load_remote_stylesheets?: boolean,
     extra_css?: string,
+    styles_as_attributes?: boolean,
 }
 
 export function inline(html: string, options?: InlineOptions): string;
diff --git a/css-inline/src/lib.rs b/css-inline/src/lib.rs
index 54fc6709..baea7cf4 100644
--- a/css-inline/src/lib.rs
+++ b/css-inline/src/lib.rs
@@ -74,6 +74,8 @@ pub struct InlineOptions<'a> {
     // Python wrapper for `CSSInliner` and `&str` in Rust & simple functions on the Python side
     /// Additional CSS to inline.
     pub extra_css: Option<Cow<'a, str>>,
+    /// Whether to break down styles into separate attributes
+    pub styles_as_attributes: bool,
 }
 
 impl<'a> InlineOptions<'a> {
@@ -87,6 +89,7 @@ impl<'a> InlineOptions<'a> {
             base_url: None,
             load_remote_stylesheets: true,
             extra_css: None,
+            styles_as_attributes: false,
         }
     }
 
@@ -125,6 +128,13 @@ impl<'a> InlineOptions<'a> {
         self
     }
 
+    /// Insert styles as attributes
+    #[must_use]
+    pub fn styles_as_attributes(mut self, styles_as_attributes: bool) -> Self {
+        self.styles_as_attributes = styles_as_attributes;
+        self
+    }
+
     /// Create a new `CSSInliner` instance from this options.
     #[must_use]
     pub const fn build(self) -> CSSInliner<'a> {
@@ -141,6 +151,7 @@ impl Default for InlineOptions<'_> {
             base_url: None,
             load_remote_stylesheets: true,
             extra_css: None,
+            styles_as_attributes: false,
         }
     }
 }
@@ -284,7 +295,7 @@ impl<'a> CSSInliner<'a> {
             }
         }
         if let Some(extra_css) = &self.options.extra_css {
-            process_css(&document, extra_css, &mut styles);
+            process_css(&document, extra_css.as_ref(), &mut styles);
         }
         for (node_id, styles) in styles {
             // SAFETY: All nodes are alive as long as `document` is in scope.
@@ -299,7 +310,15 @@ impl<'a> CSSInliner<'a> {
                 .attributes
                 .try_borrow_mut()
             {
-                if let Some(existing_style) = attributes.get_mut("style") {
+                if self.options.styles_as_attributes {
+                    if let Some(_existing_style) = attributes.get_mut("style") {
+                        // TODO
+                    } else {
+                        for (name, (_, value)) in styles {
+                            attributes.insert(name, value);
+                        }
+                    }
+                } else if let Some(existing_style) = attributes.get_mut("style") {
                     *existing_style = merge_styles(existing_style, &styles)?;
                 } else {
                     let mut final_styles = String::with_capacity(128);
diff --git a/css-inline/src/main.rs b/css-inline/src/main.rs
index 855b06df..551825fa 100644
--- a/css-inline/src/main.rs
+++ b/css-inline/src/main.rs
@@ -47,6 +47,9 @@ OPTIONS:
 
     --extra-css
         Additional CSS to inline.
+
+    --styles-as-attributes
+        Will insert styles as separate attributes.
 "#
 )
 .as_bytes();
@@ -58,6 +61,7 @@ struct Args {
     extra_css: Option<String>,
     load_remote_stylesheets: bool,
     files: Vec<String>,
+    styles_as_attributes: bool,
 }
 
 fn parse_url(url: Option<String>) -> Result<Option<url::Url>, url::ParseError> {
@@ -83,6 +87,7 @@ fn main() -> Result<(), Box<dyn Error>> {
             base_url: args.opt_value_from_str("--base-url")?,
             extra_css: args.opt_value_from_str("--extra-css")?,
             load_remote_stylesheets: args.contains("--load-remote-stylesheets"),
+            styles_as_attributes: args.opt_value_from_str("--styles-as-attributes")?.unwrap_or(false),
             files: args.free()?,
         };
         let options = InlineOptions {
@@ -91,6 +96,7 @@ fn main() -> Result<(), Box<dyn Error>> {
             base_url: parse_url(args.base_url)?,
             load_remote_stylesheets: args.load_remote_stylesheets,
             extra_css: args.extra_css.as_deref().map(Cow::Borrowed),
+            styles_as_attributes: args.styles_as_attributes,
         };
         let inliner = CSSInliner::new(options);
         if args.files.is_empty() {