1. HTML结构
基本结构:使用HTML5标准文档结构,包含head和body部分
字体引入:使用Google Fonts的Poppins字体,现代且易读
图标库:引入Font Awesome提供丰富的图标
主容器:.email-container包含整个邮件发送界面
头部区域:.email-header显示标题和简介
表单区域:.email-form包含所有输入字段和功能
2. CSS样式设计
色彩方案:
主色调:柔和的紫色到蓝色渐变
辅助色:浅灰色背景增强可读性
强调色:红色用于删除操作,绿色用于成功状态
布局设计:
响应式布局,适应不同屏幕尺寸
使用flexbox进行元素对齐
卡片式设计带有阴影和圆角
动画效果:
元素淡入动画增强用户体验
悬停效果使交互更加直观
表单元素:
精心设计的输入框和按钮
拖放上传区域视觉反馈
进度条显示发送状态
3. JavaScript功能:
文件上传:
支持拖放和点击上传
显示已上传文件列表
文件大小格式化显示
表单验证:
必填字段验证
内容非空检查
发送流程:
模拟发送进度
成功/失败状态显示
发送另一封邮件功能
编辑器功能:
基本的文本格式化工具栏
内容可编辑区域
4. 视觉设计亮点:
渐变背景:顶部装饰性渐变条增强视觉层次
柔和阴影:卡片阴影创造深度感
图标集成:Font Awesome图标增强界面直观性
动画过渡:平滑的过渡效果提升用户体验
响应式设计:在各种设备上都能良好显示
5.截图展示:

6.代码重现:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>精美邮件发送界面</title>
<!-- 引入Google Fonts - 使用Poppins字体,现代且易读 -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap" rel="stylesheet">
<!-- 引入Font Awesome图标库 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
/* 主色调定义 - 使用柔和的蓝色和紫色渐变 */
:root {
--primary-color: #6a11cb;
--secondary-color: #2575fc;
--accent-color: #ff6b6b;
--light-color: #f8f9fa;
--dark-color: #343a40;
--success-color: #28a745;
--gradient: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
}
body {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
color: var(--dark-color);
}
/* 邮件发送容器样式 */
.email-container {
background: white;
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 800px;
overflow: hidden;
position: relative;
z-index: 1;
}
/* 容器顶部装饰性波浪形状 */
.email-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 10px;
background: var(--gradient);
z-index: -1;
}
/* 邮件头部样式 */
.email-header {
padding: 30px;
text-align: center;
background: linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.9)), url('https://images.unsplash.com/photo-1497366754035-f200968a6e72?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80');
background-size: cover;
background-position: center;
position: relative;
}
.email-header::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.7);
z-index: 1;
}
.email-header-content {
position: relative;
z-index: 2;
}
.email-header h1 {
font-size: 2.2rem;
margin-bottom: 10px;
color: var(--dark-color);
background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
display: inline-block;
font-weight: 600;
}
.email-header p {
color: #6c757d;
font-size: 1.1rem;
margin-bottom: 20px;
}
/* 邮件表单区域 */
.email-form {
padding: 30px;
position: relative;
}
/* 表单组样式 - 用于收件人、主题等输入框 */
.form-group {
margin-bottom: 25px;
position: relative;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: var(--dark-color);
font-size: 0.95rem;
}
.form-control {
width: 100%;
padding: 15px 20px;
border: 2px solid #e9ecef;
border-radius: 10px;
font-size: 1rem;
transition: all 0.3s ease;
background-color: #f8f9fa;
}
.form-control:focus {
outline: none;
border-color: var(--secondary-color);
box-shadow: 0 0 0 3px rgba(37, 117, 252, 0.2);
background-color: white;
}
/* 邮件内容编辑器样式 */
.email-editor {
min-height: 300px;
border: 2px solid #e9ecef;
border-radius: 10px;
padding: 20px;
background-color: #f8f9fa;
transition: all 0.3s ease;
}
.email-editor:focus {
border-color: var(--secondary-color);
box-shadow: 0 0 0 3px rgba(37, 117, 252, 0.2);
outline: none;
background-color: white;
}
/* 工具栏按钮样式 */
.editor-toolbar {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #e9ecef;
}
.toolbar-btn {
background: none;
border: none;
font-size: 1.2rem;
color: #6c757d;
cursor: pointer;
padding: 8px 12px;
border-radius: 8px;
transition: all 0.2s ease;
}
.toolbar-btn:hover {
background-color: #e9ecef;
color: var(--secondary-color);
}
.toolbar-btn.active {
background-color: var(--secondary-color);
color: white;
}
/* 附件上传区域 */
.attachment-area {
border: 2px dashed #e9ecef;
border-radius: 10px;
padding: 20px;
text-align: center;
margin: 25px 0;
cursor: pointer;
transition: all 0.3s ease;
background-color: #f8f9fa;
position: relative;
overflow: hidden;
}
.attachment-area:hover {
border-color: var(--secondary-color);
background-color: rgba(37, 117, 252, 0.05);
}
.attachment-area input[type="file"] {
position: absolute;
left: 0;
top: 0;
opacity: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
.attachment-icon {
font-size: 2.5rem;
color: #adb5bd;
margin-bottom: 15px;
}
.attachment-text {
color: #6c757d;
margin-bottom: 10px;
}
.attachment-hint {
font-size: 0.85rem;
color: #adb5bd;
}
/* 已上传附件列表 */
.attachments-list {
margin-top: 15px;
}
.attachment-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 15px;
background-color: rgba(37, 117, 252, 0.05);
border-radius: 8px;
margin-bottom: 10px;
}
.attachment-info {
display: flex;
align-items: center;
gap: 10px;
}
.file-icon {
color: var(--secondary-color);
}
.file-name {
font-size: 0.95rem;
color: var(--dark-color);
}
.file-size {
font-size: 0.8rem;
color: #6c757d;
}
.remove-attachment {
color: #ff6b6b;
background: none;
border: none;
cursor: pointer;
font-size: 1.1rem;
padding: 5px;
}
/* 发送按钮区域 */
.send-actions {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 30px;
flex-wrap: wrap;
gap: 15px;
}
/* 发送按钮样式 */
.btn {
padding: 12px 25px;
border: none;
border-radius: 10px;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.btn-primary {
background: var(--gradient);
color: white;
box-shadow: 0 4px 15px rgba(106, 17, 203, 0.3);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(106, 17, 203, 0.4);
}
.btn-secondary {
background-color: #f8f9fa;
color: var(--dark-color);
border: 2px solid #e9ecef;
}
.btn-secondary:hover {
background-color: #e9ecef;
border-color: #dee2e6;
}
/* 进度条样式 */
.progress-container {
margin-top: 30px;
display: none;
}
.progress-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.progress-step {
display: flex;
align-items: center;
gap: 8px;
}
.progress-circle {
width: 25px;
height: 25px;
border-radius: 50%;
background-color: #e9ecef;
display: flex;
align-items: center;
justify-content: center;
color: #6c757d;
font-size: 0.8rem;
font-weight: 500;
transition: all 0.3s ease;
}
.progress-step.active .progress-circle {
background-color: var(--secondary-color);
color: white;
}
.progress-step.completed .progress-circle {
background-color: var(--success-color);
color: white;
}
.progress-bar {
height: 5px;
background-color: #e9ecef;
border-radius: 5px;
overflow: hidden;
flex-grow: 1;
margin: 0 10px;
}
.progress-fill {
height: 100%;
width: 0%;
background-color: var(--secondary-color);
transition: width 0.5s ease;
}
/* 发送状态样式 */
.send-status {
text-align: center;
padding: 30px;
display: none;
}
.status-icon {
font-size: 3.5rem;
margin-bottom: 20px;
}
.success .status-icon {
color: var(--success-color);
}
.error .status-icon {
color: var(--accent-color);
}
.status-title {
font-size: 1.5rem;
margin-bottom: 10px;
font-weight: 500;
}
.status-message {
color: #6c757d;
margin-bottom: 20px;
}
/* 响应式调整 */
@media (max-width: 768px) {
.email-container {
border-radius: 15px;
}
.email-header {
padding: 25px;
}
.email-header h1 {
font-size: 1.8rem;
}
.email-form {
padding: 25px;
}
.btn {
width: 100%;
justify-content: center;
}
}
/* 动画效果 */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animated {
animation: fadeIn 0.5s ease forwards;
}
.delay-1 { animation-delay: 0.1s; }
.delay-2 { animation-delay: 0.2s; }
.delay-3 { animation-delay: 0.3s; }
</style>
</head>
<body>
<!-- 邮件发送主容器 -->
<div class="email-container">
<!-- 邮件头部区域 -->
<div class="email-header">
<div class="email-header-content">
<h1>发送精美邮件</h1>
<p>轻松创建并发送专业美观的电子邮件</p>
</div>
</div>
<!-- 邮件表单区域 -->
<form class="email-form" id="emailForm">
<!-- 收件人输入框 -->
<div class="form-group animated delay-1">
<label for="recipient">收件人</label>
<input type="email" id="recipient" class="form-control" placeholder="输入收件人邮箱地址" required>
</div>
<!-- 主题输入框 -->
<div class="form-group animated delay-2">
<label for="subject">邮件主题</label>
<input type="text" id="subject" class="form-control" placeholder="输入邮件主题" required>
</div>
<!-- 邮件内容编辑器 -->
<div class="form-group animated delay-3">
<label>邮件内容</label>
<div class="editor-toolbar">
<button type="button" class="toolbar-btn active" title="粗体"><i class="fas fa-bold"></i></button>
<button type="button" class="toolbar-btn" title="斜体"><i class="fas fa-italic"></i></button>
<button type="button" class="toolbar-btn" title="下划线"><i class="fas fa-underline"></i></button>
<button type="button" class="toolbar-btn" title="对齐方式"><i class="fas fa-align-left"></i></button>
<button type="button" class="toolbar-btn" title="链接"><i class="fas fa-link"></i></button>
<button type="button" class="toolbar-btn" title="图片"><i class="fas fa-image"></i></button>
<button type="button" class="toolbar-btn" title="表情"><i class="fas fa-smile"></i></button>
</div>
<div class="email-editor" contenteditable="true" placeholder="在此输入邮件内容..."></div>
</div>
<!-- 附件上传区域 -->
<div class="form-group animated delay-2">
<div class="attachment-area" id="attachmentArea">
<input type="file" id="fileUpload" multiple>
<i class="fas fa-cloud-upload-alt attachment-icon"></i>
<p class="attachment-text">拖放文件到此处或点击上传</p>
<p class="attachment-hint">支持多个文件上传 (最大25MB)</p>
</div>
<!-- 已上传附件列表 -->
<div class="attachments-list" id="attachmentsList"></div>
</div>
<!-- 发送按钮和进度条 -->
<div class="progress-container" id="progressContainer">
<div class="progress-header">
<div class="progress-step active">
<div class="progress-circle">1</div>
<span>正在发送</span>
</div>
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<div class="progress-step">
<div class="progress-circle">2</div>
<span>发送完成</span>
</div>
</div>
</div>
<!-- 发送状态 -->
<div class="send-status" id="sendStatus">
<i class="fas fa-check-circle status-icon"></i>
<h3 class="status-title success">邮件发送成功!</h3>
<p class="status-message">您的邮件已成功送达收件人邮箱。</p>
<button type="button" class="btn btn-secondary" id="sendAnother">发送另一封邮件</button>
</div>
<!-- 发送操作按钮 -->
<div class="send-actions animated delay-3">
<button type="button" class="btn btn-secondary" id="saveDraft">保存草稿</button>
<button type="submit" class="btn btn-primary" id="sendButton">
<i class="fas fa-paper-plane"></i>
<span>发送邮件</span>
</button>
</div>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取DOM元素
const emailForm = document.getElementById('emailForm');
const attachmentArea = document.getElementById('attachmentArea');
const fileUpload = document.getElementById('fileUpload');
const attachmentsList = document.getElementById('attachmentsList');
const progressContainer = document.getElementById('progressContainer');
const progressFill = document.getElementById('progressFill');
const sendStatus = document.getElementById('sendStatus');
const sendButton = document.getElementById('sendButton');
const saveDraft = document.getElementById('saveDraft');
const sendAnother = document.getElementById('sendAnother');
const editor = document.querySelector('.email-editor');
// 模拟文件拖放效果
attachmentArea.addEventListener('dragover', (e) => {
e.preventDefault();
attachmentArea.style.borderColor = 'var(--secondary-color)';
attachmentArea.style.backgroundColor = 'rgba(37, 117, 252, 0.1)';
});
attachmentArea.addEventListener('dragleave', () => {
attachmentArea.style.borderColor = '#e9ecef';
attachmentArea.style.backgroundColor = '#f8f9fa';
});
attachmentArea.addEventListener('drop', (e) => {
e.preventDefault();
attachmentArea.style.borderColor = '#e9ecef';
attachmentArea.style.backgroundColor = '#f8f9fa';
if (e.dataTransfer.files.length) {
handleFiles(e.dataTransfer.files);
}
});
// 文件上传处理
fileUpload.addEventListener('change', function() {
if (this.files.length) {
handleFiles(this.files);
}
});
function handleFiles(files) {
// 清空上传区域
fileUpload.value = '';
// 显示已上传文件
Array.from(files).forEach(file => {
const fileItem = document.createElement('div');
fileItem.className = 'attachment-item';
const fileInfo = document.createElement('div');
fileInfo.className = 'attachment-info';
const fileIcon = document.createElement('i');
fileIcon.className = 'fas fa-file file-icon';
const fileName = document.createElement('span');
fileName.className = 'file-name';
fileName.textContent = file.name;
const fileSize = document.createElement('span');
fileSize.className = 'file-size';
fileSize.textContent = formatFileSize(file.size);
const removeBtn = document.createElement('button');
removeBtn.className = 'remove-attachment';
removeBtn.type = 'button';
removeBtn.innerHTML = '<i class="fas fa-times"></i>';
removeBtn.addEventListener('click', () => {
fileItem.remove();
});
fileInfo.appendChild(fileIcon);
fileInfo.appendChild(fileName);
fileInfo.appendChild(fileSize);
fileItem.appendChild(fileInfo);
fileItem.appendChild(removeBtn);
attachmentsList.appendChild(fileItem);
});
}
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// 表单提交处理
emailForm.addEventListener('submit', function(e) {
e.preventDefault();
// 验证表单
const recipient = document.getElementById('recipient').value;
const subject = document.getElementById('subject').value;
const content = editor.innerHTML;
if (!recipient) {
alert('请输入收件人邮箱地址');
return;
}
if (!subject) {
alert('请输入邮件主题');
return;
}
if (!content || content === '<p><br></p>') {
alert('请输入邮件内容');
return;
}
// 显示发送进度
emailForm.style.display = 'none';
progressContainer.style.display = 'block';
// 模拟发送进度
let progress = 0;
const interval = setInterval(() => {
progress += Math.random() * 10;
if (progress >= 100) {
progress = 100;
clearInterval(interval);
// 发送完成
progressContainer.style.display = 'none';
sendStatus.style.display = 'block';
document.querySelector('.status-icon').className = 'fas fa-check-circle status-icon';
document.querySelector('.status-title').textContent = '邮件发送成功!';
document.querySelector('.status-message').textContent = '您的邮件已成功送达收件人邮箱。';
// 更新进度步骤
document.querySelectorAll('.progress-step').forEach((step, index) => {
if (index === 0) {
step.classList.add('completed');
step.classList.remove('active');
} else {
step.classList.add('active');
}
});
progressFill.style.width = '100%';
}
progressFill.style.width = progress + '%';
}, 300);
});
// 发送另一封邮件
sendAnother.addEventListener('click', function() {
sendStatus.style.display = 'none';
emailForm.style.display = 'block';
// 重置表单
emailForm.reset();
editor.innerHTML = '';
attachmentsList.innerHTML = '';
// 重置进度条
progressFill.style.width = '0%';
document.querySelectorAll('.progress-step').forEach(step => {
step.classList.remove('active', 'completed');
});
document.querySelector('.progress-step:first-child').classList.add('active');
});
// 保存草稿
saveDraft.addEventListener('click', function() {
const recipient = document.getElementById('recipient').value;
const subject = document.getElementById('subject').value;
const content = editor.innerHTML;
if (!recipient && !subject && (!content || content === '<p><br></p>')) {
alert('没有内容可保存');
return;
}
alert('草稿已保存!');
});
// 工具栏按钮功能
document.querySelectorAll('.toolbar-btn').forEach(btn => {
btn.addEventListener('click', function() {
// 切换活动状态
document.querySelectorAll('.toolbar-btn').forEach(b => b.classList.remove('active'));
this.classList.add('active');
// 这里可以添加实际的格式化功能
// 示例:粗体
if (this.querySelector('i').classList.contains('fa-bold')) {
document.execCommand('bold', false, null);
}
// 其他格式化命令可以类似添加
});
});
// 初始化编辑器光标
editor.addEventListener('click', function() {
this.focus();
});
});
</script>
</body>
</html>

628

被折叠的 条评论
为什么被折叠?



