Jump to content
lynkfs

Responsive Design

Recommended Posts

Responsive design in essence consists of 2 measures :

  1. style all components as best as possible depending on screen size (larger buttons on mobile, proportional font sizing etc)
  2. tweak the layout of forms so that it works best on any given screen size

1) Screen size dependent styling can be done in code and/or is done as other frameworks do by including media queries in the stylesheet. Media queries basically activate different parts of a stylesheet depending on the actual screen size. Smart doesn't implement this in its shipped stylesheets, but there is no reason it can't be done. Just a bit of work.

2) Tweaking the form layout in Smart is possible by

  • doing it in code depending on screensize and orientation - a bit of a pain really
  • using the Layout Manager
  • using some css grid framework or ui kit. For website development I've used the Frow framework quite a bit, but there are many others.
  • using anchors and the CSS grid (which is basically the topic of this post)

The new anchors are fantastic, but don't really help in responsive design. Browser window resizing doesn't proportionally resize anchored components. That is unless they are dimensioned depending on screen size beforehand :

  var W3Panel0 : TW3Panel := TW3Panel.Create(self);
  W3Panel0.Left   := trunc(browserapi.window.innerWidth*0.05);
  W3Panel0.Top    := trunc(browserapi.window.innerHeight*0.05);
  W3Panel0.Width  := trunc(browserapi.window.innerWidth*0.9);
  W3Panel0.Height := trunc(browserapi.window.innerHeight*0.10);
  W3Panel0.Anchors := [akLeft, akRight, akTop];
  //
  var W3Panel1 : TW3Panel := TW3Panel.Create(self);
  W3Panel1.Left   := trunc(browserapi.window.innerWidth*0.05);
  W3Panel1.Top    := trunc(browserapi.window.innerHeight*0.15);
  W3Panel1.Width  := trunc(browserapi.window.innerWidth*0.9);
  W3Panel1.Height := trunc(browserapi.window.innerHeight*0.70);
  W3Panel1.Anchors := [akLeft, akRight, akTop, akBottom];
  W3Panel1.NativeScrolling := true;
  //
  var W3Panel2 : TW3Panel := TW3Panel.Create(self);
  W3Panel2.Left   := trunc(browserapi.window.innerWidth*0.05);
  W3Panel2.Top    := trunc(browserapi.window.innerHeight*0.85);
  W3Panel2.Width  := trunc(browserapi.window.innerWidth*0.9);
  W3Panel2.Height := trunc(browserapi.window.innerHeight*0.10);
  W3Panel2.Anchors := [akLeft, akRight, akBottom];

As an example the code above produces a header (always on top), a footer (always on the bottom) and a scrollable body inbetween with some proportional margins.

Screenshot_2019-04-28-15-04-46-78.png

The good thing is it works well on all screen sizes, and even on orientation changes, without having to code anything else.

 

Instead of using a grid system with media queries, or doing it in code, it is also possible to use the built-in css grid to get a responsive design. Much easier, see article. If I just plonk the css and html of the first example in that article into the structure above, this is how it ends up looking :

Demo

Resize browser window to see this in effect (or see it in the responsinator)

Not the end-all of all possible responsive design options, but it may fit the bill sometimes.

Note  : the built-in chrome browser doesn't understand the css grid, so execute from file or server.

 

Share this post


Link to post
Share on other sites

css here, project here

Nothing fancy, just used the css and html of the example as-is. Could be simplified 

The CSS grid is implemented in these lines in the stylesheet :

  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  grid-gap: 1rem;

"give me as many columns as fit on the available width where each column is at least 320px wide, or maximum 1 fraction"

The CSS grid is pretty powerful and is available in all modern browsers, including mobile. Time permitting, I'll dig into it a bit deeper.

 

 

Share this post


Link to post
Share on other sites

Oh yes...  this grid design very good looking on my phone also!

Thank you so much!

 

Somebody can write how is possible to catch a separated click event for examle just for the center image  in this project?

 

// I talked about this section in the innerHTML:
   <li>
        <figure>
          <!-- Photo by Drew Farwell on Unsplash -->
          <img src="https://images.unsplash.com/photo-1513309914637-65c20a5962e1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3450&q=80" alt="Several friends doing a toast">
          <figcaption><h3>Drake Equation</h3></figcaption>
        </figure>
        <p>
          Another world citizens of distant epochs from which we spring descended from astronomers Orion''s sword shores of the cosmic ocean.
        </p>
      </li>

Share this post


Link to post
Share on other sites

If this shortcut approach (providing html code directly in smart code) works for you, then adding event handlers has to be done in html too.

Just add an ID to the img element so you can find the image element in the dom, and add an eventlistener to it :
 

          <!-- Photo by Drew Farwell on Unsplash -->
          <img id="mypic01" src="https://images.unsplash.com/photo-1513309914637-65c20a5962e1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3450&q=80" alt="Several friends doing a toast">
          <figcaption><h3>Drake Equation</h3></figcaption>
etc...

  browserapi.document.getElementById("mypic01").addEventListener("click", procedure(event:variant)
  begin
    writeln('clicked');
  end);

 

Note that once you start mixing direct dom manipulation with standard rtl processing, you're mixing different worlds. Things might look the same but not necessarily have the same effect. The onclick event handler above is not the same as the standard smart OnClick handling etc.

See what works for you. 

Share this post


Link to post
Share on other sites

@lynkfs

You can do your first example also by using a div with big margins. That takes care of the outer edges. Inside the div you then add the three controls. Set the height for the header and Align to alTop. Also set the height for the footer and Align to alBottom. Last, set Align to alClient for the middle panel.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×