We discuss the fundamentals of elm-ui, and how to decide if it's the right fit for your team.
July 27, 2020

Previously called style-elements

Escape hatches

  • Element.html works at leaf nodes, but elm-ui in general doesn’t mix with plain html

  • Element.htmlAttribute

  • Refactoring is a huge asset for a team, so much easier than css refactoring

  • Doesn’t expose all the css tricks directly, sometimes you need escape hatches to access those


  • Pass in window size from your Elm model
  • Doesn’t use media queries, so that approach doesn't play well with with pre-rendered html like in elm-pages
  • classifyDevice is an optional helper for responsiveness

Semantic html

  • Express layout with Element.row, column, el
  • Semantic HTML is independent from layout. Set with attributes using the Element.Region module.


  • Element.paragraph uses text wrapping


  • elm-ui doesn't expose access to rem and em units to simplify the mental model and reduce overlapping ways to express something


Lucas Payr's elm-ui-widgets Alex Korban's elm-ui patterns )

Debugging elm-ui views

  • Element.explain gives you highlights around nested elements
  • Inspecting developer tools doesn't help much with elm-ui, but elm-ui is much more traceable because it doesn't have layout cascading like CSS



Hello, Jeroen.
Hello, Dillon.
So what are we talking about today?
Today, we are pulling out some UI knowledge
and talking about Elm UI.
I think it's the first time we talk about UI, actually.
That's true.
I do tend to, as an Elm developer,
you think so much about types, business logic.
It almost feels like this backend developer mindset
focused on sort of modeling the domain and things like that
and refactoring and testing.
But UI is an important skill.
It's not necessarily my strong suit,
but I think it's important,
and I think Elm UI is a super cool way to do it in Elm.
Yeah, it's not my strong suit either.
I'm more of a tooling guy.
But Elm is a frontend language,
or language for web apps.
So it is kind of a big point.
Essentially, what we're doing with Elm, for the most part,
is trying to put things on a web page.
So if we can do that nicely, elegantly,
in a maintainable way, it's a really important skill.
So I think the first question to answer is,
what is Elm UI?
Yep, what is Elm UI?
Well, first of all, it is a way to get something
of the type HTML in your Elm application, ultimately.
That's what it does.
But it does that in a way that's got a very Elm sort of philosophy.
That's really the way I think of it,
is if you take the philosophical ideas of Elm,
the simplicity, predictability,
the focus on making a really nice experience
without prioritizing being backwards compatible
with every script and library that's been written before,
and instead trying to create a nice little space
where you can express things in a very nice and safe way.
That's how I think of Elm UI, ultimately.
If you didn't have to worry about being backwards compatible
with every CSS decision ever,
how would you create a new way of expressing views and layouts
that would be really easy to understand,
and that's speaking in the language of a human,
not in a standard body that sort of evolved
into all these past decisions.
Since 1995 or something, yeah.
I don't know how old CSS is, actually.
I don't know the history there.
So Matt Griffith, the author of Elm UI,
he's quite knowledgeable about all those trivial things and stuff.
It's really fun to talk to him about that stuff.
But I think that's one of the really cool things,
is that Elm UI,
CSS has a lot of overlapping ways to do things,
and you see this happening a lot
in the system that you introduce let and const in ES6,
but you don't take away var.
Var is still there because the old stuff has to work.
And arrow functions are an even better example
because people can sort of agree that,
for the most part, let's not use var.
Now, var does have hoisting,
which let and const don't have,
so some people might still deliberately choose to use var
as a JavaScript style syntax code base.
But arrow functions have certain properties
of lexical scoping that are more predictable and nice,
and they're nicer for certain things,
but then they don't have hoisting,
and the syntax feels a little awkward to use
because you have to bind it to a constant.
You have to say const function name equals arrow function.
So that's sort of the same feeling with CSS,
but you can still float left and float right
and do clear fix and all these CSS hacks, right?
These things that, like, more old school CSS
didn't have native built in support
for a lot of things that we have primitives for now
with things like Flexbox.
But CSS still has all these overlapping ways
to express things,
and so it becomes really difficult
to figure out what are the good parts of CSS.
Maybe there are the parts that you are using
that you understand all these other things
and how they interact with the good parts of it,
and LMI doesn't have those problems.
Yeah, the biggest problems I find with CSS
is that a lot of things are incompatible.
Like, you can't use this property
if you are also using this one,
or if you use this one,
you also need to use this one.
So if you do flex dash direction,
you'd necessarily need to do display flex.
You can't forget it.
It's pretty simple,
but other ones can be pretty complicated.
And some of them, like,
you really need to know about
several browsers implementations.
Like, if you do position absolutes,
I think you need to set at least top and left
or bottom and right.
Otherwise, on Internet Explorer 11,
it will not show up as expected.
Which I have not had the luck to learn about
through some great teaching.
I had to learn on the stack,
and well, my skills are what they are now.
Yeah, right.
But yeah, when you learn LMI,
you learn something from scratch
which is well designed, as far as I can tell.
Good job, Matt.
And yeah, it feels much simpler, much smaller,
simply quite nice to use.
Yeah, and exactly as you say,
there aren't as many caveats
where it's like,
okay, here's this feature,
but you have to be sure
that you use it only in this context,
and if you use this one thing,
you have to use it with this other thing,
with these other conditions,
and it's going to conflict with this other thing.
And then with CSS,
it always feels like there are two ways to do it.
And the best practice is to just
maybe pick one and stick to it,
but then there are certain places
where margin and padding behaves differently,
like margin around a button
is going to have certain behavior
versus padding is inside the button.
And LMI just says like,
hey, you've got padding.
That's the tool you use
to put space around things.
And if you want space around a button,
you can use the parent container thing
and have that have padding
and then have the button inside of that,
and that's how you get like,
you don't need like these two different ways
to express the same idea.
And if you think about that
from a debugging point of view,
if you're looking at a particular page
and you know it's written with CSS,
where do you even begin
to go looking for the problem?
It could come from one style sheet.
Yeah, when you've got a UI problem,
somebody's pointed out that the padding
is off on something.
In one specific browser.
Right, maybe.
Well, that's another matter,
but there's that too.
And actually, LMI,
it is kind of cool because LMI
can have a way of expressing things
and it's more high level
than just plain CSS,
so it can encapsulate
across browser, which is true.
That's a nice feature.
But even just like a more basic,
this needs more padding.
Well, where's the padding coming from?
Is it defined in this style sheet
or in this other style sheet?
Is it being overridden?
Is there an exclamation point important somewhere
that's causing it to happen
or a more specific CSS selector somewhere
where that padding is coming from?
Is it coming from padding or from margin?
So there are so many things to think about.
So the padding is defined by the parent, period.
There's no margin.
It's just padding.
There's no cascading.
It's all just inline styles.
That style may be defined,
that layout rule may be defined in another module.
It may be defined in a function
which takes a parameter.
So you have to figure that out
just like debugging any Elm code,
and the debugging is the same as figuring out
where a particular value came from in your Elm code.
I think we need to address some other basics
that we have skipped over.
So we're talking about an Elm package
which is called md Griffith slash Elm UI,
Elm dash UI,
because there are several others Elm UI,
and this is the one we were talking about.
I think everyone in the community
is probably authors of other Elm UIs.
When they say Elm UI,
they talk about their own, maybe.
Right, and it was formerly called style elements.
So if you ever see that word floating around,
there are some really good talks
about style elements, unfortunately,
but that's sort of the 1.0 version
of those ideas of Elm UI.
Yeah, I think it doesn't change all that much
in this one, the basic ideas.
No, the basic ideas are similar.
So one of the really big changes is
there was a notion of these sort of classes
where you built them using Elm types,
so you usually would just have one big union type
or custom type that defined all the different classes
you could have, like your button class
and your, maybe the button class has variance to it
that it can be like button,
primary and button, secondary and things like that.
And it could have maybe a bool
of whether it's enabled or disabled or whatever,
but you would apply different styles
based on that class, and you would,
so instead of having just inline styles
that you put, and then it's up to you
to choose how you want to abstract those away,
you had to have a sort of single place
for possible styles and how to display them,
and then you would say,
I want an element, and it's a button primary.
Okay, yeah, that looks pretty different
from what is in Elm UI now.
And it feels very different,
and that was probably the biggest change,
and that I think was a very nice change.
A lot of the guiding philosophy I think behind Elm UI
is like, if we have a way to do it in Elm,
let's construct in this library for it.
Let's use Elm abstractions
like abstracting things to a different module.
Yeah, I think it's worth pointing out again
that Elm UI is a replacement for Elm HTML.
So it's not like Elm CSS where you use Elm slash HTML
and set style properties on it.
It is a very different paradigm meant to do the same thing.
But as we said several times,
in a simpler way, in a nicer way, in a fresher way.
Ultimately, at some point in your Elm UI based app,
you're going to have a function called element.layout
or element.layoutwith which you can provide some options,
and that's going to be like the top level thing.
So your view function,
instead of just being a view function
that takes in a bunch of HTML,
and you're going to use the other Elm view function,
you're going to need to give it a type called element
from Elm UI, that's its equivalent of HTML,
and you just take those elements
and you call the element.layout function
with all of your elements
that represent your entire page's view,
and that turns it into HTML,
which is something that Elm itself can present in your view.
And then otherwise, it feels very similar
to the way that we write HTML in Elm,
you know, HTML.div list list,
where there's like the list of attributes
and the list of the children of that div.
It's element.row or element.column,
and then those also take a list of attributes
and a list of children,
but the children are of type element,
not of type HTML now.
So it feels generally very similar in a lot of ways.
So I have not had the pleasure to use it professionally.
I've used it for a side project, which I've abandoned now.
In my previous job, we used Elm CSS,
and in my current one at Humia, we use regular CSS.
It's working well also,
though I'm not very familiar with CSS,
or at least not enough.
So I think I would have an easier time working with Elm UI,
but that's not what we use at the moment.
So you've played with it more than I have.
So yeah, I was thinking of asking you questions today.
Yes, please do.
Yeah, you know, to be honest,
I haven't used it in a paid professional setting,
but I've used it for some pretty substantial...
I built a project called Mobster,
which is like an electron app that's built with Elm.
That actually uses Elm style elements,
a few years back.
Well, if you have no experience with Elm UI,
then this is finished.
We're done talking about it.
No, I use Elm UI quite a bit in side projects,
and I really like it, but yeah.
I have the basics, but just the basics.
So when would you choose to use Elm UI
instead of CSS or Elm CSS
or is it all there?
Yeah, that is a really good question
because it's tempting to always jump on the new shiny thing.
And so you have to ask yourself,
what business problem does this solve?
And then what risks are associated with it?
What potential dead ends might we run into?
And so, I think the first thing to talk about
is how does it...
design toolkits and frameworks?
And that's not what Elm UI is.
So if you want to use Bootstrap or Material Design
or InDesign, Tailwind, right.
Now Tailwind is interesting
because Tailwind is a set of utility classes.
So Tailwind CSS is actually...
You can look at a site and you know it's built with Bootstrap.
Even if it's using a sort of custom theme with Bootstrap,
it's pretty clear,
that's a Bootstrap primary button,
that's a Bootstrap secondary button,
that's a Bootstrap outline button, whatever.
And with Tailwind CSS,
often people are going to be sort of copy pasting
certain recipes from the Tailwind docs and stuff,
which they do quite a nice job.
But really you can build a view
that looks like whatever you want it to using Tailwind.
Organizing that and building that out.
So Elm UI is more like that,
where it's not going to be a total design framework
that's made all these decisions for you
and it has a look and feel baked into it, right.
Which for a lot of professionally designed
custom applications, that's what you want.
Because I think you do hit up against a wall eventually
if you're limited to the decisions that Bootstrap has made
or that Material Design has made.
But if you consider, you know, Elm UI is not,
it's not designed to play well
by just sprinkling in a little bit of CSS.
So if you want to look up some CSS
for some custom thing, there are escape patches.
There is a function called element.html
which takes an actual HTML thing
and it lets you sneak in an Elm HTML element
for Elm UI code.
Which is nice because then you can gradually add Elm UI
to your project or back out of it also if you don't like it.
Yes, definitely.
And it doesn't always play nicely
and you shouldn't expect it to.
But when you're adding something at a leaf node,
it might be okay because you're just saying
like I have a select, you know, like drop down
and it works exactly the way I want.
I just want to render that with my regular styles
and you call out to it
and that's probably going to work pretty well.
The reason why you say that it doesn't always work well
with normal CSS is because under the hood
it uses CSS classes.
So ones are very, very small class names,
but it does have CSS classes.
So potentially they could conflict
and it inherits properties from Elm UI elements
that are above your HTML elements.
And there are also escape patches.
There's what is it called element.attribute.
HTML Attribute.
Yeah, exactly.
element.html attribute is the escape patch for,
you know, you could even add a CSS class
to an Elm UI element.
And I've found occasions to use it
that we can get into more details,
like some stuff around like responsive elements
with media queries.
But, you know, generally if you want to sprinkle in
a lot of CSS for whatever reason, you know,
you have some really complicated CSS tricks
that you're using for things.
It's something to be aware of that like Elm UI
works really nicely if you're just sort of
presenting some core things.
But yes, Elm UI is not attempting to expose
every single thing you could possibly do with CSS.
And it gives you escape patches
in case you need to do that.
And, you know, if you want a tool that, you know,
lets you use the same mental model as using CSS
and that lets you just do anything
you could possibly do with CSS,
but in a way that's more type safe,
then that's basically what Richard Feldman's
So I often see the advice that if you don't know CSS well,
like for instance, if you are a backend developer originally,
and you're new to frontend and Elm,
then Elm UI is a good recommendation
that it will help you out
to get things looking nicely in an easy way.
So I don't question that that is a good advice.
What do you think about using Elm UI
when you are someone who knows CSS very well?
And also, how does it work with teams?
Like when, for instance, you don't know CSS well,
but your colleagues do, do you need to win them over?
Or is it a bad idea to use Elm UI?
Right. Here's my bottom line.
Like if the client was asking me,
we're considering using Elm UI or something else,
I would go with...
Yes, go with Elm UI. Go.
Yeah, I mean, I think there are a lot of reasons to go with Elm UI.
Here's how I would frame that decision.
I'd be thinking about, let's start with the pros.
We've talked about a lot of them.
I think the number one pro in my mind,
well, I think the best way to summarize
what will work really well for using Elm UI
in a company setting for a team
is that Elm UI feels way more like refactoring
plain Elm code than it does refactoring CSS style sheets.
Which if you've ever done both of those things,
then I think you know exactly what I mean by that, right?
It's very scary.
If you're changing CSS,
it feels like a huge risk to tweak something
because you're like, well, what other things
is that going to affect?
Just start from scratch.
Just start the whole page from scratch.
That's what I do.
And when you're talking about a code base
that over time is really going to grow
into a large code base and a large team maintaining it,
that's huge.
Because ultimately, things just can slow down so much
as a code base and a team gets large, right?
So I would say that that is the number one consideration,
how maintainable is it going to be?
And that's going to outweigh any cost of,
whatever cost there is for learning a new thing.
Honestly, learning it isn't that hard.
I wouldn't be concerned about learning Elm UI.
It does look very simple, yeah.
It's quite simple.
And it's not the kind of thing that you're like,
okay, this is how we use Elm UI
and don't use these parts of it
as one way to express things for the most part.
And then you can organize your code nicely,
and that's important.
But for the most part, you express things one way.
It kind of looks like the same arguments
as for Elm, basically.
I think that's a really good way to put it, yes.
Yeah, if you're willing to make the jump to Elm,
then you can make the jump to Elm UI in a way.
I think that's probably a pretty fair statement.
But yeah, the refactoring experience is second to none
as far as view code goes.
Because if you're saying,
hey, is it going to break anything
if I change this style in this one place?
You can literally just,
if you're using IntelliJ,
you can say find usages of the definition
of some style thing you're looking at.
It's a function for how wide a button is going to be.
You can literally say find usages, and that's it.
You know every place it's used, which is amazing.
So you know that it's not going to have
some hidden spooky effects that when you change
this one thing, it's going to alter the way
these other things are working.
You can do a refactoring.
If you do a series of steps where I extract this code
to this place, I move this here,
I know it's going to work the same way.
Whereas with CSS, I wouldn't feel that way.
Have you ever had a case where you did get a surprise?
Not in that way at all, no.
Those things aren't surprising.
So those are the pros.
I think those are the big things that I would be
focused on in evaluating that decision for a team.
It's like, okay, this is going to be amazing
for maintainability and bringing new team members
and changing the view code, which is awesome.
That's huge.
Especially for a web app.
Yeah, exactly.
Yeah, it's going to be quite nice for adding new things
in a really easy way and creating nice abstractions
in Elm code.
So that part is amazing.
The cons I would be considering would be
responsiveness is something that, well,
I've been talking to Matt about responsiveness
like working with Elm pages.
So when you talk about responsiveness, it's about
making it look good on all window sizes or tablets, mobile.
And if you change the window size, then things get
rearranged automatically.
That is something that Elm UI does not do on its own.
Does it?
It does.
But the way it does it is it's just,
the recommendation is have a flag that passes in
the initial window size and then have a subscription
to listen to a resize event in the window.
And then store the window size in your model
and pass that around any places that need to be responsive.
That certainly works.
But it's not as smooth as media queries,
although it does solve a lot of problems, I think.
I mean, I've seen very nice responsive designs built with that.
And you can definitely do nice things with it.
For me, the problem is if you're pre rendering your pages,
then you don't have access to the user's initial window size
at the time that you're pre rendering your entire site.
Because you just pre render everything to HTML files.
And then you just serve up static HTML files.
Go listen to episode one about Elm pages if you want to know
how to do that.
That's right.
Media queries play a lot nicer than responsiveness
that's in pure Elm code because it doesn't require
a JavaScript runtime in order to display correctly.
Yeah, it doesn't slow down your page.
And I wouldn't say that speed is such a problem.
It's just that you don't need to wait for the JavaScript
to load for the app to be hydrated.
But for me, building static sites,
I find it to be quite important.
And I know it's on Matt's radar,
and it's something that we've been talking about.
Is there a possible nice design that could support that?
So it's possible that there might be support for that.
And it's possible that you don't care about that at all.
If you're building a big SaaS product,
then maybe you don't even pre render your pages
and you don't care.
I also tend to prefer just saying,
okay, here's this view,
and I want the width to be whatever.
I want it to fill a portion of this size
if it's on a larger device.
And if it's on mobile,
then I want it to fill the full width of the page.
Or you want to display some other text, for instance.
And I tend to not want to pass around something
from my model to do that.
Again, maybe that's being finicky,
and that's just my own personal preference.
So you might totally disagree and say,
I really don't care about that,
and that works fine for me.
That's just my own personal thing.
And I find that one of the hardest things to do
in order to make a site look really professional
is making it responsive.
Making things responsive with Tailwind CSS
is a really nice experience from what I've worked with.
So the way that LMI does it is using a device type
or device class information,
which is stored in the model,
and then you have to pass it around
to every child element
until you don't need to pass it to any children anymore.
Yeah, I mean, that's one helper it gives you.
The device is just like a custom type
for whatever, like mobile, tablet, browser,
whatever it is.
You could build your own.
You could pass it around.
You could pass it as a Boolean, like isMobile,
or whatever.
It's totally up to you.
But ultimately, you have to pass state,
and you use pure Elm to say,
if I'm on mobile, then render it like this,
then include this attribute
or use this value for this attribute,
else do this.
I actually quite like that design.
I actually, with LMI,
the first time a few years ago,
I actually copied that to my work project,
which uses Elm CSS,
but we still use that version.
Because the really nice part I found was,
when you want to display different things,
like I want to display this text when I'm on desktop,
and this text if I'm on mobile.
What I see people do in CSS is display both.
Well, have both in the HTML tree,
and then have a display none
in one media query case,
and display in the other one.
And you switch depending on the device that you're on.
So I found that to be much simpler.
So I really like that idea.
There are also a few other things
that I found really easy to use.
Oh yeah, definitely.
Yeah, right, because you can sort of
put the appropriate parent child relationship
for the display flex
and the flex direction and all that.
Yeah, you preset that it's going to be
in column or in a row,
and it reads better, I think, also.
It doesn't read div class something,
which doesn't give you much information.
It just tells you what it does,
which I think is what LMUI's philosophy is about.
You explain what it should look like,
not what it should represent,
which is, I don't know if it's a good idea design wise,
but for me it worked well.
No, I think that makes a lot of sense.
I think it's, LMUI is very declarative, right?
And of course that's a very positive thing.
Yeah, and I think what you're talking about
through pure LMUI stuff,
obviously that philosophy has a lot of advantages,
and it's a matter of personal preference
as much as anything, right?
To me it sometimes feels more declarative
to say whatever, if a view is going to be displaying
in column or row,
if I say, like in Tailwind CSS,
like if I say whatever it is,
like lg colon flex dash row,
greater than large device,
then it's flex row,
and otherwise it's flex column.
To me that feels more declarative
to just say, this is the rule for displaying this,
rather than a stateful thing where I check
what is the state of this window.
That's my personal preference,
but if you're doing things like you're talking about
where you're showing different text or things like that,
based on the window size,
then it's a lot more elegant to do that
with personal preference as much as anything.
When it comes to pre rendered sites,
then it really becomes a pain point.
But if you don't have a pre rendered site,
and it works for your taste to check something in your model
to see how to render something responsively,
then that's great.
Then it might be a really good fit for you.
Those are really my own personal experiences with it
based on the types of problems that I work on
and the ways that I think about things.
But for a lot of people, I don't think that is a problem.
So don't let that stop you.
You're the only one who talks about that as far as I know.
I mean, I spend a lot of time thinking about
making the hydration of a static site really nice
when I'm working on Elm pages.
So I'm not necessarily the best representation
of a typical Elm user there.
I think other cons...
Did we talk about integrating it into teams?
We talked about the ease of refactoring
and the ability to create nice abstractions and stuff.
So I think overall, it's a very strong choice.
I think it's worth just understanding the philosophy of Elm UI.
And if you find yourself wanting to do
very nuanced, detailed CSS tricks all over the place,
then it may be that you feel like Elm UI gets in the way of that
because it creates a simpler abstraction
that doesn't expose every detailed thing that CSS gives you.
And it gives you escape patches to do that,
so you can do whatever you want to for the most part.
But I think it's just worth understanding the philosophy
more than anything to consider
whether it's the right fit for your team.
And create nice abstractions so it's easier to create new code.
It's unbeatable. It's amazing.
Yeah. Do you actually know of people who tried out Elm
because of Elm UI?
I know it's a big name in the Elm community.
People say,
Oh, if you try out Elm, try out Elm UI, it's amazing.
But do you know people who actually went
and tried Elm because of Elm UI?
I actually have a coaching client
that initially had me come in and help them
because they wanted to build their SaaS product using Elm UI.
That was sort of the main thing.
They wanted to use Elm UI and Elm GraphQL.
And they've told me that the experience
of maintaining a complex SaaS product
that's the core of their business
has been absurdly easy using those two things.
So infrequently that it's laughable.
Okay, awesome.
So you need a different mindset sometimes
when you're working with Elm UI.
For instance, the one thing that comes to mind
which I haven't had the chance to play with
is for instance, menus.
So menus, they appear above other elements in Elm UI.
Whereas in CSS, you would use a z index.
So you apply an attribute which is display above.
Is that?
Okay, good.
I remember things from two years ago.
Yeah, I think there's in front and behind content.
And so like, for example, if you wanted to display a modal,
then in front gives you an attribute
that lets you put an element in front of another element.
And so you could take like the very uppermost parent
of your entire view, of your entire page.
And you could, so let's say that your entire page
is like a column.
You could say like element.column
and that would be your whole page, right?
And then the child in that column would be like your nav bar.
And that would be like a row.
That child would be a row element
which has its own children laid out, however it's laid out.
And then the next thing in the top level column of your page
would be the body of the page.
And then the last thing would be the footer, let's say.
And that might be a row as well.
So that very topmost container,
that's how you would display a modal in front of your main view.
So you say element.column
and then you give a list of attributes
and then you give a list of children.
The list of attributes,
if you wanted to be displaying a modal,
then that list of attributes would include element.infront
and then you'd give the modal view to that function.
And now you're displaying,
which it's a little hard to wrap your head around at first,
but you're displaying a modal in front of your main view.
What kind of problems did you run into
when working with LMI?
Things where you need to think differently,
just like that case of in front and behind or below?
I think the thing that is probably most difficult
to wrap your head around
is the way that wrapping works.
So maybe, no pun intended there, but...
You intended it.
You scammer.
Secretly, I intended it.
I wanted to say this joke for years.
Now is my chance.
Yeah, so essentially,
the way that wrapping works is you have...
Do you mean about text wrapping?
Yeah, text wrapping...
Like if you wanted to do a heading,
like a column that's got three top level elements
of the nav bar, the body, the footer.
Inside of the body,
the first thing we want to have there would be a title,
like a heading.
Then the way you would do that is,
let's say you can do what's called an EL, like an element.
And that would be...
It's not like a layout container
that has multiple children, like a row or a column.
There's a style to it.
It's kind of like a DOM node.
Like span or an A or a div.
In a way.
It doesn't have children, so it's...
EL does have children.
Well, it has one child.
What I meant to say is it doesn't have multiple children.
So it's like a container for a single element,
not a bigger container.
Otherwise, you need row or column.
That's an interesting mental model.
You could think of it as...
I believe you could just define L yourself as EL, that is.
As just passing a single element to a row.
Because it doesn't matter if you're displaying it
as a row or a column if there's one element.
In practice, the CSS under the hood
might be a little different,
but it's effectively going to be displayed the same way.
You just do element.EL
in your main body area there.
You say, okay, I want to...
There are a lot of things that are going to work really nicely.
Let's say that you just have a title that says,
Hello, it's a nice short title.
Then you're not going to run into any text wrapping issues.
Then maybe you're going to want to center it.
That's going to work in a very intuitive way.
Way more intuitive than you're used to
because you're just going to say,
you're going to do element.EL
and then it takes the child,
which would be element.text of Hello.
The element attributes,
you're just going to say element.centerX.
Now it's going to be centered.
It's going to be centered horizontally.
You can also use the heading attributes in this case.
Or is it different?
You can do element.region.heading.
For accessibility purposes,
there's this module element.region.
That gives you a way to use semantic HTML.
But semantic HTML is not used for styling in Elm UI.
It's used for accessibility purposes.
It's a best practice,
like Lighthouse will complain
if you don't have something marked as main
if you have navbar and things like that.
You can set those types of things with element.region.
But otherwise, listeners may notice
from our conversation that we've been talking about
element.row, element.column, element.EL,
but we haven't been talking about H1, H2, article, span.
It's a smaller palette of functions
because you express layout with one thing
with element.region.
With that module, it gives you helpers
for saying this is a heading,
this is the main element.
We can center our header very intuitively.
We can add element.region to add a heading
with some semantic UI,
but that's not going to come with any built in style.
Like in vanilla HTML, if you say H1 or H2,
they come with built in styles.
With Elm UI, they don't.
because you need to pass an argument
which is a number or an integer,
it won't be big as just like when you do H1.
What makes it big is when you say
You add that attribute and it doesn't care
what its region is.
It's just a possibility.
All of those things, there are a few things to learn,
but there's not much of a learning curve.
They're very intuitive and it's like a small set of concepts.
But then instead of having our heading say hello,
if we wanted to say a very long message,
maybe on a small device,
suddenly our heading isn't wrapping.
Oh no.
It's not going to wrap.
If you use element.el,
by default, it's not going to wrap the contents of it.
But if you put it in an element.paragraph,
it's going to wrap.
That's one of the concepts in Elm UI
that takes a little getting used to,
but once you get used to it,
you see that something isn't wrapping.
You wrap it in an element.paragraph.
I know that that's something that Matt has a few ideas
that the model might be more intuitive for that,
but it's not like a problem.
It's just that it doesn't necessarily do the thing
you would intuitively think it's going to do
the first time around.
Yeah, gotcha.
So that's wrapping,
and that's one of the few things
that's a little bit counterintuitive sometimes.
So there are different modules to set the attributes,
unlike in Elm HTML where you have HTML.attributes.
You have elements.background,
that border, events,
font, inputs, and region.
And I kind of like that
just because when you have that list of attributes,
I always prepend those with border.solid,
border.width1 or whatever,
and it allows me to group things visually,
like border, border, border, events, border.
should be next to the border because they're grouped.
And I always find that a bit irritating in CSS.
When I have a CSS class and I set the properties,
I don't know in which order I'm supposed to have them.
Not that it matters, but just team wise,
like how do you group them together?
So I know that at my company,
we had actually, because it was annoying we disabled it,
we had an auto formatter that reordered those
to be consistent, which I really like.
I like that kind of thing, just like Elm formats.
But yeah, if you don't have that,
I don't know which order things should be.
Like do you have the position first,
then the font siding?
I don't know.
Just with these names,
how do you get to group those together?
It is nice.
I think that one of the reasons why that isn't the case
in the Elm HTML package,
I mean, besides just it's a different package,
so maybe it wasn't a different design vision or whatever.
But if you imagine doing that with HTML attributes,
there are so many,
and they can be used to do so many different types of things.
Organize those concepts into like 10 different groups.
It would be hard to do that precisely.
But with Elm UI, there really is like a very nice toolkit
of concepts to pull from.
Yeah, Elm HTML is just not opinionated.
So it aims to be able to do all the things
that you can do with an HTML and CSS,
not necessarily CSS.
But because Elm UI is a fresh start,
it can be a bit more opinionated,
and it does it well.
One other thing that maybe might be surprising
coming to Elm UI is there are some opinions around sizing
that a lot of people are used to using EM and REM
sizing in CSS.
And Elm UI has a lot of functions where you say like...
You just pass it to an integer,
and it's expected to be a number of pixels,
which I find weird.
I was going to ask that.
That's part of the vision.
So just to give a quick example,
you could say like element.width
of the particular element,
and it takes an int,
and it's going to set the width in pixels.
You can do element.fillPortion,
and that's going to be,
if you give three different elements
a portion of one each,
then each of them will get one third of the width.
Yeah, so that's how you do percentages in a way.
Of the parent size.
That's right. Yep.
And then you can just distribute it.
But yeah, when you say element.width,
it takes an int which represents pixels,
and that's a little counterintuitive at first.
I know that the first time I encountered that,
I was used to using things like EM
for responsive font sizes and things like that.
But the rationale behind it, I believe,
is just sort of an opinion that,
I don't know, if somebody's on a 4K display,
it's going to look smaller
than if it's on an iPhone.
But that's what you want it to look like.
You're on a larger screen with more pixels,
but it's okay for it to look smaller,
and then you fit more things in,
and that's okay.
Just use pixels.
Is that what you're saying?
I believe those are going to be proportionate
to the actual pixels,
like to the actual display.
Do you want to check that?
If he's wrong, edit this out.
I'm trying to protect you, Dillon.
m is relative to the font size
of its direct or nearest parent.
You're right.
Clearly, my mental model around m and rem
is rusty and inaccurate
because I have been so spoiled by Elm UI.
But essentially, I guess it's,
I mean, it's one of those things,
like many things in Elm UI,
that it's trying to create
a cleaner mental model
that doesn't have as many special cases and rules
that you have to think about,
and probably will have to look up
something on Stack Overflow to explain it
and use it,
because they're kind of confusing concepts.
So ems are relative to the font size
of its direct or nearest parent,
and rem is relative to the root font size.
And so I guess the idea is that
sometimes people use em or rem sizing
to set all their font sizes
and they'll set the font size in the body
based on a media query.
So if you're on an iPhone or a 4K monitor,
then there will be a media query
in a single point that sets the main body font size.
So that complexity is just,
I mean, it seems pretty sensible,
even more so when we look at the actual definition,
that, I mean, like, when you're using em or rem,
you can see what it does.
My learning has been always use rem.
And then I read some articles that say always use em.
And yeah, well, opinions diverge on this, clearly.
Clearly one way is better than the other,
but not everyone agrees on which one.
So one thing that I noticed is that
it is quite easy to reuse elements
so have you had the chance to create style guides
or design systems with Elm UI?
Is that something that people tend to do more often with it
or no relation?
I know that there was a talk at Elm Europe
where there was a project that's like storybook
in the React ecosystem, but using Elm UI
as a way of presenting different layout components.
And I was doing some projects where they...
Is that Elm UI Explorer, maybe?
I think it was Elm UI Explorer,
which actually does not about Elm UI I learned after that.
Oh, okay. I wasn't fully clear.
It's a storybook like project.
Yeah, I think it is easier to encapsulate nice interfaces
for displaying different things,
design systems and that sort of thing as a result.
But people are starting to come out
with more sort of community tools
and sort of like, I know some people are working
on like recipe sites for it and that sort of thing.
Yeah, we saw that.
Elm UI Storybook, for instance, I think by Lucas Pair.
We'll correct myself if that was wrong.
Yeah, we'll have to find a few resources like that
but there's a pretty large user base
and a very active group of people discussing these things
in the Elm UI channel in Slack.
So it's definitely worth asking for opinions on things
and how to...
Or help, by the way.
...tile drop downs.
Yeah, getting help, getting clarity on a mental model,
things like that.
But I think regarding creating nice abstractions for things,
with Elm UI, it's very easy to refactor things
into nice abstractions.
I would just give a public service announcement
to remind people to actually do that step
to abstract things nicely because it's tempting,
like everything in Elm UI is inline.
It's not something you write in like a style sheet
and you have to have a class for things.
So it doesn't force you to abstract things away
but abstracting things when you do is awesome.
But I would encourage people to actually do that step.
So I've worked with people who were very good at CSS
and when they were on a project with Elm CSS,
they had a lot more trouble finding the code associated
with the classes they saw
because the classes are hashed
You can't look for button dash item in your source code
and find the file that contains that class.
And you have the same problem with Elm UI.
When you need to change an element that you see on a page,
how do you go from visually seeing that item on the page
to finding it in the project in your source code?
So there is one tool at your disposal called element.explain
and it's quite handy.
And what you do is you set element.explain,
you have to pass it do for internal purposes
but you get used to it.
It's not a big deal.
So as not to forget to remove it.
So you don't forget to remove it.
So you're not going to compile it
with the optimize flag on for production.
And then it gives you a nice little highlight
around the area you're looking at.
So if you're finding that something is like wrapping strangely
I use that pretty often.
And it's a very nice way to debug.
Beyond that, as you say,
even more so than like with Elm CSS,
there's not even a direct mapping to CSS
like there is with Elm CSS.
Elm CSS is an abstraction
but it's a pretty direct one on CSS
and Elm UI is a much more high level abstraction.
And so there's not a direct mapping
and so the going in your browser's developer tools
is not going to give you that much help.
So what usually ends up happening is
you just kind of trace back
where things are coming from.
Like I was saying earlier,
why is the padding like this on this element?
Well, what's rendering this element?
If you can find the parent,
that's all there is to it.
It's not going to cascade from anything.
It's not going to get overridden by bang important.
It's not going to be,
is it coming from a margin or from this?
And is part of it coming from margin?
Is part of it coming from the parent's padding?
It just comes from one place.
It's the parent's padding.
It's the only place it could be.
So it's much more traceable.
Okay, but yeah, if you need to find one element
or then you have to go through the whole code.
You can be a bit smarter than that, but obviously,
but that's kind of what it pulls down to.
It's true.
I would say that overall,
my experience figuring out
where a certain view issue is coming from
has been easier in Elm UI than it is with CSS.
For what it's worth, yeah.
No surprise here.
Is there anything that people can use as resources
getting started with Elm UI?
Yeah, definitely.
So first of all, I would mention Matt's conference talk
at Elm Europe 2017.
I was in the audience
and I didn't realize how good it was at that time.
I watched it again a few years later
and I thought, man, that was actually genius.
I was stunned by that talk initially.
It inspired me in my approach to API design quite a bit,
just that vision of that clarity of the API
and the design goals
and just rethinking things from the ground up,
which really is very much the Elm approach.
Yes, definitely.
It feels like if you love the philosophy behind Elm,
you're probably going to love the philosophy behind Elm UI.
It's incredibly insightful.
Yeah, I agree.
Even though that talk is about style elements,
the older incantation of it,
or the older incarnation of Elm UI,
CSS is more like an incantation.
Elm UI is more like an incarnation.
But it is still relevant in terms of the design philosophy.
But Matt's given a few talks about Elm UI
and I think they're all worthwhile to watch.
And Richard Feldman gave,
even though he's the author of Elm CSS,
he gave a really cool talk about Elm UI
back when it was still style elements as well.
I thought that was a nice talk
that gives some motivation of some of the ideas
and why it's a nice tool.
I know Richard is definitely a fan of Elm UI as well,
but he's got some great resources on that.
I think that's it for this channel on the Elm Slack.
Definitely go there if you want to know more
about what's going on and if you want to ask for help.
I think that is probably one of the most visited channels
in the Elm Slack that is not general,
or general purpose, I mean.
Sometimes it feels like it's even more active
than the general channel.
Actually, since I don't use Elm UI,
it's just too many people talking over there
for things that I'm not that interested in.
Yeah, there are almost 1800 people over there.
That's a lot.
And if you have a question,
there's a very good chance
that you'll get a good answer.
So it's definitely a good idea
to jump in that channel as you're getting started.
Yeah. Other resources?
Go to
too, that's a great way to get started.
And there's some examples in the examples folder.
Yeah, and take the one from MD Griffith.
Oh yes, that's right.
I think that's a pretty good summary.
Yeah. Actually, there's no other Elm UI.
There used to be.
There used to be, but...
pdog design, but I think it didn't get moved over
to Elm 19 maybe.
Okay, well, then if you find Elm UI, use Elm UI.
No confusion there.
Now there is thanks to us,
but that's okay.
Thanks to me.
You're welcome, community.
Well, thanks for the discussion,
Jeroen, I'll talk to you next time.
See you next time.