// 获取DOM元素
const cssInput = document.getElementById(‘cssInput’);
const output = document.getElementById(‘output’);
const formatBtn = document.getElementById(‘formatBtn’);
const copyBtn = document.getElementById(‘copyBtn’);
const downloadBtn = document.getElementById(‘downloadBtn’);
const fileInput = document.getElementById(‘fileInput’);
const toast = document.getElementById(‘toast’);
// 获取所有选项元素
const options = {
sortProperties: document.getElementById(‘sortProperties’),
removeComments: document.getElementById(‘removeComments’),
alignColons: document.getElementById(‘alignColons’),
compressOutput: document.getElementById(‘compressOutput’),
vendorPrefix: document.getElementById(‘vendorPrefix’),
removeEmptyRules: document.getElementById(‘removeEmptyRules’),
convertRGBToHex: document.getElementById(‘convertRGBToHex’),
removeLastSemicolon: document.getElementById(‘removeLastSemicolon’),
indentSize: document.getElementById(‘indentSize’)
};
// 显示提示信息的函数
function showToast(message, isError = false) {
toast.textContent = message;
toast.classList.toggle(‘error’, isError);
toast.classList.add(‘show’);
setTimeout(() => toast.classList.remove(‘show’), 3000);
}
// 创建粒子效果的函数
function createParticles(x, y) {
const particleCount = 15;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.classList.add('particle');
const size = Math.random() * 8 + 4;
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
particle.style.left = `${x}px`;
particle.style.top = `${y}px`;
const angle = Math.random() * Math.PI * 2;
const distance = Math.random() * 100;
document.body.appendChild(particle);
const animation = particle.animate(
[
{ transform: 'translate(0, 0)', opacity: 1 },
{ transform: `translate(${Math.cos(angle) * distance}px, ${Math.sin(angle) * distance}px)`, opacity: 0 }
],
{ duration: 800, easing: 'ease-out' }
);
animation.onfinish = () => {
particle.remove();
};
}
}
// 将RGB转换为十六进制颜色的函数
function rgbToHex(rgb) {
const match = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
if (!match) return rgb;
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const toHex = (n) => {
const hex = n.toString(16);
return hex.length === 1 ? ‘0’ + hex : hex;
};
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
// 格式化CSS的函数
function formatCSS(css) {
// 如果选项被选中,则删除注释
if (options.removeComments.checked) {
css = css.replace(/\/\*[\s\S]*?\*\//g, ”);
}
// 分割成规则
let rules = css.split(‘}’)
.filter(rule => rule.trim())
.map(rule => {
let [selector, properties] = rule.split(‘{‘);
if (!properties) return ”;
// 整理选择器
selector = selector.trim();
// 如果选项被选中,则跳过空规则
if (options.removeEmptyRules.checked && !properties.trim()) {
return ”;
}
// 将属性分割成数组
let propsArray = properties
.split(‘;’)
.filter(prop => prop.trim())
.map(prop => prop.trim());
// 排序厂商前缀
if (options.vendorPrefix.checked) {
propsArray.sort((a, b) => {
const aPrefix = a.match(/^-\w+-/) || [”];
const bPrefix = b.match(/^-\w+-/) || [”];
return aPrefix[0].localeCompare(bPrefix[0]);
});
}
// 如果选项被选中,则排序属性
if (options.sortProperties.checked) {
propsArray.sort((a, b) => {
const aProp = a.split(‘:’)[0].trim();
const bProp = b.split(‘:’)[0].trim();
return aProp.localeCompare(bProp);
});
}
// 如果选项被选中,则将RGB转换为十六进制
if (options.convertRGBToHex.checked) {
propsArray = propsArray.map(prop => {
const [name, value] = prop.split(‘:’);
if (value && value.includes(‘rgb(‘)) {
return `${name}: ${rgbToHex(value.trim())}`;
}
return prop;
});
}
// 查找属性名的最大长度,用于冒号对齐
let maxPropLength = 0;
if (options.alignColons.checked) {
propsArray.forEach(prop => {
const propName = prop.split(‘:’)[0];
maxPropLength = Math.max(maxPropLength, propName.trim().length);
});
}
const indent = ‘ ‘.repeat(parseInt(options.indentSize.value));
// 格式化属性
let formattedProps = propsArray.map((prop, index) => {
let [propName, propValue] = prop.split(‘:’);
propName = propName.trim();
propValue = propValue ? propValue.trim() : ”;
if (options.alignColons.checked) {
const padding = ‘ ‘.repeat(maxPropLength – propName.length);
return `${indent}${propName}${padding}: ${propValue}`;
} else {
return `${indent}${propName}: ${propValue}`;
}
});
// 如果选项被选中,则删除最后一个分号
if (options.removeLastSemicolon.checked && formattedProps.length > 0) {
formattedProps[formattedProps.length – 1] = formattedProps[formattedProps.length – 1].replace(‘;’, ”);
}
// 连接属性
let result = formattedProps.join(‘;\n’);
if (!options.removeLastSemicolon.checked) {
result += ‘;’;
}
// 组合选择器和属性
if (options.compressOutput.checked) {
return `${selector}{${formattedProps.join(‘;’)}}`;
} else {
return `${selector} {\n${result}\n}`;
}
})
.filter(rule => rule); // 移除空规则
return options.compressOutput.checked ?
rules.join(”) :
rules.join(‘\n\n’);
}
// 文件导入处理程序
fileInput.addEventListener(‘change’, (e) => {
const file = e.target.files[0];
if (file && file.type === ‘text/css’) {
const reader = new FileReader();
reader.onload = (event) => {
cssInput.value = event.target.result;
showToast(‘CSS文件导入成功’);
};
reader.onerror = () => {
showToast(‘读取文件时出错’, true);
};
reader.readAsText(file);
} else {
showToast(‘请选择有效的CSS文件’, true);
}
});
// 格式化按钮处理程序
formatBtn.addEventListener(‘click’, (e) => {
const css = cssInput.value.trim();
if (!css) {
showToast(‘请输入CSS代码’, true);
return;
}
try {
const formattedCSS = formatCSS(css);
output.value = formattedCSS;
copyBtn.disabled = !formattedCSS;
downloadBtn.disabled = !formattedCSS;
const rect = e.target.getBoundingClientRect();
createParticles(e.clientX, rect.top);
showToast(‘CSS已成功格式化’);
} catch (error) {
showToast(‘格式化CSS时出错’, true);
console.error(error);
}
});
// 复制按钮处理程序
copyBtn.addEventListener(‘click’, async () => {
try {
await navigator.clipboard.writeText(output.value);
showToast(‘CSS已复制到剪贴板’);
const originalText = copyBtn.textContent;
copyBtn.textContent = “已复制!”;
setTimeout(() => {
copyBtn.textContent = originalText;
}, 2000);
} catch (error) {
showToast(‘复制到剪贴板时出错’, true);
}
});
// 下载按钮处理程序
downloadBtn.addEventListener(‘click’, () => {
try {
const blob = new Blob([output.value], { type: ‘text/css’ });
const url = URL.createObjectURL(blob);
const a = document.createElement(‘a’);
a.href = url;
a.download = ‘formatted.css’;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showToast(‘CSS文件已下载’);
} catch (error) {
showToast(‘下载文件时出错’, true);
}
});
// 输入变化处理程序
cssInput.addEventListener(‘input’, () => {
copyBtn.disabled = true;
downloadBtn.disabled = true;
});
// 初始化
copyBtn.disabled = true;
downloadBtn.disabled = true;
什么是 CSS 格式化工具?
CSS 格式化工具是一种通过添加适当的缩进、空格和换行来组织和美化 CSS 代码的工具。它提高了 CSS 文件的可读性和一致性。
为什么要使用 CSS 格式化工具?
使用 CSS 格式化工具可以使 CSS 代码更易读和调试,确保团队或项目中的格式一致,帮助发现语法错误或冗余代码,并提升维护性,尤其是针对大型 CSS 文件。
CSS 格式化工具是如何工作的?
CSS 格式化工具将 CSS 代码解析为其结构组件(选择器、属性、值),使用一致的缩进、换行和空格重新组织代码,并输出格式化后的 CSS,同时保持其功能不变。
我可以自定义格式化规则吗?
可以,您可以选择多种格式化选项和规则,包括压缩和缩小 CSS、属性排序、对齐冒号、移除注释、缩进样式等。
CSS 格式化工具会影响我的代码功能吗?
不会,我们的 CSS 格式化工具只改变代码的外观,不改变其行为。它确保 CSS 保持有效且可正常工作。
CSS 格式化工具能处理大文件吗?
可以,我们的 CSS 格式化工具能够处理大文件。但对于非常大的文件,性能可能取决于您的浏览器和系统资源。
格式化和压缩 CSS 有什么区别?
格式化 CSS 通过合理的缩进和空格组织代码,提高可读性;压缩 CSS 则通过删除不必要的字符(如空白、注释)来减小文件大小,而不改变功能。