git.iko.soy/typeable/elm-ui
on master help sign in
updated font adjustment experiment
commitd94a2b589d3ccb4081786a1ab0bf1fd68e594123 authorMatthew Griffith <mdg.griffith@gmail.com> dateSat 22 Sep 2018, 08:47 (8 years ago) parentef9dcc3
3 files changed+601−19
experiments/font-adjustment-updated/FontAdjustment.elm+545 experiments/font-adjustment-updated/elm.json+25 experiments/font-adjustment/FontAdjustment.elm+31−19
experiments/font-adjustment-updated/FontAdjustment.elmnew file+545
@@ -0,0 +1,545 @@
1+module Main exposing (main)
2+
3+{-| Line Height as its specified through CSS doesn't make a whole lot of sense typographically.
4+
5+We also run into issues with sizing a font. The font size generally refers to the full type size (from the top of ascendors to the bottom of descenders)
6+
7+However, sometimes we might want to size things from the top of the Capital to the baseline.
8+
9+Or from the top of the x-height to the baseline.
10+
11+The main place this shows up is for dropped capitals, and for text on buttons.
12+
13+-}
14+
15+import Browser
16+import Element exposing (..)
17+import Element.Background as Background
18+import Element.Border as Border
19+import Element.Font as Font
20+import Element.Input as Input
21+import Element.Lazy
22+import Html
23+import Html.Attributes
24+
25+
26+type alias FontAdjustment =
27+ { lineHeight : Float
28+ , capital : Line
29+ , lowercase : Line
30+ , baseline : Line
31+ , descender : Line
32+ }
33+
34+
35+type alias Line =
36+ Float
37+
38+
39+type Msg
40+ = UpdateAdjustment FontAdjustment
41+
42+
43+edges =
44+ { top = 0
45+ , right = 0
46+ , bottom = 0
47+ , left = 0
48+ }
49+
50+
51+garamond =
52+ let
53+ default =
54+ { capital = 1.09
55+ , lowercase = 0.81
56+ , baseline = 0.385
57+ , descender = 0.095
58+ , lineHeight = 1.5
59+ }
60+ in
61+ { adjustment =
62+ default
63+ , converted =
64+ convertAdjustment default
65+ , font =
66+ { url = Just "https://fonts.googleapis.com/css?family=EB+Garamond"
67+ , name = "EB Garamond"
68+ , adjustment =
69+ { capital = default.capital
70+ , lowercase = default.lowercase
71+ , baseline = default.baseline
72+ , descender = default.descender
73+ }
74+ }
75+ }
76+
77+
78+catamaran =
79+ let
80+ default =
81+ { capital = 1.15
82+ , lowercase = 0.96
83+ , baseline = 0.465
84+ , descender = 0.245
85+ , lineHeight = 1.5
86+ }
87+ in
88+ { adjustment =
89+ default
90+ , converted =
91+ convertAdjustment default
92+ , font =
93+ { url = Just "https://fonts.googleapis.com/css?family=Catamaran"
94+ , name = "Catamaran"
95+ , adjustment =
96+ { capital = default.capital
97+ , lowercase = default.lowercase
98+ , baseline = default.baseline
99+ , descender = default.descender
100+ }
101+ }
102+ }
103+
104+
105+poiret =
106+ let
107+ default =
108+ { capital = 1.12
109+ , lowercase = 0.82
110+ , baseline = 0.365
111+ , descender = 0.18
112+ , lineHeight = 1.5
113+ }
114+ in
115+ { adjustment =
116+ default
117+ , converted =
118+ convertAdjustment default
119+ , font =
120+ { url = Just "https://fonts.googleapis.com/css?family=Poiret+One"
121+ , name = "Poiret One"
122+ , adjustment =
123+ { capital = default.capital
124+ , lowercase = default.lowercase
125+ , baseline = default.baseline
126+ , descender = default.descender
127+ }
128+ }
129+ }
130+
131+
132+roboto =
133+ let
134+ default =
135+ { capital = 1.115
136+ , lowercase = 0.93
137+ , baseline = 0.4
138+ , descender = 0.19
139+ , lineHeight = 1.5
140+ }
141+ in
142+ { adjustment =
143+ default
144+ , converted =
145+ convertAdjustment default
146+ , font =
147+ { url = Just "https://fonts.googleapis.com/css?family=Roboto"
148+ , name = "Roboto"
149+ , adjustment =
150+ { capital = default.capital
151+ , lowercase = default.lowercase
152+ , baseline = default.baseline
153+ , descender = default.descender
154+ }
155+ }
156+ }
157+
158+
159+init =
160+ -- catamaran
161+ garamond
162+
163+
164+
165+-- poiret
166+-- roboto
167+
168+
169+update msg model =
170+ case msg of
171+ UpdateAdjustment adj ->
172+ let
173+ font =
174+ model.font
175+ in
176+ { model
177+ | adjustment = adj
178+ , converted = convertAdjustment adj
179+ , font =
180+ { font
181+ | adjustment =
182+ { capital = adj.capital
183+ , lowercase = adj.lowercase
184+ , baseline = adj.baseline
185+ , descender = adj.descender
186+ }
187+ }
188+ }
189+
190+
191+main =
192+ Browser.sandbox
193+ { init = init
194+ , update = update
195+ , view = view
196+ }
197+
198+
199+view model =
200+ Element.layout
201+ [ above (html (Html.node "style" [] [ Html.text """
202+.lh-15 .t {
203+ line-height: 1.5;
204+}
205+
206+.lh-norm .t {
207+ line-height: normal;
208+}
209+
210+ """ ]))
211+ , Background.color (rgba 1 1 1 1)
212+ , padding 100
213+ , Font.color (rgba 0 0 0 1)
214+ , Font.family
215+ [ -- Font.external
216+ -- { url = "https://fonts.googleapis.com/css?family=EB+Garamond"
217+ -- , name = "EB Garamond"
218+ -- }
219+ -- Font.external
220+ -- { url = "https://fonts.googleapis.com/css?family=Catamaran"
221+ -- , name = "Catamaran"
222+ -- }
223+ Font.with
224+ model.font
225+ , Font.sansSerif
226+ ]
227+ ]
228+ <|
229+ column [ width fill, height fill, spacing 128 ]
230+ [ adjustor 120 model.adjustment
231+ , adjusted 120 model.converted
232+ ]
233+
234+
235+style name val =
236+ htmlAttribute (Html.Attributes.style name val)
237+
238+
239+class name =
240+ htmlAttribute (Html.Attributes.class name)
241+
242+
243+charcoal =
244+ rgb 0.7 0.7 0.7
245+
246+
247+adjustor size adjustment =
248+ let
249+ labels =
250+ [ viewAdjustment "Type Height" adjustment.capital size 180 adjustment.lineHeight (\capital -> { adjustment | capital = capital })
251+ , viewAdjustment "Lowercase Height" adjustment.lowercase size 60 adjustment.lineHeight (\lowercase -> { adjustment | lowercase = lowercase })
252+ , viewAdjustment "Baseline" adjustment.baseline size 120 adjustment.lineHeight (\baseline -> { adjustment | baseline = baseline })
253+ , viewAdjustment "Descender" adjustment.descender size 0 adjustment.lineHeight (\descender -> { adjustment | descender = descender })
254+ ]
255+ in
256+ el
257+ ([ centerX
258+ , centerY
259+ , Background.color (rgb 0 0.8 0.9)
260+ , class "lh-15"
261+ , style "line-height" (String.fromFloat adjustment.lineHeight)
262+ , onRight
263+ (el
264+ [ centerY
265+ , width (px 40)
266+
267+ -- , height (px (round (toFloat size * (1 / 1.5))))
268+ , height (px size)
269+ , Background.color (rgb 0.9 0.8 0)
270+ ]
271+ none
272+ )
273+ , Font.size size
274+ ]
275+ ++ labels
276+ )
277+ (text "Typography")
278+
279+
280+adjusted size adjustment =
281+ column
282+ [ spacing 48
283+ , centerX
284+ , centerY
285+ ]
286+ [ el [ Font.size 32 ] (text "Standard Defaults in CSS")
287+ , row
288+ [ spacing 32
289+ , Font.size 120
290+ ]
291+ [ el
292+ [ Background.color (rgb 0 0.8 0.9)
293+ , style "line-height" "normal"
294+ , class "lh-norm"
295+ , above (el [ Font.size 12 ] (text "line-height: normal"))
296+ ]
297+ (text "Typography")
298+ , el
299+ [ Background.color (rgb 0 0.8 0.9)
300+ , style "line-height" "1"
301+ , above (el [ Font.size 12 ] (text "line-height: 1"))
302+ ]
303+ (text "Typography")
304+ ]
305+ , el
306+ [ Font.size 32 ]
307+ (text "New Adjustments in Els")
308+ , row
309+ [ Font.size 120
310+ , padding 80
311+ ]
312+ [ --corrected adjustment.full "corrected"
313+ -- , corrected adjustment.capital "corrected capital"
314+ el
315+ [ Font.sizeByCapital
316+ , Background.color (rgb 0 0.8 0.9)
317+ , above (el [ Font.size 12, moveUp 6 ] (text "corrected capital"))
318+ , onLeft <|
319+ el
320+ [ centerY
321+ , width (px 40)
322+ , height (px 120)
323+ , Background.color (rgb 0.9 0.8 0)
324+ ]
325+ none
326+ ]
327+ (text "Typography")
328+ ]
329+ , row [ spacing 120 ]
330+ [ paragraph
331+ [ Font.size 25
332+ , spacing 5
333+ , width (px 200)
334+ , Background.color
335+ (rgb 0 0.8 0.9)
336+ , above (el [ Font.size 32, moveUp 32 ] (text "Normal Paragraphs"))
337+ ]
338+ [ el [ Font.size 55, alignLeft, Background.color (rgb 0.9 0.8 0) ] (text "L")
339+ , text "orem Ipsum is simply dummy text of the printing and typesetting industry."
340+ ]
341+ , paragraph
342+ [ Font.size 45
343+ , spacing 10
344+ , width (px 600)
345+ , inFront
346+ (el
347+ [ width (px 100)
348+ , height (px 5)
349+ , moveDown 45
350+ , alignRight
351+ , Background.color (rgba 0.9 0.8 0.2 0.5)
352+ ]
353+ none
354+ )
355+ , inFront
356+ (el
357+ [ width (px 100)
358+ , height (px 45)
359+ , alignRight
360+ , Background.color (rgba 0 0 0 0.5)
361+ ]
362+ none
363+ )
364+ , Background.color
365+ (rgb 0 0.8 0.9)
366+ , above
367+ (el [ Font.size 32, moveUp 32 ] (text "Corrected Paragraphs"))
368+ ]
369+ [ el
370+ [ Font.size 100
371+ , alignLeft
372+ , Background.color (rgb 0.9 0.8 0)
373+ , Font.sizeByCapital
374+ ]
375+ (text "C")
376+ , text "ontrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32."
377+ ]
378+ ]
379+ ]
380+
381+
382+corrected converted label =
383+ el
384+ [ Background.color (rgb 0 0.8 0.9)
385+ , style "display" "block"
386+ , above (el [ Font.size 12, moveUp 6 ] (text label))
387+ , style "line-height" (String.fromFloat converted.height)
388+ , below
389+ (column [ Font.size 12, spacing 5, moveDown 10 ]
390+ [ text ("height: " ++ String.left 5 (String.fromFloat converted.height))
391+ , text ("vertical: " ++ String.left 5 (String.fromFloat converted.vertical))
392+ ]
393+ )
394+ ]
395+ (el
396+ [ style "display" "inline-block"
397+ , style "line-height" (String.fromFloat converted.height)
398+ , style "vertical-align" (String.fromFloat converted.vertical ++ "em")
399+ ]
400+ (text "Typography")
401+ )
402+
403+
404+convertAdjustment adjustment =
405+ let
406+ base =
407+ adjustment.lineHeight
408+
409+ normalDescender =
410+ (adjustment.lineHeight - 1)
411+ / 2
412+
413+ oldMiddle =
414+ adjustment.lineHeight / 2
415+
416+ newCapitalMiddle =
417+ ((ascender - newBaseline) / 2) + newBaseline
418+
419+ newFullMiddle =
420+ ((ascender - descender) / 2) + descender
421+
422+ lines =
423+ [ adjustment.capital
424+ , adjustment.baseline
425+ , adjustment.descender
426+ , adjustment.lowercase
427+ ]
428+
429+ ascender =
430+ Maybe.withDefault adjustment.capital (List.maximum lines)
431+
432+ descender =
433+ Maybe.withDefault adjustment.descender (List.minimum lines)
434+
435+ newBaseline =
436+ lines
437+ |> List.filter (\x -> x /= descender)
438+ |> List.minimum
439+ |> Maybe.withDefault adjustment.baseline
440+
441+ capitalVertical =
442+ (oldMiddle - newCapitalMiddle) * 2
443+
444+ fullVertical =
445+ (oldMiddle - newFullMiddle) * 2
446+ in
447+ { full =
448+ { vertical = fullVertical
449+ , height =
450+ (ascender - descender)
451+ - abs fullVertical
452+ }
453+ , capital =
454+ { vertical = capitalVertical
455+ , height = (ascender - newBaseline) - abs capitalVertical
456+ }
457+ }
458+
459+
460+viewAdjustment label adjustment size left lineHeight updateWith =
461+ let
462+ fullHeight =
463+ toFloat size * 1.5
464+ in
465+ onLeft
466+ (el
467+ [ moveLeft left
468+
469+ -- , moveUp (0.125 * toFloat size)
470+ , height (px (round (toFloat size * lineHeight)))
471+ ]
472+ <|
473+ Input.slider
474+ [ Font.size 24
475+ , Element.behindContent
476+ (Element.el
477+ [ Element.width (Element.px 1)
478+ , Element.height Element.fill
479+ , Element.centerY
480+ , Background.color charcoal
481+ , Border.rounded 2
482+ ]
483+ Element.none
484+ )
485+ , height (px (round fullHeight))
486+ , width (px 1)
487+ , spacing 0
488+ , Background.color charcoal
489+ , below (el [ centerX ] (text (String.fromFloat adjustment)))
490+ , onRight
491+ (el
492+ [ height (px 0)
493+ , width (px 800)
494+ , moveRight 10
495+ , alignBottom
496+ , moveUp (fullHeight * (adjustment / lineHeight))
497+ , Border.color (rgb 0 0 0)
498+ , Border.dashed
499+ , Border.widthEach
500+ { top = 1
501+ , right = 0
502+ , bottom = 0
503+ , left = 0
504+ }
505+ ]
506+ none
507+ )
508+ ]
509+ { label = Input.labelHidden "font adjustment"
510+ , max = lineHeight
511+ , min = 0
512+ , onChange =
513+ \x ->
514+ UpdateAdjustment
515+ (updateWith x)
516+ , step = Just 0.005
517+ , thumb =
518+ Input.thumb
519+ [ Element.width (Element.px 16)
520+ , Element.height (Element.px 16)
521+ , Border.rounded 8
522+ , Border.width 1
523+ , Border.color (Element.rgb 0.5 0.5 0.5)
524+ , Background.color (Element.rgb 1 1 1)
525+
526+ -- , onRight
527+ -- (el
528+ -- [ height (px 0)
529+ -- , width (px 1200)
530+ -- , moveDown 8
531+ -- , Border.color (rgb 0 0 0)
532+ -- , Border.dashed
533+ -- , Border.widthEach
534+ -- { top = 1
535+ -- , right = 0
536+ -- , bottom = 0
537+ -- , left = 0
538+ -- }
539+ -- ]
540+ -- none
541+ -- )
542+ ]
543+ , value = adjustment
544+ }
545+ )
experiments/font-adjustment-updated/elm.jsonnew file+25
@@ -0,0 +1,25 @@
1+{
2+ "type": "application",
3+ "source-directories": [
4+ ".",
5+ "../../src/"
6+ ],
7+ "elm-version": "0.19.0",
8+ "dependencies": {
9+ "direct": {
10+ "elm/browser": "1.0.0",
11+ "elm/core": "1.0.0",
12+ "elm/html": "1.0.0",
13+ "elm/json": "1.0.0",
14+ "elm/virtual-dom": "1.0.0"
15+ },
16+ "indirect": {
17+ "elm/time": "1.0.0",
18+ "elm/url": "1.0.0"
19+ }
20+ },
21+ "test-dependencies": {
22+ "direct": {},
23+ "indirect": {}
24+ }
25+}
experiments/font-adjustment/FontAdjustment.elm+31−19
@@ -40,7 +40,11 @@ type Msg
4040
4141
4242edges =
43− { top = 0, right = 0, bottom = 0, left = 0 }
43+ { top = 0
44+ , right = 0
45+ , bottom = 0
46+ , left = 0
47+ }
4448
4549
4650default =
@@ -158,26 +162,36 @@ adjustor size adjustment =
158162
159163
160164adjusted size adjustment =
161− row
162− [ centerX
165+ column
166+ [ spacing 48
167+ , centerX
163168 , centerY
164− , spacing 32
165− , Font.size 120
166169 ]
167− [ el
168− [ Background.color (rgb 0 0.8 0.9)
169− , style "line-height" "normal"
170− , above (el [ Font.size 12 ] (text "line-height: normal"))
170+ [ row
171+ [ spacing 32
172+ , Font.size 120
173+ , above (text "hi")
171174 ]
172− (text "Typography")
173− , el
174− [ Background.color (rgb 0 0.8 0.9)
175− , style "line-height" "1"
176− , above (el [ Font.size 12 ] (text "line-height: 1"))
175+ [ el
176+ [ Background.color (rgb 0 0.8 0.9)
177+ , style "line-height" "normal"
178+ , above (el [ Font.size 12 ] (text "line-height: normal"))
179+ ]
180+ (text "Typography")
181+ , el
182+ [ Background.color (rgb 0 0.8 0.9)
183+ , style "line-height" "1"
184+ , above (el [ Font.size 12 ] (text "line-height: 1"))
185+ ]
186+ (text "Typography")
187+ ]
188+ , row
189+ [ spacing 32
190+ , Font.size 120
191+ ]
192+ [ corrected adjustment.full "corrected"
193+ , corrected adjustment.capital "corrected capital"
177194 ]
178− (text "Typography")
179− , corrected adjustment.full "corrected"
180− , corrected adjustment.capital "corrected capital"
181195 , paragraph [ Font.size 25, spacing 5, width (px 200) ]
182196 [ el [ Font.size 55, alignLeft ] (text "L")
183197 , text "orem Ipsum is simply dummy text of the printing and typesetting industry."
@@ -244,8 +258,6 @@ convertAdjustment adjustment =
244258 |> List.minimum
245259 |> Maybe.withDefault adjustment.baseline
246260
247−
248−
249261 capitalVertical =
250262 (oldMiddle - newCapitalMiddle) * 2
251263