Web Application Programming in PicoLisp: Adding CSS

Search for a command to run...

No comments yet. Be the first to comment.
In this series, we will show how to create a basic web application in PicoLisp.
Today we will show how to create a simple HTML form in PicoLisp. User Interaction in HTML If a website purely works in HTML, the user interface can only be realized using <form> and <input> elements. The <form> tag accepts several attributes, of whi...
In our previous post, we introduced how to utilize Discrete Event Simulation (DES) in PicoLisp. Now, let's explore another application: a railroad model simulation that includes tracks and trains. The visualization is ASCII-based, so feel free to unl...

The Dining Philosophers

In this post, we will introduce the concept of co-routines and how they are handled in PicoLisp. This will be the foundation for the subsequent posts on Discrete Event Simulation and finally a couple of examples, including an ASCII model railway simu...

One of the many nice things of PicoLisp is that it comes with a built-in database. This makes it easy to collect and store our own data, for example via a mobile app. But not all data is best represented in tables and lists: sometimes a colorful litt...

In the last two posts, we have built a little app that shows the current location and displays the nearest ice cream shops: https://picolisp-explored.com/an-openstreetmap-app-written-in-picolisp-pt-1 https://picolisp-explored.com/an-openstreetmap-ap...

In the last post, we expanded our "Hello World" example by some tags. However, the page still looks really boring. We need to add some styles.
CSS stands for Cascading Style Sheets. The main idea is that you can define the layout independently from the text content. The style instructions are also called "attributes".
There are two possibilities to define CSS attributes: In a separate file or by directly editing the tags within the HTML text.
PicoLisp comes with a pre-defined css-file that includes some very basic stylings, lib.css. You can find it in the root of the PicoLisp installation folder.
Let's include it to our previous helloworld.l-file. We just need to edit the first line:
(html 0 "Hello" "@lib.css" NIL
...
As the comparison below shows, there are some changes indeed: For instance, the background color is different, and the font type has also changed.

In a typical application, you might not only use one css-file, but several ones. In this case, you can hand over a list of files like this:
(html 0 "Project" '("@lib.css" "my1.css" "my2.css") NIL
The CSS files that come later in the list will redefine specifications from the previous ones. To increase readibility, you can also use a global variable to define it:
(setq *Css '("@lib.css" "my1.css" "my2.css"))
(html 0 "Project" *Css NIL
...
This is not a CSS-tutorial, so we will not cover this topic in depth. But you should be aware that the way a styling is displayed depends on a lot of things: screen width, browser type, browser version... It can be really frustrating to style your app for hours in your Firefox browser, only to realize that it looks completely wrong on Chrome.
The good news is that there is no need to re-invent the wheel. Talented webdesigners have contributed thousands and thousands of hours to create frameworks that react responsively and reliably on all kinds of browsers and viewports. One famous example for this is the Bootstrap framework. For example, the grid system in Bootstrap is quite powerful and a big help to increase responsiveness.
The standard installation comes with a lot of JavaScript included, but since we only need styles, we can download the .css-files separately from here. The file size is approx. 200 kB.
Now let's modify our "helloworld.l"-file with some Bootstrap classes.
Crash-course (better check the docs!):
m-3 is short for "margin", level 3. You can choose between 1 to 5. You can addx to only modify left and right margin, or y for upper and lower margin. row defines a row, col a column.text-primary, secondary, success and so on are predefined colors that can be modified in the css-datad-flex is a flexbox where you can style many things, like floating, position, orientation and so on.Here is the boostrapped helloworld.l file after I played around with it a little. I admit it's not a great design, I'm sure you can do better than me :-) You can find the hosted version here on picolisp.com.
(setq *Css '("@lib.css" "css/bootstrap.css"))
(html 0 "Hello World - CSS Bootstrap" *Css NIL
(<div> "d-flex flex-column"
(<h1> "d-flex m-5 justify-content-center" "Hello World!")
(<h2> "d-flex m-3 justify-content-center" "Playing around with Bootstrap classes.") )
(<hr>)
(<p> "text-white bg-dark m-4 d-inline-flex p-1"
"This is a text block. "
(<strong> " Still the same text block. ")
" Still a text block.")
(<hr>)
(<h5> "ml-5" "This is the bootstrap grid system:")
(<div> "row mx-3 bg-secondary"
(<div> "col border rounded m-1 p-3 text-success bg-white" "This is a div in a div."
(<ul> "text-dark"
(<li> NIL "Item 1")
(<li> NIL "Item 2"
(<ul> "text-secondary"
(<li> NIL "2-1")
(<li> NIL "2-2") ) ) ) )
(<div> "col border rounded m-1 p-3 text-success bg-white" "This is a second div in a div."
(<ul> "text-dark"
(<li> NIL "Item 3")
(<li> NIL "Item 4"
(<ul> "text-secondary"
(<li> NIL "4-1")
(<li> NIL "4-2")
(<li> "border rounded m-2 text-danger bg-light" "div in a div in a div") ) ) ) ) )
(<div> "row mx-3 mt-1 bg-secondary"
(<div> "col border rounded m-1 p-3 bg-white text-center"
(<img> "img/Sunflower_from_Silesia.JPG" "Sunflower" NIL 300 300) ) )
(<div> "d-flex flex-column m-5"
(<p> NIL "View source code on "
(<href> "Gitlab" "https://gitlab.com/picolisp-blog/web-applications/-/blob/main/bootstrap-example/helloworld-bootstrapped.l" "_blank") ) ) )
Below you can see how it looks like both on desktop and mobile browsers. As you can see, the content collapses automatically to fit the screen. There are also options to handle different behaviour depending on screen size and other parameters.

All files can be downloaded here.
Of course Bootstrap has its limits - so in order to add or modify your styling, you can always create an additional custom CSS-file to overwrite or expand the defined classes. For example, if you define the <h1> tag in a new css file custom.css, your definitions will be executed if custom.css is the last file to be called, like this:
(setq *Css '("@lib.css" "css/bootstrap.css" "css/custom.css"))
If you still prefer to to add some classes directly to your HTML, you can do so by adding a "cons pair".
(<div> '(style . "margin: 60px;")
or
(<div> '("myClass" (style . "margin: 60px;") ..)
However, I wouldn't recommend to do so as you lose some of your flexibility, especially if you also include a .css-file. It also makes debugging your style much more difficult if the CSS is defined in various sources.
As you might have noticed, we didn't have any interactive components yet, so let's start with this topic in the next post.
https://picolisp.com/wiki/?css
https://getbootstrap.com/