Skip to content
This repository has been archived by the owner on Sep 6, 2019. It is now read-only.

Replace Native JS Code #14

Open
k15a opened this issue Mar 24, 2017 · 6 comments
Open

Replace Native JS Code #14

k15a opened this issue Mar 24, 2017 · 6 comments

Comments

@k15a
Copy link
Member

k15a commented Mar 24, 2017

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.

@leskeg-zz
Copy link

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!

@gdejohn
Copy link

gdejohn commented Jul 15, 2017

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?

@baransu
Copy link

baransu commented Aug 18, 2017

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

@k15a
Copy link
Member Author

k15a commented Aug 18, 2017

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

@justgage
Copy link

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

@k15a
Copy link
Member Author

k15a commented Oct 23, 2017

@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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Development

No branches or pull requests

5 participants