user4527: I have a Teensy 4.1 with ethernet, but I have other networked MCUs like a D1 mini, various ESP8266s and Arduino ethernet shields.
My question is: how I can make better looking web pages on these devices, where having a filesystem is limited by memory, or which lack a filesystem.
Specifically, I would like to add SVG images; I'm interested in how to make things like background images. I understand HTML/CSS, and I can code in C, get my data, whatever, but I want to make the page look good too.
Here's an example of the issue as it relates to HTML being rendered; here is an HTML page:
<!DOCTYPE html>
<html>
  <head> 
    <style>
      body {
           background-image: url(example.svg);
           }
    </style>
  </head>
  <body>
  </body>
</html>

Cool, well to write that in something an Arduino can render, you use print statements; you might write:
// listen for incoming clients
// forgoing all of server setup
EthernetClient client = server.available();
client.println("<!DOCTYPE html><head><style>");
client.println("body {background-image: url(example.svg);}");
client.println("</style></head><body></body></html>");

This won't work without a filesystem, or won't work as is.
Then, I tried inline SVG:
// listen for incoming clients
// forgoing all of server setup
EthernetClient client = server.available();
client.println("<!DOCTYPE html><head><style>");
client.println("body { ");
client.println("background-image: url("data:image/svg+xml;utf8,<svg>**Omited**</svg>);");
client.println("}");
client.println("</style></head><body></body></html>");

This works, sometimes, but seems to have limitations as well.
I'm just wondering how I can make great looking webpages with stylesheets on an Arduino, only using print statements, or not requiring a filesystem.

user4527: well, I still want to know more about writing great looking webpages on ardunio network devices.
I got my immediate issue sorted for now.
html/css seems to have some issues I dont quite understand as they relate to print statements, and Im pretty sure the url attribute is what is getting me.
I found this great github project that encodes svg for css inline functions.
https://yoksel.github.io/url-encoder/

I set up a basic web server example to simplify the code I was looking at.
its weird, on html pages I have put full style sheets on one line and never had a problem. here, it wouldn't work until I broke the style sheet into multiple lines (even with the url encoded svg).
Here is my simpler example for a page with a background image:
#include <SPI.h>
#include <NativeEthernet.h>
void  pageWrite(EthernetClient client);
void listenClient(EthernetClient client);
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(10, 1, 0, 177);
EthernetServer server(80);
void setup() {

  delay(5000);  //you want this delay. reason: tl;dr
  Serial.begin(9600); 
  Ethernet.begin(mac, ip);

if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }
  // start the server
  server.begin();
  delay(100);
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
} //end setup

void loop() {
      EthernetClient client = server.available();
listenClient(client);
}  //end loop  
void listenClient(EthernetClient client){
  
   if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
       if (client.available()) {
          char c = client.read();
       // Serial.write(c);   //tells about the client connection
        if (c == '\n' && currentLineIsBlank) {
          pageWrite(client);
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }//end avail 
    } //end conect
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  } //end client
}//end listenClient()
void  pageWrite(EthernetClient client){
client.println("<!DOCTYPE html><html><head><style>");
client.println("body {");
client.println("background-image:"); 
client.println("url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 227.35277 156.29323' height='6.1532764in' width='8.9508963in' %3E%3Cpath style='fill:%23ff0000; stroke:%23ff0000; stroke-width:1.32300019;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1' d='m 12.000819,0.66145838 c -6.2819637,0 -11.33936062,5.05739692 -11.33936062,11.33936062 V 144.29249 c 0,6.28197 5.05739692,11.33936 11.33936062,11.33936 H 215.35224 c 6.28197,0 11.33885,-5.05739 11.33885,-11.33936 V 12.000819 c 0,-6.2819637 -5.05688,-11.33936062 -11.33885,-11.33936062 z M 18.932696,12.696383 H 205.5854 c 5.02557,0 9.07128,4.04571 9.07128,9.071282 v 77.03923 c 0,5.025575 -4.04571,9.071285 -9.07128,9.071285 H 18.932696 c -5.025572,0 -9.0712819,-4.04571 -9.0712819,-9.071285 v -77.03923 c 0,-5.025572 4.0457099,-9.071282 9.0712819,-9.071282 z' /%3E%3Cellipse style='fill:%23ffffff;fill-opacity:1; stroke:%23ff0000; stroke-width:1.32300007; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1' cx='21.16666' cy='130.59085' rx='10.583334' ry='9.0714283' /%3E%3Cellipse style='fill:%23ffffff; fill-opacity:1; stroke:%23ff0000; stroke-width:1.32300007; stroke-miterlimit:4; stroke-dasharray:none;stroke-opacity:1' cx='200.62982' cy='131.57361' rx='10.583334' ry='9.0714283' /%3E%3C/svg%3E%0A\");");
client.println("background-repeat: no-repeat;");
client.println(" }");
client.println(" </style></head><body ></body></html>");
    }


user14095: As I understand what you want to send is basically a big string(s) stored in memory. You can quite easily store it  it in external memory. You can use FRAM which is non volatile with 32K x 8 modules available for less then $5.00. They will run (Read / Write) at I2C or SPI speeds, no delays for writing or reading. There are other memory types that will also do the job but this is simple and inexpensive.
I am currently doing that with a project I am working on.  It is using an Arduino Nano with about 20K of messages and several of application / program data that I store. Flash will not contain the messages and the program, not enough room. The program data is created via sensors and a rotary switch. I load the data into the FRAM sometimes in sections depending on size with my loading code. I then go to my application code which retrieves the messages from the FRAM and displays them on the LCD and terminal.
There is a pointer table in a specific location in FRAM that is pointing to each message address, size etc. This allows messages and other data to change without changing the main code. The FRAM in my case is a plug in module. This approach although a bit convoluted works nicely and you do not have to have a file structure. You can if you want. I do not know if this will work for you but it does for me.

user10794: Your method of embedding SVG seems unnecessarily complicated to me. You don't need to give a URL of anything. Below is valid for putting SVG onto a web page:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
  <title>Test</title>
</head>
<body>
<div style="position:absolute; z-index:-1;">
  <svg width="500" height="500">
    <rect x="5" y="5" width="450" height="450" fill="lightblue" stroke="black"></rect>
  </svg>
</div>
<p style="padding:10px;">
Hello, world
</body>
</html>

The "position:absolute" and the z-index styles put the SVG in a fixed position on the page (like a background image) and underneath anything else you might put there.

4527: <p>I have a Teensy 4.1 with ethernet, but I have other networked MCUs like a D1 mini, various ESP8266s and Arduino ethernet shields.</p>
<p>My question is: how I can make better looking web pages on these devices, where having a filesystem is limited by memory, or which lack a filesystem.</p>
<p>Specifically, I would like to add SVG images; I'm interested in how to make things like background images. I understand HTML/CSS, and I can code in C, get my data, whatever, but I want to make the page look good too.</p>
<p>Here's an example of the issue as it relates to HTML being rendered; here is an HTML page:</p>
<pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt; 
    &lt;style&gt;
      body {
           background-image: url(example.svg);
           }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Cool, well to write that in something an Arduino can render, you use print statements; you might write:</p>
<pre class="lang-cpp prettyprint-override"><code>// listen for incoming clients
// forgoing all of server setup
EthernetClient client = server.available();
client.println(&quot;&lt;!DOCTYPE html&gt;&lt;head&gt;&lt;style&gt;&quot;);
client.println(&quot;body {background-image: url(example.svg);}&quot;);
client.println(&quot;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;&quot;);
</code></pre>
<p>This won't work without a filesystem, or won't work as is.</p>
<p>Then, I tried inline SVG:</p>
<pre class="lang-cpp prettyprint-override"><code>// listen for incoming clients
// forgoing all of server setup
EthernetClient client = server.available();
client.println(&quot;&lt;!DOCTYPE html&gt;&lt;head&gt;&lt;style&gt;&quot;);
client.println(&quot;body { &quot;);
client.println(&quot;background-image: url(&quot;data:image/svg+xml;utf8,&lt;svg&gt;**Omited**&lt;/svg&gt;);&quot;);
client.println(&quot;}&quot;);
client.println(&quot;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;&quot;);
</code></pre>
<p>This works, sometimes, but seems to have limitations as well.</p>
<p>I'm just wondering how I can make great looking webpages with stylesheets on an Arduino, only using print statements, or not requiring a filesystem.</p>
 4527: <p>well, I still want to know more about writing great looking webpages on ardunio network devices.</p>
<p>I got my immediate issue sorted for now.
html/css seems to have some issues I dont quite understand as they relate to print statements, and Im pretty sure the url attribute is what is getting me.</p>
<p>I found this great github project that encodes svg for css inline functions.
<a href="https://yoksel.github.io/url-encoder/" rel="nofollow noreferrer">https://yoksel.github.io/url-encoder/</a></p>
<p><a href="https://i.stack.imgur.com/sjLwY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/sjLwY.png" alt="etchasketch svg" /></a></p>
<p>I set up a basic web server example to simplify the code I was looking at.
its weird, on html pages I have put full style sheets on one line and never had a problem. here, it wouldn't work until I broke the style sheet into multiple lines (even with the url encoded svg).</p>
<p>Here is my simpler example for a page with a background image:</p>
<pre><code>#include &lt;SPI.h&gt;
#include &lt;NativeEthernet.h&gt;
void  pageWrite(EthernetClient client);
void listenClient(EthernetClient client);
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(10, 1, 0, 177);
EthernetServer server(80);
void setup() {

  delay(5000);  //you want this delay. reason: tl;dr
  Serial.begin(9600); 
  Ethernet.begin(mac, ip);

if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println(&quot;Ethernet cable is not connected.&quot;);
  }
  // start the server
  server.begin();
  delay(100);
  Serial.print(&quot;server is at &quot;);
  Serial.println(Ethernet.localIP());
} //end setup

void loop() {
      EthernetClient client = server.available();
listenClient(client);
}  //end loop  
void listenClient(EthernetClient client){
  
   if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
       if (client.available()) {
          char c = client.read();
       // Serial.write(c);   //tells about the client connection
        if (c == '\n' &amp;&amp; currentLineIsBlank) {
          pageWrite(client);
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }//end avail 
    } //end conect
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  } //end client
}//end listenClient()
void  pageWrite(EthernetClient client){
client.println(&quot;&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;style&gt;&quot;);
client.println(&quot;body {&quot;);
client.println(&quot;background-image:&quot;); 
client.println(&quot;url(\&quot;data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 227.35277 156.29323' height='6.1532764in' width='8.9508963in' %3E%3Cpath style='fill:%23ff0000; stroke:%23ff0000; stroke-width:1.32300019;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1' d='m 12.000819,0.66145838 c -6.2819637,0 -11.33936062,5.05739692 -11.33936062,11.33936062 V 144.29249 c 0,6.28197 5.05739692,11.33936 11.33936062,11.33936 H 215.35224 c 6.28197,0 11.33885,-5.05739 11.33885,-11.33936 V 12.000819 c 0,-6.2819637 -5.05688,-11.33936062 -11.33885,-11.33936062 z M 18.932696,12.696383 H 205.5854 c 5.02557,0 9.07128,4.04571 9.07128,9.071282 v 77.03923 c 0,5.025575 -4.04571,9.071285 -9.07128,9.071285 H 18.932696 c -5.025572,0 -9.0712819,-4.04571 -9.0712819,-9.071285 v -77.03923 c 0,-5.025572 4.0457099,-9.071282 9.0712819,-9.071282 z' /%3E%3Cellipse style='fill:%23ffffff;fill-opacity:1; stroke:%23ff0000; stroke-width:1.32300007; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1' cx='21.16666' cy='130.59085' rx='10.583334' ry='9.0714283' /%3E%3Cellipse style='fill:%23ffffff; fill-opacity:1; stroke:%23ff0000; stroke-width:1.32300007; stroke-miterlimit:4; stroke-dasharray:none;stroke-opacity:1' cx='200.62982' cy='131.57361' rx='10.583334' ry='9.0714283' /%3E%3C/svg%3E%0A\&quot;);&quot;);
client.println(&quot;background-repeat: no-repeat;&quot;);
client.println(&quot; }&quot;);
client.println(&quot; &lt;/style&gt;&lt;/head&gt;&lt;body &gt;&lt;/body&gt;&lt;/html&gt;&quot;);
    }
</code></pre>
 14095: <p>As I understand what you want to send is basically a big string(s) stored in memory. You can quite easily store it  it in external memory. You can use FRAM which is non volatile with 32K x 8 modules available for less then $5.00. They will run (Read / Write) at I2C or SPI speeds, no delays for writing or reading. There are other memory types that will also do the job but this is simple and inexpensive.</p>
<p>I am currently doing that with a project I am working on.  It is using an Arduino Nano with about 20K of messages and several of application / program data that I store. Flash will not contain the messages and the program, not enough room. The program data is created via sensors and a rotary switch. I load the data into the FRAM sometimes in sections depending on size with my loading code. I then go to my application code which retrieves the messages from the FRAM and displays them on the LCD and terminal.</p>
<p>There is a pointer table in a specific location in FRAM that is pointing to each message address, size etc. This allows messages and other data to change without changing the main code. The FRAM in my case is a plug in module. This approach although a bit convoluted works nicely and you do not have to have a file structure. You can if you want. I do not know if this will work for you but it does for me.</p>
 10794: <p>Your method of embedding SVG seems unnecessarily complicated to me. You don't need to give a URL of anything. Below is valid for putting SVG onto a web page:</p>
<pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html;charset=utf-8&quot; &gt;
  &lt;title&gt;Test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div style=&quot;position:absolute; z-index:-1;&quot;&gt;
  &lt;svg width=&quot;500&quot; height=&quot;500&quot;&gt;
    &lt;rect x=&quot;5&quot; y=&quot;5&quot; width=&quot;450&quot; height=&quot;450&quot; fill=&quot;lightblue&quot; stroke=&quot;black&quot;&gt;&lt;/rect&gt;
  &lt;/svg&gt;
&lt;/div&gt;
&lt;p style=&quot;padding:10px;&quot;&gt;
Hello, world
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>The &quot;position:absolute&quot; and the z-index styles put the SVG in a fixed position on the page (like a background image) and underneath anything else you might put there.</p>
