Code Monkey home page Code Monkey logo

elm-css's Introduction

elm-css

elm-css lets you define CSS in Elm. (For an Elm styling system that is a complete departure from CSS, check out Elm-UI.)

Here's an example of how to define some elm-css styles:

module MyCss exposing (main)

import Css exposing (..)
import Html
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing (css, href, src)
import Html.Styled.Events exposing (onClick)


{-| A logo image, with inline styles that change on hover.
-}
logo : Html msg
logo =
    img
        [ src "logo.png"
        , css
            [ display inlineBlock
            , padding (px 20)
            , border3 (px 5) solid (rgb 120 120 120)
            , hover
                [ borderColor theme.primary
                , borderRadius (px 10)
                ]
            ]
        ]
        []


{-| A plain old record holding a couple of theme colors.
-}
theme : { secondary : Color, primary : Color }
theme =
    { primary = hex "55af6a"
    , secondary = rgb 250 240 230
    }


{-| A reusable button which has some styles pre-applied to it.
-}
btn : List (Attribute msg) -> List (Html msg) -> Html msg
btn =
    styled button
        [ margin (px 12)
        , color (rgb 250 250 250)
        , hover
            [ backgroundColor theme.primary
            , textDecoration underline
            ]
        ]


{-| A reusable style. Css.batch combines multiple styles into one, much
like mixins in CSS preprocessors.
-}
paragraphFont : Style
paragraphFont =
    Css.batch
        [ fontFamilies [ "Palatino Linotype", "Georgia", "serif" ]
        , fontSize (px 16)
        , fontWeight normal
        ]


{-| Css.property lets you define custom properties, using strings as their values.
-}
legacyBorderRadius : String -> Style
legacyBorderRadius amount =
    Css.batch
        [ property "-moz-border-radius" amount
        , property "-webkit-border-top-left-radius" amount
        , property "-webkit-border-top-right-radius" amount
        , property "-webkit-border-bottom-right-radius" amount
        , property "-webkit-border-bottom-left-radius" amount
        , property "border-radius" amount
        ]


view : Model -> Html Msg
view model =
    nav []
        [ img [ src "assets/backdrop.jpg", css [ width (pct 100) ] ] []
        , btn [ onClick DoSomething ] [ text "Click me!" ]
        ]


main : Program Never Model Msg
main =
    Html.beginnerProgram
        { view = view >> toUnstyled
        , update = update
        , model = initialModel
        }

See the Css module documentation for an explanation of how this code works.

elm-css draws inspiration from the excellent Sass, Stylus, CSS Modules, and styled-components libraries. It includes features like:

Examples

Related Projects

elm-css's People

Contributors

ahstro avatar akoppela avatar amarqueslee avatar bobwhitelock avatar devnacho avatar edkv avatar eeue56 avatar gurdiga avatar jfmengels avatar k15a avatar krisajenkins avatar lukewestby avatar mattjbray avatar maxhallinan avatar micahhahn avatar minibill avatar pautrik avatar pxfnc avatar quinnfreedman avatar robertbasden avatar roberto avatar robinheghan avatar robrtle avatar rodrigo-morais avatar rtfeldman avatar scottcorgan avatar tolgap avatar tsawan avatar vipentti avatar wmjoubert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elm-css's Issues

Add a `color : Color.Color` field to `Css.Color`

I'm starting a package for color mixing functions in elm.

My plan is to cover all color functions that are documented in the LessCss preprocessor:

http://lesscss.org/functions/#color-operations

And to use the Core Color type provided by Elm.

I definitely want to make sure it's compatible with elm-css, though with the current plan I believe that means elm-css would have to switch over to using the core Color type. I don't know if there are any issues with that though.

Anyway, let me know your thoughts!
I'm going to be starting work pretty quick.

margin: auto

It would be great if the various margin declarations accepted auto as a value as well as number.
I'd be keen to see how you could solve this (with Elm), so I could potentially help with other properties.

elm-css-webpack-loader

First of all, very nice project!
I'm just trying it out for the first time and I got it working smoothly.

But now I was thinking that it would be nice to have a webpack loader (or even integrate this with the elm-webpack-loader).
I know that this package is not ready yet, so this kind of idea is probably not yet on the roadmap, but it might be nice to already have a discussion about it.

For me the nicest thing would be that the loader would recompile the css file on changes and that it is able to pipe into the file-loader, so you can get hashed file names.

Font keywords

Can't import Html.CssHelpers

Hey,

I'm having trouble with your 1.0.0. I need to manually modify your elm-package.json to have more exposed modules. Specifically Html.CssHelpers, and Css.Namespace. There's probably a tonne but I've only just started looking at the library :)

Am I using the library incorrectly or is the elm-package.json out of date?

Cheers,
SerialVelocity

Vendor prefixes?

Hello!

This is a feature request for automatic vendor-prefixes for the "experimental" CSS properties.

Thanks!

Can elm-css be used in Elm files?

Hello!

Just a quick question: is elm-css intended to be a stand-alone, or can it be used in Elm files as a substitute for Html.Attributes?

`class` from helpers should take a list

e.g

div 
  [ class [ Swimlane, swimlaneType ] ]
  ]

where swimlaneType : CssClasses

right now I have to do

div
        [ classList
            [ (classType, True)
            , (Swimlane, True)
            ]
        ]

rgbaFromHex

This needs to be implemented: https://github.com/rtfeldman/elm-css/blob/master/src/Css.elm#L635-L643

Semantics:

  • Should work with hexadecimal strings of length 3, 4, 6, or 8 (the 4 and 8 would include alpha, just like in CSS)
  • If you give it a crazy value, like you use non-hexadecimal chars or a crazy length, it should return appropriate warning messages

Relatedly, there should probably also be a rgbaFromHsla that works similarly except for HSLA colors.

Post-1.0.0 keywords

Add comment support for compatibility with style guide generators

http://trulia.github.io/hologram/

One possible API: add a comment function that emits comments.

stylesheet
  { name = "homepage" }
  [ comment
"""doc

---
title: Buttons
name: button
category: Base CSS

---

Button styles can be applied to any element.
"""
  , ((.) Button)
      [ borderColor (rgb 12 120 10) ]
  ]

...outputs:

/*doc

---
title: Buttons
name: button
category: Base CSS

---

Button styles can be applied to any element.
*/
.homepageButton {
    border-color: rgb(12, 120, 10);
}

Supporting this would require changing Declarations to support Comment.

Should we support something like `@extend` or `composes` in addition to mixins?

Both SASS's @extend and CSS Modules's composes have to do with using CSS classes to reuse code. Classes are more limited than mixins (for example, they can't incorporate pseudo-classes or pseudo-elements), but whereas mixins disappear after compilation, classes stick around; the browser is actually aware of them. Is that a good justification for expanding their use as a method of style composition?

@extend is a notorious footgun. There's an entire article on why never to use it. (tl;dr from the article itself: "Extending doesnโ€™t necessarily help file weight, contrary to the saying. Extending doesnโ€™t work across media queries. Extending is not flexible. Mixins have absolutely no drawback.") A cursory Google search reveals several other articles raising red flags about @extend.

I personally don't use @extend for these reasons, and don't see any reason elm-css should support that footgun in the first place.

composes declares that a certain class is always to be used in conjunction with another. For example (with some hand-waving) if you're using CSS Modules and you say "btn-warning composes btn" then when in your code you use "class='btn-warning'" you'll actually get "class='btn btn-warning'" in the DOM.

If you already have mixins (which we do), then the benefits of composes seem dubious. If you're using gzip, there's a good chance the way mixins duplicate output properties will actually save space compared to declaring additional (unique within the document) class strings. Worse, the browser has to do more work to apply the classes in sequence, rather than just having a single class worth of styles to applyโ€”on top of which, minifiers can no longer help the browser by excising redundant declarations in advance.

Is there actually any significant net upside to including these? It seems like "just use mixins" is the best design, but I'd like to at least have an issue to discuss this in case I'm missing something important.

Miscellaneous keywords

These are keywords that are in the spec but not mentioned in other issues. Some of them should probably be moved to #12

Would you consider a `raw` function for adding additional properties as a raw string?

The idea is something like this:

css =
  (stylesheet << namespace "myModule")
    [ (.) Grid
        [ display flex
        , width (px 200)
        , height (px 200)
        ] ++ raw """
        cursor: default;
        border: 3px solid black;
        """
    ]

The raw function would just spit out raw css, with no type checking. I don't know enough about elm-css to know how this would be implemented. raw would return a list of something (I don't know what).

I realise this goes against one of the goals of elm-css, which is of type safety. However, here are two justifications for this approach:

  1. It gives the users of elm-css the option of using properties that haven't implemented. Currently cursor: default| pointer | grabbing | resize-sw etc is not implemented., there are hundreds (if not thousands?) of css properties and they are constantly being added to the css specification. The elm community is small: it may not be feasible to keep up. I need to use cursor: default;. A the moment my options are either to:
    • A. wait till the cursor property gets implemented. An issue has been created (#90), but it's already 8 days old, so it may take a month before it's implemented. I didn't intend to spend more than a couple of days on the thing I'm working on, so I'd have to go back to using plain old css.
    • B. Implement it and submit a pull request. This is the noble route, but I don't think we should expect all users to have to understand the internals of elm-css. I had a quick go, but I quickly got confused by types such as Compatible. The default option of cursor seems problematic - I'm sure the word default is used by other css properties. Even if I did implement it, I'd have to wait until it got accepted and pushed to elm-packages. A raw function would provide an interim option: it could be replaced once the cursor property appears in elm-css.
  2. There are two main modes of writing css: implementing someone else's design, and designing in the browser. When you implement someone else's design you know in advance the sizes of paddings and borders. When you design in the browser you are constantly tweaking things until you like them. It would be extremely handy to be able to paste in raw css properties from a browser developer tool, and convert them to elm-css once you've settled on a design. This is one advantage of SCSS: the css property syntax is backwards compatible with css.

I'd be happy to implement this. The real question is whether there would be any philosophical objections to having this functionality in elm-css.

hsl and hsla functions

We should have hsl and hsla functions that:

  • Compile to hsl() and hsla() in CSS, respesctively. These are supported in IE9+, which makes them reasonable to include as a passthrough compile without (for example) converting to rgb behind the scenes.
  • Records warnings if you pass numbers outside the acceptable range for these values (see how rgb and rgba do this for examples)
  • Have elm-test tests in test/Properties.elm to verify that they can be used as intended.
  • Have elm-check tests like what rgb and rgba have to verify that the warnings work.

Example isn't working

I'm getting the following error when running elm reactor in the examples dir, or
elm-css src/Stylesheets.elm from the command line

Detected errors in 1 module.
-- NAMING ERROR ----------------------------------- ./../src/Html/CssHelpers.elm
Cannot find type `Snippet`
26โ”‚   , rules : List Snippet -> List Snippet
                     ^^^^^^^
-- NAMING ERROR ----------------------------------- ./../src/Html/CssHelpers.elm
Cannot find type `Snippet`
26โ”‚   , rules : List Snippet -> List Snippet
                                     ^^^^^^^

Support charset, namespace, and import

There are three non-nested at-rules in CSS: @charset, @import, and @namespace.

They have extremely strong restrictions on how you can use them. A stylesheet that uses any of these must be laid out precisely as follows:

  1. 0-1 @charset declarations, with no preceding characters in the stylesheet
  2. 0 or more @import declarations
  3. 0 or more @namespace declarations
  4. All other styles. From here on, these three rules cannot be used.

As such, allowing them to be mixed and matched with other declarations is asking for trouble.

A reasonable way to support them nicely would be to offer an alternative to compile - something like:

type alias StylesheetOptions =
  { charset : Maybe String
  , imports : List CssImport
  , namespaces : List CssNamespace
  }

compileWithOptions : StylesheetOptions -> { a | name : b } -> List Declaration -> Result String String

Then it could emit these statements as appropriate, automatically following the rules, and all would be well.

Split out Css.Elements

What do you think about separating keywords for selectors, properties, media queries, etc. into separate modules? I'm trying elm-css out on a personal project right now and I'd like to colocate each component's CSS with its view, but the html selector keywords clash with elm-html's element functions. I'd love to be able to do:

import Html exposing (...)
import Css.Elements
import Css.Properties exposing (..)
import Css exposing (..)

-- ...

css =
  stylesheet { name = "example" }
    $ Css.Elements.body |$ Css.Elements.html
      ~ margin zero
    . Nav
      ~ padding (px 10)

-- ...

Opacity or other integer only properties cannot use initial, inherit or unset

This is basically because all the other property functions work in such a way that they will be given a function to return a compatible record:

~ display inline

This means you can just add any new props to the definition of BasicProperty and they will function. With opacity though, presumably you want to do something like this:
~ opacity 0.2

Which means opacity currently assume it's getting a number:
opacity num =
prop1 "opacity" { value = stringToNumber num }

Which works, but, can't operate on what initial, inherit, or unset return.

I suppose we write up "simpleNum" or something so you could do
~ opacity (simpleNum 0.2)

But that seems odd. I'm too new at elm to know the right path, but wanted to post that I got this error when I tried adding opacity to the tests with initial, inherit, unset.

Cheers

Nick

1.0.0 Roadmap

  • Specify enough docs and exposed modules to satisfy elm package publish
  • Finish all the combinator permutations (e.g. >. and |#)
  • Add support for pseudo-classes and pseudo-elements
  • Run elm-format ๐Ÿ’ฅ
  • Merge in the npm branch
  • Implement Mixins
  • Have the Node .css file generator spit out error messages (and nonzero exit code) if prettyPrint fails
  • Split out elm-css-helpers into its own package
  • Split out elm-css-util into its own package, to be shared with elm-css-helpers
  • Implement @media with proper error handling
  • Implement @charset with proper error handling
  • Add all the missing keywords ๐Ÿ™€
  • Add all the missing elements
  • Figure out a solution for :not - don't want to shadow Basics.not and also want to be able to express :not(div, .Foo) in a type-checked way - could make a series of not operators like &:!$, but that's not the prettiest
  • Add examples to documentation
  • Resolve all the TODOs
  • Write a basic tutorial explaining things like what with does

Add tests for at least one of each possible value

Every property needs a check to make sure it can be set to initial, unset, inherit, plus all the other appropriate ones.

Don't need to use elm-check for this; just need to make sure they all type-check.

Why is the core Color.Color type not used to define colors?

elm-css defines its own Css.Color type rather then using the core Color.Color type. It also redefines functions such as rgb that are defined in the core library. This seems a bit redundant and means you must map between Core color types and Css color types when using Core color types. Is there a good reason for this?

No `String -> MediaQuery` function for custom media queries

Hi,

I'm trying to use media queries like this:

@media (max-width: 768px) {
    ...
}

I'm new to Elm, so I could be missing it, but it looks like only queries like @media "print" are supported. Is that correct? Is there any way for me to use more generic functions to generate the right output?

Thanks!

Border keywords

Node version support

Should the command line tool be supported for node < v4? The current implementation uses template strings which aren't implemented in < v4 so CI is failing for those runtimes.

Validity checks

This is not MVP, but at some point I'd like to have elm-css do some additional checks for invalid values (perhaps once the Declarations have been assembled, or perhaps sooner...waiting for Declarations arguably allows extra context and thus nicer error messages, but requires more regexp work).

Some checks that sound good:

  • Run a regex (regex "^([a-fA-F]{3}|[a-fA-F]{6})$" for hex colors) to confirm they're valid color values.
  • Warn if there are any selectors defined with no properties; they won't do anything and should be deleted.
  • Warn if the same property is declared multiple times within the same selector. All but the last declaration should be deleted.
  • Warn if the same selector is declared multiple times within the same stylesheet. There are theoretically reasons it might be reasonable to support this, but more likely than not, this will just be error-prone. The Anti Footgun League says: complain about it.
  • Warn if any MultiSelectors include multiple Type Selectors; these will for sure emit busted CSS.
  • Warn if any class, id, or animation names are not valid CSS identifiers - possible if you use strings instead of union types.
  • Verify that text-align and text-align-last disallow the appropriate properties that the other doesn't support. This can't be fixed with type checking because of left, right, top, and bottom being overloaded as both keys and values.

Parent rule gets printed one time for each rule in its `children`

That means the generated CSS can have multiple identical rules.

E.g.

    article
        [ margin zero
        , children
            [ header [ margin zero ]
            , section [ margin zero ]
            , nav [ margin zero ]
            ]
        ]

gets compiled to

article {
    margin: 0;
}

article > header {
    margin: 0;
}

article {
    margin: 0;
}

article > section {
    margin: 0;
}

article {
    margin: 0;
}

article > nav {
    margin: 0;
}

Is this expected behaviour? One could fix the CSS by splitting the parent in one definition with just the styles and one with just the children. Or would there be a more idiomatic way?

Tests for continuing the "Or"

It's important that >$, >>$ continue styling the previous |$, |#, and |. if applicable.

In other words, this:

$ body |# page |# editor-container |# editor-frame |# body >$ div |# body >$ div >$ div |# body >$ div >$ div >$ div

...should compile to this:

body, #page, #editor-container, #editor-frame, body > div, body > div > div, body > div > div > div

There should be tests confirming this.

Examples doesn't work

Hi @rtfeldman

I tried to run elm make HomepageView.elm and got an error

I cannot find find module 'Html.Helpers'.

Module 'HomepageView' is trying to import it.

Potential problems could be:
  * Misspelled the module name
  * Need to add a source directory or new dependency to elm-package.json

It would be great you fix examples. I'm trying to use elm-css in one of my non-production app.

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.