2.1 Sciter HTML扩展
标准HTML支持
Sciter支持大部分HTML5标准,但也有一些独特的扩展和限制。
支持的HTML元素
<!-- 基本结构元素 -->
<html>, <head>, <body>, <title>
<div>, <span>, <section>, <article>, <header>, <footer>
<nav>, <aside>, <main>
<!-- 文本元素 -->
<h1>-<h6>, <p>, <br>, <hr>
<strong>, <em>, <b>, <i>, <u>, <s>
<code>, <pre>, <blockquote>
<!-- 列表元素 -->
<ul>, <ol>, <li>
<dl>, <dt>, <dd>
<!-- 表格元素 -->
<table>, <thead>, <tbody>, <tfoot>
<tr>, <th>, <td>
<caption>, <colgroup>, <col>
<!-- 表单元素 -->
<form>, <input>, <textarea>, <select>, <option>
<button>, <label>, <fieldset>, <legend>
<!-- 媒体元素 -->
<img>, <video>, <audio>
<canvas>, <svg>
<!-- 链接和脚本 -->
<a>, <link>, <script>, <style>
Sciter特有元素
1. <popup>
元素
<!-- 弹出窗口容器 -->
<popup class="context-menu">
<menu>
<li>复制</li>
<li>粘贴</li>
<li>删除</li>
</menu>
</popup>
2. <frame>
元素
<!-- 内嵌框架,类似iframe但更轻量 -->
<frame src="child-window.htm" />
3. <widget>
元素
<!-- 自定义控件容器 -->
<widget type="calendar" value="2024-01-15" />
<widget type="slider" min="0" max="100" value="50" />
4. <htmlarea>
元素
<!-- 富文本编辑器 -->
<htmlarea spellcheck="true">
<p>可编辑的富文本内容</p>
</htmlarea>
HTML属性扩展
1. 行为属性 (behavior)
<!-- 为元素添加特殊行为 -->
<div behavior="button">自定义按钮</div>
<div behavior="hyperlink" href="#section1">内部链接</div>
<input behavior="masked-edit" mask="(###) ###-####" />
<div behavior="collapsible">可折叠内容</div>
2. 状态属性
<!-- 元素状态控制 -->
<button state-disabled="true">禁用按钮</button>
<div state-expanded="false">折叠状态</div>
<input state-readonly="true" value="只读文本" />
3. 数据绑定属性
<!-- 数据绑定 -->
<div data-bind="text: userName">用户名</div>
<input data-bind="value: email" />
<img data-bind="src: avatarUrl" />
2.2 Sciter CSS增强
CSS选择器扩展
1. 状态选择器
/* 元素状态选择器 */
button:disabled { opacity: 0.5; }
button:pressed { transform: scale(0.95); }
input:focus { border-color: #007acc; }
div:expanded { height: auto; }
div:collapsed { height: 0; }
/* 自定义状态 */
.item:current { background: #e3f2fd; }
.item:selected { background: #1976d2; color: white; }
2. 结构选择器增强
/* 扩展的结构选择器 */
li:nth-child(odd) { background: #f5f5f5; }
li:nth-child(even) { background: white; }
/* 范围选择器 */
li:nth-child(2n+1):nth-child(-n+10) {
/* 选择前10个奇数项 */
color: red;
}
CSS属性扩展
1. 流式布局 (flow)
/* Sciter独有的流式布局 */
.container {
flow: horizontal; /* 水平流式布局 */
}
.vertical-container {
flow: vertical; /* 垂直流式布局 */
}
.stack-container {
flow: stack; /* 堆叠布局 */
}
.grid-container {
flow: grid(3, 1fr); /* 网格布局 */
}
/* 流式布局示例 */
.toolbar {
flow: horizontal;
padding: 8px;
gap: 4px;
}
.toolbar > button {
padding: 6px 12px;
border: 1px solid #ccc;
background: #f8f9fa;
}
.sidebar {
flow: vertical;
width: 200px;
height: *; /* 自适应高度 */
}
.content-area {
flow: vertical;
width: *; /* 自适应宽度 */
height: *;
}
2. 尺寸单位扩展
/* Sciter特有的尺寸单位 */
.element {
width: *; /* 自适应宽度 */
height: *; /* 自适应高度 */
width: 1*; /* 权重为1的自适应 */
height: 2*; /* 权重为2的自适应 */
min-width: min-content; /* 最小内容宽度 */
max-width: max-content; /* 最大内容宽度 */
}
/* 百分比和固定尺寸混合 */
.layout {
width: 300px + 50%; /* 固定宽度 + 百分比 */
height: 100px + 1*; /* 固定高度 + 自适应 */
}
3. 背景和边框增强
/* 渐变背景 */
.gradient-bg {
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
background: radial-gradient(circle, #667eea, #764ba2);
}
/* 多重背景 */
.multi-bg {
background:
url(pattern.png) repeat,
linear-gradient(to bottom, #fff, #f0f0f0);
}
/* 边框图像 */
.border-image {
border: 10px solid transparent;
border-image: url(border.png) 10 repeat;
}
/* 圆角和阴影 */
.card {
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
background: white;
}
4. 变换和动画
/* 2D变换 */
.transform-element {
transform: rotate(45deg) scale(1.2) translate(10px, 20px);
transform-origin: center center;
}
/* 过渡动画 */
.animated-button {
transition: all 0.3s ease;
background: #007acc;
color: white;
}
.animated-button:hover {
background: #005a9e;
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(0, 122, 204, 0.3);
}
/* 关键帧动画 */
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.pulse-animation {
animation: pulse 2s infinite;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-100%);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.slide-in {
animation: slideIn 0.5s ease-out;
}
响应式设计
1. 媒体查询
/* 基于窗口大小的媒体查询 */
@media (max-width: 768px) {
.container {
flow: vertical;
padding: 10px;
}
.sidebar {
width: 100%;
height: auto;
}
}
@media (min-width: 1200px) {
.container {
max-width: 1140px;
margin: 0 auto;
}
}
/* 基于设备特性的查询 */
@media (pointer: coarse) {
/* 触摸设备样式 */
button {
min-height: 44px;
min-width: 44px;
}
}
@media (hover: hover) {
/* 支持悬停的设备 */
.hover-effect:hover {
background: #f0f0f0;
}
}
2. 弹性布局
/* Flexbox布局 */
.flex-container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 16px;
}
.flex-item {
flex: 1; /* 等分剩余空间 */
}
.flex-item.grow {
flex-grow: 2; /* 增长因子 */
}
.flex-item.shrink {
flex-shrink: 0; /* 不收缩 */
}
/* 网格布局 */
.grid-container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-gap: 16px;
height: 100vh;
}
.header {
grid-column: 1 / -1;
grid-row: 1;
}
.sidebar {
grid-column: 1;
grid-row: 2;
}
.main {
grid-column: 2;
grid-row: 2;
}
.aside {
grid-column: 3;
grid-row: 2;
}
.footer {
grid-column: 1 / -1;
grid-row: 3;
}
2.3 实用CSS组件
按钮组件
/* 基础按钮样式 */
.btn {
display: inline-block;
padding: 8px 16px;
border: 1px solid transparent;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
text-align: center;
cursor: pointer;
transition: all 0.2s ease;
user-select: none;
}
/* 按钮变体 */
.btn-primary {
background: #007acc;
color: white;
border-color: #007acc;
}
.btn-primary:hover {
background: #005a9e;
border-color: #005a9e;
}
.btn-primary:pressed {
background: #004578;
transform: translateY(1px);
}
.btn-secondary {
background: #6c757d;
color: white;
border-color: #6c757d;
}
.btn-outline {
background: transparent;
color: #007acc;
border-color: #007acc;
}
.btn-outline:hover {
background: #007acc;
color: white;
}
/* 按钮尺寸 */
.btn-sm {
padding: 4px 8px;
font-size: 12px;
}
.btn-lg {
padding: 12px 24px;
font-size: 16px;
}
/* 按钮状态 */
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
pointer-events: none;
}
.btn.loading {
position: relative;
color: transparent;
}
.btn.loading::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 16px;
height: 16px;
margin: -8px 0 0 -8px;
border: 2px solid currentColor;
border-radius: 50%;
border-top-color: transparent;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
表单组件
/* 表单容器 */
.form-group {
margin-bottom: 16px;
}
.form-label {
display: block;
margin-bottom: 4px;
font-weight: 500;
color: #333;
}
/* 输入框样式 */
.form-control {
display: block;
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.2s ease;
}
.form-control:focus {
outline: none;
border-color: #007acc;
box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.2);
}
.form-control:invalid {
border-color: #dc3545;
}
.form-control:invalid:focus {
box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.2);
}
/* 选择框样式 */
.form-select {
display: block;
width: 100%;
padding: 8px 32px 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
background: white url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="none" stroke="%23333" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2 5l6 6 6-6"/></svg>') no-repeat right 8px center;
background-size: 16px;
appearance: none;
}
/* 复选框和单选框 */
.form-check {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.form-check-input {
margin-right: 8px;
}
.form-check-label {
cursor: pointer;
}
/* 文本域 */
.form-textarea {
resize: vertical;
min-height: 80px;
}
/* 表单验证反馈 */
.invalid-feedback {
display: none;
color: #dc3545;
font-size: 12px;
margin-top: 4px;
}
.form-control:invalid + .invalid-feedback {
display: block;
}
.valid-feedback {
display: none;
color: #28a745;
font-size: 12px;
margin-top: 4px;
}
.form-control:valid + .valid-feedback {
display: block;
}
卡片组件
/* 卡片容器 */
.card {
background: white;
border: 1px solid #e0e0e0;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: box-shadow 0.3s ease;
}
.card:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
/* 卡片头部 */
.card-header {
padding: 16px 20px;
border-bottom: 1px solid #e0e0e0;
background: #f8f9fa;
}
.card-title {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #333;
}
.card-subtitle {
margin: 4px 0 0 0;
font-size: 14px;
color: #666;
}
/* 卡片内容 */
.card-body {
padding: 20px;
}
.card-text {
margin-bottom: 16px;
line-height: 1.5;
color: #555;
}
/* 卡片底部 */
.card-footer {
padding: 12px 20px;
border-top: 1px solid #e0e0e0;
background: #f8f9fa;
display: flex;
justify-content: flex-end;
gap: 8px;
}
/* 卡片图片 */
.card-img {
width: 100%;
height: auto;
display: block;
}
.card-img-top {
border-radius: 8px 8px 0 0;
}
.card-img-bottom {
border-radius: 0 0 8px 8px;
}
导航组件
/* 导航栏 */
.navbar {
display: flex;
align-items: center;
padding: 12px 20px;
background: #fff;
border-bottom: 1px solid #e0e0e0;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.navbar-brand {
font-size: 20px;
font-weight: 700;
color: #333;
text-decoration: none;
margin-right: auto;
}
.navbar-nav {
display: flex;
list-style: none;
margin: 0;
padding: 0;
gap: 8px;
}
.nav-item {
position: relative;
}
.nav-link {
display: block;
padding: 8px 16px;
color: #666;
text-decoration: none;
border-radius: 4px;
transition: all 0.2s ease;
}
.nav-link:hover {
background: #f0f0f0;
color: #333;
}
.nav-link.active {
background: #007acc;
color: white;
}
/* 下拉菜单 */
.dropdown {
position: relative;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
min-width: 160px;
background: white;
border: 1px solid #e0e0e0;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
z-index: 1000;
display: none;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.dropdown-item {
display: block;
padding: 8px 16px;
color: #333;
text-decoration: none;
transition: background 0.2s ease;
}
.dropdown-item:hover {
background: #f0f0f0;
}
.dropdown-divider {
height: 1px;
background: #e0e0e0;
margin: 4px 0;
}
2.4 布局系统
网格系统
/* 容器 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px;
}
.container-fluid {
width: 100%;
padding: 0 16px;
}
/* 行和列 */
.row {
display: flex;
flex-wrap: wrap;
margin: 0 -8px;
}
.col {
flex: 1;
padding: 0 8px;
}
/* 固定列宽 */
.col-1 { flex: 0 0 8.333333%; }
.col-2 { flex: 0 0 16.666667%; }
.col-3 { flex: 0 0 25%; }
.col-4 { flex: 0 0 33.333333%; }
.col-5 { flex: 0 0 41.666667%; }
.col-6 { flex: 0 0 50%; }
.col-7 { flex: 0 0 58.333333%; }
.col-8 { flex: 0 0 66.666667%; }
.col-9 { flex: 0 0 75%; }
.col-10 { flex: 0 0 83.333333%; }
.col-11 { flex: 0 0 91.666667%; }
.col-12 { flex: 0 0 100%; }
/* 响应式列 */
@media (max-width: 768px) {
.col-sm-12 { flex: 0 0 100%; }
.col-sm-6 { flex: 0 0 50%; }
}
@media (max-width: 576px) {
.col-xs-12 { flex: 0 0 100%; }
}
实用工具类
/* 间距工具 */
.m-0 { margin: 0; }
.m-1 { margin: 4px; }
.m-2 { margin: 8px; }
.m-3 { margin: 16px; }
.m-4 { margin: 24px; }
.m-5 { margin: 32px; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 4px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 16px; }
.p-0 { padding: 0; }
.p-1 { padding: 4px; }
.p-2 { padding: 8px; }
.p-3 { padding: 16px; }
.p-4 { padding: 24px; }
.p-5 { padding: 32px; }
/* 文本工具 */
.text-left { text-align: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-justify { text-align: justify; }
.text-primary { color: #007acc; }
.text-secondary { color: #6c757d; }
.text-success { color: #28a745; }
.text-danger { color: #dc3545; }
.text-warning { color: #ffc107; }
.text-info { color: #17a2b8; }
.text-muted { color: #6c757d; }
/* 显示工具 */
.d-none { display: none; }
.d-block { display: block; }
.d-inline { display: inline; }
.d-inline-block { display: inline-block; }
.d-flex { display: flex; }
.d-grid { display: grid; }
/* 弹性布局工具 */
.justify-content-start { justify-content: flex-start; }
.justify-content-end { justify-content: flex-end; }
.justify-content-center { justify-content: center; }
.justify-content-between { justify-content: space-between; }
.justify-content-around { justify-content: space-around; }
.align-items-start { align-items: flex-start; }
.align-items-end { align-items: flex-end; }
.align-items-center { align-items: center; }
.align-items-baseline { align-items: baseline; }
.align-items-stretch { align-items: stretch; }
/* 位置工具 */
.position-static { position: static; }
.position-relative { position: relative; }
.position-absolute { position: absolute; }
.position-fixed { position: fixed; }
.position-sticky { position: sticky; }
/* 浮动工具 */
.float-left { float: left; }
.float-right { float: right; }
.float-none { float: none; }
/* 清除浮动 */
.clearfix::after {
content: "";
display: table;
clear: both;
}
2.5 主题系统
CSS变量定义
/* 主题变量 */
:root {
/* 颜色系统 */
--primary-color: #007acc;
--primary-dark: #005a9e;
--primary-light: #4da6e0;
--secondary-color: #6c757d;
--success-color: #28a745;
--danger-color: #dc3545;
--warning-color: #ffc107;
--info-color: #17a2b8;
/* 中性色 */
--white: #ffffff;
--gray-100: #f8f9fa;
--gray-200: #e9ecef;
--gray-300: #dee2e6;
--gray-400: #ced4da;
--gray-500: #adb5bd;
--gray-600: #6c757d;
--gray-700: #495057;
--gray-800: #343a40;
--gray-900: #212529;
--black: #000000;
/* 字体系统 */
--font-family-base: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--font-family-monospace: 'Consolas', 'Monaco', 'Courier New', monospace;
--font-size-xs: 12px;
--font-size-sm: 14px;
--font-size-base: 16px;
--font-size-lg: 18px;
--font-size-xl: 20px;
--font-size-xxl: 24px;
--font-weight-light: 300;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
/* 间距系统 */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
--spacing-xxl: 48px;
/* 边框和圆角 */
--border-width: 1px;
--border-color: #dee2e6;
--border-radius-sm: 4px;
--border-radius: 6px;
--border-radius-lg: 8px;
--border-radius-xl: 12px;
/* 阴影 */
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
--shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.15);
--shadow-xl: 0 8px 32px rgba(0, 0, 0, 0.2);
/* 过渡 */
--transition-fast: 0.15s ease;
--transition-base: 0.3s ease;
--transition-slow: 0.5s ease;
}
/* 深色主题 */
[data-theme="dark"] {
--primary-color: #4da6e0;
--primary-dark: #007acc;
--primary-light: #7bc3ea;
--white: #1a1a1a;
--gray-100: #2d2d2d;
--gray-200: #3a3a3a;
--gray-300: #4a4a4a;
--gray-400: #5a5a5a;
--gray-500: #6a6a6a;
--gray-600: #8a8a8a;
--gray-700: #aaaaaa;
--gray-800: #cccccc;
--gray-900: #eeeeee;
--black: #ffffff;
--border-color: #4a4a4a;
}
主题应用
/* 使用CSS变量 */
.themed-component {
background: var(--white);
color: var(--gray-900);
border: var(--border-width) solid var(--border-color);
border-radius: var(--border-radius);
padding: var(--spacing-md);
font-family: var(--font-family-base);
font-size: var(--font-size-base);
box-shadow: var(--shadow);
transition: var(--transition-base);
}
.themed-button {
background: var(--primary-color);
color: var(--white);
border: none;
border-radius: var(--border-radius);
padding: var(--spacing-sm) var(--spacing-md);
font-weight: var(--font-weight-medium);
cursor: pointer;
transition: var(--transition-fast);
}
.themed-button:hover {
background: var(--primary-dark);
transform: translateY(-1px);
box-shadow: var(--shadow-lg);
}
2.6 本章总结
在本章中,我们深入学习了:
HTML扩展
- Sciter特有的HTML元素和属性
- 行为属性和状态控制
- 数据绑定机制
CSS增强
- 扩展的选择器和属性
- 流式布局系统
- 响应式设计技巧
组件系统
- 常用UI组件的实现
- 布局系统和网格
- 实用工具类
主题系统
- CSS变量的使用
- 主题切换机制
- 设计系统构建
2.7 练习题
基础练习
- 创建一个响应式的导航栏
- 实现一个卡片布局的产品展示页面
- 设计一个完整的表单组件
- 制作一个可切换的主题系统
进阶练习
- 实现一个复杂的网格布局系统
- 创建自定义的CSS动画效果
- 设计一个模态对话框组件
- 实现一个可拖拽的面板布局
挑战练习
- 创建一个完整的设计系统
- 实现复杂的CSS变换和动画
- 设计一个自适应的数据表格
- 制作一个交互式的图表组件
下一章预告: 在第3章中,我们将学习TIScript脚本语言,这是Sciter的核心脚本引擎,了解其语法特性、内置对象和API,以及如何编写高效的脚本代码。