Search code examples
htmlelm

Get element width in ELM


i have html like

<h1 class = 'block__title' id='title'>Main text</h1>

with css:

.block__title {
  display: inline-block;
}

i can get this element in js with:

const title = document.getElementById('title');

and doing anything with width title.offsetWidth+1

How i can do the same in ELM? i have:

[ h1 [ class "block-title" ]
            [ text (Main text)
            ]
]

i need to get width of the element higher for further changes


Solution

  • You need to use Browser.Dom.getElement like so:

    module Main exposing (main)
    
    import Browser
    import Browser.Dom exposing (Element, Error)
    import Html exposing (Html, button, div, h1, text)
    import Html.Attributes exposing (class, id)
    import Html.Events exposing (onClick)
    import Task
    
    
    type alias Model =
        { titleWidth : Float }
    
    
    init : () -> ( Model, Cmd Msg )
    init _ =
        ( { titleWidth = 0 }
        , Browser.Dom.getElement "title" |> Task.attempt GotElement
        )
    
    
    type Msg
        = GotElement (Result Error Element)
    
    
    update : Msg -> Model -> ( Model, Cmd Msg )
    update msg model =
        case msg of
            GotElement (Err err) ->
                ( model, Cmd.none )
    
            GotElement (Ok element) ->
                ( { model | titleWidth = element.element.width }, Cmd.none )
    
    
    view : Model -> Html Msg
    view model =
        div []
            [ h1 [ class "block-title", id "title" ] [ text "Main Title Text" ]
            , div [] [ text <| "Title Width: " ++ String.fromFloat model.titleWidth ]
            ]
    
    
    main : Program () Model Msg
    main =
        Browser.element
            { init = init
            , view = view
            , update = update
            , subscriptions = \_ -> Sub.none
            }
    

    You can find more information in the getElement docs.