diff --git a/Nasal/canvas/gui/Config.nas b/Nasal/canvas/gui/Config.nas
index b8bdfe183..24f516a00 100644
--- a/Nasal/canvas/gui/Config.nas
+++ b/Nasal/canvas/gui/Config.nas
@@ -17,5 +17,10 @@ var Config = {
       return val;
 
     return default;
+  },
+  set: func(key, value)
+  {
+    me._cfg[key] = value;
+    return me;
   }
 };
diff --git a/Nasal/canvas/gui/Widget.nas b/Nasal/canvas/gui/Widget.nas
index e3a19b824..44f8c8b8a 100644
--- a/Nasal/canvas/gui/Widget.nas
+++ b/Nasal/canvas/gui/Widget.nas
@@ -61,7 +61,7 @@ gui.Widget = {
     me._size[1] = h;
 
     if( me._view != nil )
-      me._view.setSize(w, h);
+      me._view.setSize(me, w, h);
     return me;
   },
   # Set geometry of widget (usually used by layouting system)
diff --git a/Nasal/canvas/gui/styles/DefaultStyle.nas b/Nasal/canvas/gui/styles/DefaultStyle.nas
index 887997428..ec177e4a0 100644
--- a/Nasal/canvas/gui/styles/DefaultStyle.nas
+++ b/Nasal/canvas/gui/styles/DefaultStyle.nas
@@ -39,7 +39,7 @@ DefaultStyle.widgets.button = {
               .set("character-size", 14)
               .set("alignment", "center-baseline");
   },
-  setSize: func(w, h)
+  setSize: func(model, w, h)
   {
     me._bg.reset()
           .rect(3, 3, w - 6, h - 6, {"border-radius": 5});
@@ -108,7 +108,7 @@ DefaultStyle.widgets.label = {
   {
     me._root = parent.createChild("group", "label");
   },
-  setSize: func(w, h)
+  setSize: func(model, w, h)
   {
     if( me['_bg'] != nil )
       me._bg.reset().rect(0, 0, w, h);
@@ -116,22 +116,39 @@ DefaultStyle.widgets.label = {
       me._img.set("size[0]", w)
              .set("size[1]", h);
     if( me['_text'] != nil )
+    {
       # TODO different alignment
-      me._text.setTranslation(2, h / 2);
+      me._text.setTranslation(2, 2 + h / 2);
+      me._text.set(
+        "max-width",
+        model._cfg.get("wordWrap", 0) ? (w - 4) : 0
+      );
+    }
     return me;
   },
   setText: func(model, text)
   {
     if( text == nil or size(text) == 0 )
+    {
+      model.setHeightForWidthFunc(nil);
       return me._deleteElement('text');
+    }
 
     me._createElement("text", "text")
       .set("text", text)
       .set("fill", "black");
 
-    # TODO get real font metrics
-    model.setMinimumSize([size(text) * 5 + 4, 14]);
-    model.setSizeHint([size(text) * 5 + 14, 24]);
+    if( model._cfg.get("wordWrap", 0) )
+    {
+      var m = me;
+      model.setHeightForWidthFunc(func(w) m.heightForWidth(w));
+    }
+    else
+    {
+      # TODO get real font metrics
+      model.setMinimumSize([size(text) * 5 + 4, 14]);
+      model.setSizeHint([size(text) * 5 + 14, 24]);
+    }
 
     return me;
   },
@@ -155,9 +172,16 @@ DefaultStyle.widgets.label = {
     me._createElement("bg", "path")
       .set("fill", bg);
 
-    me.setSize(model._size[0], model._size[1]);
+    me.setSize(model, model._size[0], model._size[1]);
     return me;
   },
+  heightForWidth: func(w)
+  {
+    if( me['_text'] == nil )
+      return -1;
+
+    return math.max(14, me._text.heightForWidth(w - 4));
+  },
 # protected:
   _createElement: func(name, type)
   {
diff --git a/Nasal/canvas/gui/widgets/Label.nas b/Nasal/canvas/gui/widgets/Label.nas
index 47654d158..a648e1bec 100644
--- a/Nasal/canvas/gui/widgets/Label.nas
+++ b/Nasal/canvas/gui/widgets/Label.nas
@@ -1,10 +1,10 @@
 gui.widgets.Label = {
   new: func(parent, style, cfg)
   {
-    var cfg = Config.new(cfg);
     var m = gui.Widget.new(gui.widgets.Label);
+    m._cfg = Config.new(cfg);
     m._focus_policy = m.NoFocus;
-    m._setView( style.createWidget(parent, "label", cfg) );
+    m._setView( style.createWidget(parent, "label", m._cfg) );
 
     return m;
   },
diff --git a/Nasal/canvas/gui/widgets/ScrollArea.nas b/Nasal/canvas/gui/widgets/ScrollArea.nas
index 64528525c..99eea1457 100644
--- a/Nasal/canvas/gui/widgets/ScrollArea.nas
+++ b/Nasal/canvas/gui/widgets/ScrollArea.nas
@@ -179,8 +179,12 @@ gui.widgets.ScrollArea = {
       var min_size = me._layout.minimumSize();
       var max_size = me._layout.maximumSize();
       var size_hint = me._layout.sizeHint();
-      var w = math.min(max_size[0], math.max(math.max(min_size[0], size_hint[0]), me._size[0]));
-      var h = math.min(max_size[1], math.max(math.max(min_size[1], size_hint[1]), me._size[1]));
+      var w = math.min(max_size[0], math.max(size_hint[0], me._size[0]));
+      var h = math.max(
+              math.min(max_size[1], math.max(size_hint[1], me._size[1])),
+              me._layout.heightForWidth(w)
+            );
+
       me._layout.setGeometry([0, 0, w, h]);
 
       # Layout always has the origin at (0, 0)