解决position: fixed;弹框的中input自定义表单1px border看起来模糊问题

博客聚焦于解决1px边框在fixed状态下出现模糊的问题,介绍了两种CSS解决方案。一是使用CSS3缩放方式,通过设置transform:scaleY(0.5)来处理;二是采用边框图方式,用1px图片做border图片并设置相关样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

出现的问题:

我们想要的效果:

 

结构:

<body>
    咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩
    <div class="box">
        <div class="box_bg"></div>
        <div class="box_bubble">
            <h2>hello!muzidigbig</h2>
            <input type="text">
        </div>

    </div>
</body>

出现问题的样式:

    <style>
        .box {
            position: fixed;
            left: 0;
            top: 0;
            height: 100%;
            width: 100%;
            text-align: center;
        }
        
        .box_bg {
            position: fixed;
            left: 0;
            top: 0;
            z-index: -1;
            width: 100%;
            height: 100%;
            background-color: #000;
            filter: alpha(opacity=30);
            opacity: .3;
        }
        
        .box_bubble {
            background: #fff;
            width: 400px;
            padding: 50px;
            text-align: left;
            border: 2px solid pink;
            /* 这种定位方式会使input表单设有border的边框线加粗 */
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
        
        input {
            border: 1px solid #666;
        }
    </style>

我们想要的效果的样式:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            position: fixed;
            left: 0;
            top: 0;
            height: 100%;
            width: 100%;
            text-align: center;
        }
        
        .box::before {
            content: "";
            height: 100%;
            display: inline-block;
            vertical-align: middle;
        }
        
        .box_bg {
            position: fixed;
            left: 0;
            top: 0;
            z-index: -1;
            width: 100%;
            height: 100%;
            background-color: #000;
            filter: alpha(opacity=30);
            opacity: .3;
        }
        
        .box_bubble {
            background: #fff;
            width: 400px;
            padding: 50px;
            text-align: left;
            border: 2px solid pink;
            
            position: static;
            top: auto;
            left: auto;
            transform: none;
            margin-left: 0;
            display: inline-block;
            vertical-align: middle;
        }
        
        input {
            border: 1px solid #666;
        }
    </style>
</head>

<body>
    咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩咩
    <div class="box">
        <div class="box_bg"></div>
        <div class="box_bubble">
            <h2>hello!muzidigbig</h2>
            <input type="text">
        </div>

    </div>
</body>

</html>

这里我也有疑问   就是不知道下面这块代码表达的原理是什么?

        .box::before {
            content: "";
            height: 100%;
            display: inline-block;
            vertical-align: middle;
        }

2.css3---缩放的方式

-webkit-transform:scaleY(0.5)

transform:scaleY(0.5);

3.css3---边框图的方式

用类似的1px图片做border图片

border-width: 0 0 1px 0; border-image: url(linenew.png) 0 0 2 0 stretch;

border-width: 1px 0; border-image: url(linenew.png) 2 0 stretch;

 

固定,有颜色还得换图

 

 

 

 

以下代碼在content-display的部份在footer增加一個切換按鈕,除了原本顯示格式外,可切換成帶有html標籤的格式: <template> <div> <div> <div class="wangeditor"> <WangEditor v-model="content" @response="(msg) => content = msg" /> </div> <div class="right-panel"> <mreditor1 ref="mreditor1" /> </div> </div> <div v-if="isVisible" class="content-display" v-html="highlightedContent"></div> <footer class="sticky-footer"> <span><button @click="toggleContent">顯示/隱藏標籤</button></span> <span><button @click="resetAll" class="reset-btn">輸入新醫案</button></span> <!-- 新增ID输入和获取按钮 --> <span class="id-input"> <input v-model="fetchId" placeholder="輸入醫案ID" type="number" min="1" /> <button @click="fetchById">獲取醫案</button> </span> <!-- 操作按钮组 --> <span v-if="submittedId"> <button @click="updateContent" class="update-btn">更新醫案</button> <button @click="deleteContent" class="delete-btn">刪除醫案</button> </span> <span v-else> <button @click="submitContent" class="submit-btn">提交醫案</button> </span> <span v-if="submittedId" class="submitted-id">醫案 ID: {{ submittedId }}</span> <span>醫案編輯器</span> </footer> </div> </template> <script> import WangEditor from './WangEditor.vue'; import mreditor1 from './mreditor1.vue'; export default { components: { WangEditor, mreditor1 }, data() { return { content: '', isVisible: true, submittedId: null, fetchId: null, dnTags: [] // 存储从API获取的标签数据 }; }, computed: { // 计算高亮后的内容 highlightedContent() { if (!this.dnTags.length || !this.content) return this.content; // 创建临时DOM元素处理高亮 const tempEl = document.createElement('div'); tempEl.innerHTML = this.content; // 遍历所有文本节点 const walker = document.createTreeWalker( tempEl, NodeFilter.SHOW_TEXT ); const nodes = []; while (walker.nextNode()) { nodes.push(walker.currentNode); } // 对每个文本节点进行处理 nodes.forEach(node => { let text = node.nodeValue; let newHtml = text; // 对每个标签进行高亮处理(按长度降序排序,避免短标签优先匹配) this.dnTags .slice() .sort((a, b) => b.length - a.length) .forEach(tag => { const regex = new RegExp( escapeRegExp(tag), 'g' ); newHtml = newHtml.replace( regex, `<span style="color: rgb(212, 107, 8); font-weight: bold;">${tag}</span>` ); }); // 如果内容有化则替换节点 if (newHtml !== text) { const span = document.createElement('span'); span.innerHTML = newHtml; node.parentNode.replaceChild(span, node); } }); return tempEl.innerHTML; } }, async mounted() { // 组件挂载时获取标签数据 await this.fetchDNTags(); }, methods: { // 获取标签数据 async fetchDNTags() { try { const response = await fetch('DNTag/?format=json'); const data = await response.json(); this.dnTags = data .map(item => item.dnname) .filter(name => name && name.trim().length > 0); } catch (error) { console.error('获取标签失败:', error); alert('标签数据加载失败,高亮功能不可用'); } }, // 通过ID获取医案数据 async fetchById() { if (!this.fetchId) { alert('請輸入有效的醫案ID'); return; } try { const response = await fetch(`MRInfo/${this.fetchId}/?format=json`); if (response.ok) { const data = await response.json(); // 填充表单数据 this.$refs.mreditor1.formData.mrname = data.mrname || ''; this.$refs.mreditor1.formData.mrposter = data.mrposter || ''; this.content = data.mrcase || ''; this.submittedId = data.id; this.fetchId = null; // 清空输入 // 刷新标签数据 await this.fetchDNTags(); alert('醫案數據加載成功!'); } else if (response.status === 404) { alert('未找到該ID的醫案'); } else { throw new Error('獲取醫案失敗'); } } catch (error) { console.error('Error:', error); alert(`獲取醫案失敗: ${error.message}`); } }, // 提交医案 async submitContent() { const formData = this.$refs.mreditor1.getFormData(); const postData = { mrcase: this.content, ...formData }; try { const response = await fetch('MRInfo/?format=json', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(postData), }); if(response.ok) { const data = await response.json(); this.submittedId = data.id; alert('醫案提交成功!'); } else { throw new Error('提交失败'); } } catch (error) { console.error('Error:', error); alert(`提交失败: ${error.message}`); } }, // 更新医案 async updateContent() { if (!this.submittedId) return; const formData = this.$refs.mreditor1.getFormData(); const postData = { mrcase: this.content, ...formData }; try { const response = await fetch(`MRInfo/${this.submittedId}/?format=json`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(postData), }); if (response.ok) { alert('醫案更新成功!'); } else { throw new Error('更新失败'); } } catch (error) { console.error('Error:', error); alert(`更新失败: ${error.message}`); } }, // 删除医案 async deleteContent() { if (!this.submittedId) return; if (!confirm('確定要刪除這個醫案嗎?')) return; try { const response = await fetch(`MRInfo/${this.submittedId}/?format=json`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', } }); if (response.ok) { this.resetAll(); alert('醫案刪除成功!'); } else { throw new Error('刪除失败'); } } catch (error) { console.error('Error:', error); alert(`刪除失败: ${error.message}`); } }, // 重置表单 resetAll() { this.content = ''; this.submittedId = null; this.fetchId = null; this.$refs.mreditor1.resetForm(); }, // 切换内容显示 toggleContent() { this.isVisible = !this.isVisible; } } }; // 辅助函数:转义正则特殊字符 function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } </script> <style scoped> /* 原有样式保持不 */ .wangeditor { flex: 1; padding: 10px; overflow-y: auto; } .right-panel { position: fixed; top: 56px; bottom: 45px; right: 0; width: 30%; background: white; padding: 10px; z-index: 100; overflow-y: auto; } .content-display { position: fixed; top: 570px; left: 0; width: 70%; bottom: 45px; z-index: 999; background-color: white; overflow-y: auto; padding: 10px; border: 1px solid #eee; } .sticky-footer { display: flex; justify-content: flex-end; align-items: center; position: fixed; bottom: 0; left: 0; width: 100%; background-color: #ffd800ff; z-index: 999; padding: 10px 20px; box-sizing: border-box; flex-wrap: wrap; } .sticky-footer > span { margin-left: 5px; display: flex; align-items: center; } .submitted-id { padding: 2px; background-color: #e2f0fd; color: #004085; border-radius: 4px; } .reset-btn { margin-left: 10px; padding: 2px; background-color: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer; } .reset-btn:hover { background-color: #c82333; } /* 新增ID输入样式 */ .id-input { display: flex; align-items: center; } .id-input input { width: 100px; padding: 2px 5px; margin-right: 5px; border: 1px solid #ccc; border-radius: 4px; } /* 操作按钮样式 */ .submit-btn { background-color: #28a745; color: white; border: none; padding: 2px 8px; border-radius: 4px; cursor: pointer; } .update-btn { background-color: #007bff; color: white; border: none; padding: 2px 8px; border-radius: 4px; cursor: pointer; } .delete-btn { background-color: #dc3545; color: white; border: none; padding: 2px 8px; border-radius: 4px; cursor: pointer; } .submit-btn:hover { background-color: #218838; } .update-btn:hover { background-color: #0069d9; } .delete-btn:hover { background-color: #c82333; } </style>
最新发布
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值