elm-styled icon indicating copy to clipboard operation
elm-styled copied to clipboard

Replace Native JS Code

Open k15a opened this issue 8 years ago • 6 comments

I recently realized that only the elm-lang/core package is allowed to have native JS code. Currently elm-styled is using native JS code to inject the CSS. The problem is that I can't publish elm-styled to the official package manager and users would have to install this package directly from GitHub with tools like elm-github-install. The last couple of days I thought how to remove the native code from elm-styled to finally publish the package. My current solutions are:

Monkey Patching Element.prototype

This would work similar to https://github.com/gdotdesign/elm-html-styles. We would add a new attribute setter to the element prototype and everytime an element is created the styles would inject magically.

Usage

The user would have to inject a single script which monkey patches the elment.prototype.

Pros

  • The simplest solution for the users.
  • We could use sheet.insertRule() which is very fast.

Cons

  • We would have to monkey patch browser internals. (I don't like that)

Ports

Usage

  1. Setting up the model to hold all of the rules. (similar to https://github.com/evancz/elm-sortable-table)
  2. Creating a port module and injecting the styles with JavaScript on the other site. / Injecting the styles into a single style tag (probably pretty slow)
  3. Calling styled with an additional argument which is the Msg type to add styles to the model.
    type Msg
        = AddStyle Styled.Msg
        | OtherMsg
    
    styled
        AddStyle div
        [ padding zero
        ]
    

Pros

  • No monkey patching of browser internals.
  • We could use sheet.insertRule() which is very fast.

Cons

  • Much boilerplate which hurts the simplicity of elm-styled

I would love the get some feedback and suggestions for better solutions. Maybe someone with more elm experience has a great solution for us.

k15a avatar Mar 24 '17 19:03 k15a

I am a beginner in Elm but I have an idea...

As far as I see the main problem is injecting the CSS in the HTML. Css.js could be translated to Elm module, and for the function insertStyleSheet you could use node from Elm VirtualDom package somehow: http://package.elm-lang.org/packages/elm-lang/virtual-dom/2.0.4/VirtualDom#Node

I have done a small POC and works good:

module App exposing (..)

import Html exposing (text)
import VirtualDom exposing (node)

main =
    node "style"
        []
        [ text 
            """
            body {
                background:red;
            }

            @media (max-width: 600px) {
                body {
                    background: green;
                }
            }
            """ 
        ]

The only con of this is that style tag is inserted on the body instead of head, but browsers support this: http://stackoverflow.com/questions/1362039/style-and-script-tags-in-html-body-why-not

I hope it helps, by the way thanks for the elm implementation of styled-components!

leskeg-zz avatar Apr 13 '17 21:04 leskeg-zz

Maybe instead of trying to shoehorn the benefits of sheet.insertRule() into a pure Elm package, we should be lobbying Evan to make this the way to do CSS in Elm. This approach seems terrific to me. Are there downsides that I'm not seeing?

gdejohn avatar Jul 15 '17 08:07 gdejohn

https://github.com/elm-lang/virtual-css just got public and it may be good fit for replacing Native code. I really don't know how it's done right now but virtual-css seems excellent for that.

EDIT: This is unreleased yet and I guessing it will be part of the 0.19 release as well as https://github.com/elm-lang/browser

baransu avatar Aug 18 '17 07:08 baransu

I will take a closer look in the future but that looks very promising. Thank you for notifying me.

k15a avatar Aug 18 '17 12:08 k15a

Maybe look at this libarary as well to figure out how it does it: http://package.elm-lang.org/packages/mdgriffith/style-elements/latest

justgage avatar Oct 18 '17 20:10 justgage

@justgage last time I took a look at styled elements they used inline style attributes to add the styles. This is a problem because they don't support keyframe animation pseudo selectors / classes and media queries.

k15a avatar Oct 23 '17 05:10 k15a