fix(ui): Fix mobile layout and styling issues

- Add viewport settings to disable user zoom for a better mobile experience
- Set fixed height and hide overflow for html, body, and the app container
- Use svh units to ensure the shell component displays correctly on mobile devices
- Change the chat header layout from flexbox to grid to improve responsive design
- Adjust the chat controls area’s grid layout and alignment
- Optimize the selector component’s font size and padding for small screens
- Hide the divider and adjust the input box’s bottom margin to fit the safe area
- Set min-height: 0 to prevent content overflow issues
This commit is contained in:
ruiqian 2026-03-14 17:00:53 +08:00
parent 815d603ce2
commit e08a640ea0
2 changed files with 189 additions and 123 deletions

View File

@ -1,69 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenClaw Control</title>
<meta name="color-scheme" content="dark light" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<script>
(function () {
var THEMES = { claw: 1, knot: 1, dash: 1 };
var MODES = { system: 1, light: 1, dark: 1 };
var LEGACY = {
dark: "claw:dark",
light: "claw:light",
openknot: "knot:dark",
fieldmanual: "dash:dark",
clawdash: "dash:light",
system: "claw:system",
};
try {
var keys = Object.keys(localStorage);
var raw;
for (var i = 0; i < keys.length; i++) {
if (keys[i].indexOf("openclaw.control.settings.v1") === 0) {
raw = localStorage.getItem(keys[i]);
if (raw) break;
}
}
if (!raw) return;
var s = JSON.parse(raw);
var t = s && s.theme;
var m = s && s.themeMode;
if (typeof t !== "string") t = "";
if (typeof m !== "string") m = "";
var legacy = LEGACY[t];
var theme = THEMES[t] ? t : legacy ? legacy.split(":")[0] : "claw";
var mode = MODES[m] ? m : legacy ? legacy.split(":")[1] : "system";
if (mode === "system") {
mode = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
}
var resolved =
theme === "knot"
? mode === "light"
? "openknot-light"
: "openknot"
: theme === "dash"
? mode === "light"
? "dash-light"
: "dash"
: mode === "light"
? "light"
: "dark";
document.documentElement.setAttribute("data-theme", resolved);
document.documentElement.setAttribute(
"data-theme-mode",
resolved.indexOf("light") !== -1 ? "light" : "dark",
);
} catch (e) {}
})();
</script>
</head>
<body>
<openclaw-app></openclaw-app>
<script type="module" src="/src/main.ts"></script>
</body>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>OpenClaw Control</title>
<meta name="color-scheme" content="dark light" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
</head>
<body>
<openclaw-app></openclaw-app>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@ -4,6 +4,15 @@
/* Tablet and smaller: switch the left nav to a slide-over drawer. */
@media (max-width: 1100px) {
html[data-ios-mobile]
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]):not(
[type="submit"]
):not([type="reset"]):not([type="file"]):not([type="image"]):not([type="hidden"]),
html[data-ios-mobile] textarea,
html[data-ios-mobile] select {
font-size: 16px !important;
}
.shell,
.shell--nav-collapsed {
grid-template-columns: minmax(0, 1fr);
@ -223,6 +232,55 @@
/* Mobile-specific styles */
@media (max-width: 768px) {
html,
body,
openclaw-app {
height: 100%;
}
html[data-ios-shell-lock],
body[data-ios-shell-lock] {
height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
overflow: hidden;
}
openclaw-app {
height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
min-height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
}
openclaw-app[data-ios-shell-lock] {
overflow: hidden;
}
openclaw-app[data-ios-shell-lock][data-ios-keyboard-open] .content--chat .agent-chat__input {
position: fixed;
left: 8px;
right: 8px;
bottom: max(8px, env(safe-area-inset-bottom, 0px));
margin: 0;
z-index: 60;
}
openclaw-app[data-ios-shell-lock][data-ios-keyboard-open] .content--chat .chat-thread {
padding-bottom: calc(var(--mobile-chat-input-height, 112px) + 16px);
scroll-padding-bottom: calc(var(--mobile-chat-input-height, 112px) + 16px);
}
.shell,
.shell--chat,
.shell--nav-collapsed,
.shell--chat-focus {
height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
min-height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
}
.shell,
.shell--nav-collapsed,
.shell--chat-focus {
grid-template-rows: auto minmax(0, 1fr);
}
.shell {
--shell-pad: 8px;
--shell-gap: 8px;
@ -235,21 +293,43 @@
}
.topnav-shell {
flex-wrap: wrap;
gap: 10px;
flex-wrap: nowrap;
gap: 6px;
}
.topnav-shell__actions {
min-width: 0;
flex: 1 1 auto;
justify-content: space-between;
gap: 10px;
align-items: stretch;
order: 2;
flex: 1 1 0;
justify-content: flex-start;
gap: 6px;
align-items: center;
}
.topnav-shell__content {
display: none;
width: 100%;
order: 3;
width: auto;
min-width: 0;
flex: 0 0 auto;
}
.topnav-shell .dashboard-header {
justify-content: flex-end;
gap: 4px;
}
.topnav-shell .dashboard-header__breadcrumb {
gap: 4px;
font-size: 12px;
}
.topnav-shell .dashboard-header__breadcrumb-link {
white-space: nowrap;
}
.topnav-shell .dashboard-header__breadcrumb-current {
min-width: 0;
max-width: none;
}
.topbar-nav-toggle {
@ -268,6 +348,7 @@
}
.topbar-status {
flex-shrink: 0;
gap: 6px;
width: auto;
flex-wrap: nowrap;
@ -275,7 +356,20 @@
.topbar-search {
min-width: 0;
flex: 1;
flex: 1 1 0;
max-width: none;
padding-inline: 10px;
gap: 6px;
}
.topbar-search__label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.topbar-search__kbd {
display: none;
}
.topbar-theme-mode {
@ -330,76 +424,99 @@
display: none;
}
/* Hide the entire content-header on mobile chat — controls are in mobile gear menu */
.content--chat .content-header {
display: none;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 8px;
}
.content--chat {
gap: 2px;
}
/* Show the mobile gear toggle (lives in topbar now) */
.chat-mobile-controls-wrapper {
display: flex;
position: relative;
.content--chat .content-header > div:first-child {
min-width: 0;
}
.chat-mobile-controls-wrapper .chat-controls-mobile-toggle {
display: flex;
.content--chat .page-meta {
width: auto;
justify-self: end;
}
/* The dropdown panel — anchored below the gear in topbar */
.chat-mobile-controls-wrapper .chat-controls-dropdown {
.content--chat .chat-controls__session-row {
display: flex;
gap: 4px;
align-items: center;
min-width: 0;
}
.content--chat .chat-controls__session,
.content--chat .chat-controls__model {
min-width: 0;
max-width: none;
}
.content--chat .chat-controls__session {
flex: 2 1 0;
}
.content--chat .chat-controls__model {
flex: 3 1 0;
}
.content--chat .chat-controls {
display: flex;
align-items: center;
justify-content: end;
flex-wrap: nowrap;
gap: 4px;
min-width: 0;
}
.content--chat .chat-controls__session select,
.content--chat .chat-controls__model select {
width: 100%;
font-size: 16px;
padding: 6px 8px;
}
.content--chat .btn--icon {
min-width: 30px;
height: 30px;
padding: 5px !important;
}
.content--chat .btn--icon svg {
width: 14px;
height: 14px;
}
.content--chat .chat-controls__separator {
display: none;
position: absolute;
top: 100%;
right: 0;
z-index: 100;
background: var(--card, #161b22);
border: 1px solid var(--border, #30363d);
border-radius: 10px;
padding: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
flex-direction: column;
gap: 4px;
min-width: 220px;
}
.chat-mobile-controls-wrapper .chat-controls-dropdown.open {
display: flex;
.content--chat .content-header,
.content--chat .chat,
.content--chat .chat-split-container,
.content--chat .chat-main {
min-height: 0;
}
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls {
display: flex;
flex-direction: column;
gap: 4px;
width: 100%;
.content--chat .card.chat {
padding-top: 0;
}
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls__session {
min-width: unset;
max-width: unset;
width: 100%;
.content--chat .chat-thread {
padding-bottom: 8px;
}
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls__session select {
width: 100%;
font-size: 14px;
padding: 10px 12px;
.content--chat .agent-chat__input {
margin: 0 8px calc(10px + env(safe-area-inset-bottom, 0px));
}
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls__thinking {
display: flex;
flex-direction: row;
gap: 6px;
padding: 4px 0;
justify-content: center;
}
.chat-mobile-controls-wrapper .chat-controls-dropdown .btn--icon {
min-width: 44px;
height: 44px;
.content--chat .agent-chat__input > textarea {
font-size: 16px;
}
.content {
padding: 4px 4px 16px;