diff --git a/browser2/js/TODO.MD b/browser2/js/TODO.MD index 1f9dbbd..318350e 100644 --- a/browser2/js/TODO.MD +++ b/browser2/js/TODO.MD @@ -2,3 +2,4 @@ * create consistency with the `lingo-app` container element. It needs to be passed into `renderLingoApp` and is also referenced in various places in markup.js as the id `lingo-app` or via closest css `.closest('.lingo-container')`. * delete `handleSequenceOps` and move logic to custom functions which will be placed in the function lookup * add type checking when using `set` to update a struct's value +* ~~responsive CSS: mobile and desktop support~~ ✅ done (fluid layout, mobile ≤600px / tablet 601–900px breakpoints, table scroll wrappers) diff --git a/browser2/js/src/markup.js b/browser2/js/src/markup.js index 1504883..42768a7 100644 --- a/browser2/js/src/markup.js +++ b/browser2/js/src/markup.js @@ -3594,7 +3594,10 @@ function createValueElement(app, element, ctx = null) { } table.appendChild(tbody); - return table; + const wrapper = document.createElement('div'); + wrapper.className = 'table-scroll-wrapper'; + wrapper.appendChild(table); + return wrapper; } else if(element.type == 'list') { const listFormat = (element.display && element.display.format) ? element.display.format : 'bullets'; @@ -3751,7 +3754,10 @@ function createValueElement(app, element, ctx = null) { } table.appendChild(tbody); - return table; + const wrapper = document.createElement('div'); + wrapper.className = 'table-scroll-wrapper'; + wrapper.appendChild(table); + return wrapper; }else if(listFormat == 'bullets' || listFormat == 'numbers') { let elementType; diff --git a/browser2/js/src/style.css b/browser2/js/src/style.css index d2daf46..3bc3f63 100644 --- a/browser2/js/src/style.css +++ b/browser2/js/src/style.css @@ -1,14 +1,23 @@ /** * Browser 2.0 JavaScript Renderer Styles + * + * Responsive breakpoints: + * mobile : max-width 600px + * tablet : 601px – 900px + * desktop : 901px+ (base styles, max-width 1000px centred) */ /* Base styles */ body { font-family: Verdana, sans-serif; font-size: 12px; - margin: 20px; + margin: 0; + padding: 16px; background-color: white; + box-sizing: border-box; max-width: 1000px; + margin-left: auto; + margin-right: auto; } /* Heading styles */ @@ -29,18 +38,21 @@ h6 { font-size: 16px; } } /* Form element styles */ -input[type="text"] { - padding: 5px; - border: 1px solid #ccc; - border-radius: 3px; - width: 233px; +input[type="text"], +input[type="password"], +input[type="email"], +select, +textarea { + width: 100%; + max-width: 400px; + box-sizing: border-box; } +input[type="text"], input[type="password"] { padding: 5px; border: 1px solid #ccc; border-radius: 3px; - width: 233px; } button { @@ -182,4 +194,73 @@ table td { padding: 20px; border-radius: 5px; z-index: 100; +} + +/* Navigation / breadcrumb styles */ +.breadcrumb { + display: flex; + flex-wrap: wrap; + gap: 4px; +} + +/* Table scroll wrapper — allows horizontal scrolling on narrow screens */ +.table-scroll-wrapper { + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +/* Mobile breakpoint */ +@media (max-width: 600px) { + body { + padding: 8px; + font-size: 13px; + } + + h1 { font-size: 24px; } + h2 { font-size: 20px; } + h3 { font-size: 18px; } + h4 { font-size: 16px; } + + .form-table td { + display: block; + width: 100%; + } + + button { + width: 100%; + margin: 4px 0; + } + + input[type="text"], + input[type="password"], + input[type="email"], + select, + textarea { + max-width: 100%; + width: 100%; + } + + .lingo-container { + padding: 10px; + border-width: 2px; + } + + .popup-content { + width: 90%; + left: 5%; + top: 10%; + } +} + +/* Tablet breakpoint */ +@media (min-width: 601px) and (max-width: 900px) { + body { padding: 12px; } + + input[type="text"], + input[type="password"], + input[type="email"], + select, + textarea { + max-width: 300px; + } } \ No newline at end of file