The Focus Cell feature highlights the active cell with a semi-transparent overlay on its entire row and column, making it easier to identify the current position in a large spreadsheet.
You can configure the focusCell through the workbook options:
Enable or Disable
Use the enabled property to toggle the focus cell highlight:
Color
Set the highlight color using theme colors or RGBA values(the opacity from color as high priority):
Opacity
Adjust the transparency of the highlight overlay:
<template>
<div class="sample-tutorial">
<div class="sample-spreadsheets">
<gc-spread-sheets :hostStyle="hostStyle" @workbookInitialized="initSpread">
<gc-worksheet></gc-worksheet>
</gc-spread-sheets>
</div>
<aside class="options-container" aria-label="Focus Cell Settings">
<div class="panel-header">
<h1>Focus Cell Settings</h1>
<p class="panel-description">Change the properties below to see how they affect the focus cell highlight.</p>
</div>
<section class="control-section">
<h2>Availability</h2>
<label class="check-field" for="chk_enabled">
<input type="checkbox" id="chk_enabled" v-model="focusCellEnabled" @change="updateFocusCell" />
<span>
<strong>Enable Focus Cell</strong>
</span>
</label>
</section>
<section class="control-section">
<h2>Highlight Style</h2>
<div class="field">
<label for="focusCellColor">Color</label>
<div class="field-row">
<input type="text" id="focusCellColor" v-model="focusCellColor" :disabled="!focusCellEnabled" />
<input type="button" value="Set" id="setFocusCellColor" @click="updateFocusCell" :disabled="!focusCellEnabled" class="narrow" />
</div>
</div>
<div class="field">
<label for="focusCellOpacity">Opacity</label>
<div class="field-row range-field">
<input type="range" id="focusCellOpacity" min="0" max="1" step="0.01"
v-model.number="focusCellOpacity" @input="updateFocusCell" :disabled="!focusCellEnabled" />
<span class="opacity-value">{{ focusCellOpacity.toFixed(2) }}</span>
</div>
</div>
</section>
</aside>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { data } from './dataset.js';
const hostStyle = { width: '100%', height: '100%' };
const spread = ref(null);
const focusCellEnabled = ref(false);
const focusCellColor = ref('');
const focusCellOpacity = ref(0);
function initSpread(workbook) {
spread.value = workbook;
workbook.fromJSON(data[0]);
// Enable focus cell and read options to init component values
workbook.options.focusCell.enabled = true;
var focusCell = workbook.options.focusCell || {};
focusCellEnabled.value = true;
focusCellColor.value = focusCell.color || '';
focusCellOpacity.value = focusCell.opacity || 0.22;
}
function updateFocusCell() {
if (!spread.value) return;
spread.value.options.focusCell = {
enabled: focusCellEnabled.value,
color: focusCellColor.value,
opacity: focusCellOpacity.value
};
}
</script>
<style>
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 0;
color: #1f2933;
background: #f7f8fa;
}
#app {
height: 100%;
}
.sample-tutorial {
display: flex;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
flex: 1 1 auto;
min-width: 0;
height: 100%;
overflow: hidden;
}
.options-container {
flex: 0 0 320px;
width: 320px;
height: 100%;
padding: 24px 20px;
box-sizing: border-box;
overflow: auto;
background: #fff;
border-left: 1px solid #e5e7eb;
}
.panel-header {
padding-bottom: 20px;
border-bottom: 1px solid #eef0f3;
}
.panel-header h1 {
margin: 0;
font-size: 20px;
font-weight: 650;
line-height: 1.25;
}
.panel-description {
margin: 10px 0 0;
color: #6b7280;
font-size: 13px;
line-height: 1.6;
}
.control-section {
padding: 20px 0;
border-bottom: 1px solid #eef0f3;
}
.control-section:last-child {
border-bottom: 0;
}
.control-section h2 {
margin: 0 0 14px;
color: #374151;
font-size: 13px;
font-weight: 700;
line-height: 1.3;
}
.field {
display: grid;
gap: 7px;
margin-bottom: 14px;
}
.field:last-child {
margin-bottom: 0;
}
.options-container label {
color: #374151;
font-size: 13px;
font-weight: 600;
line-height: 1.35;
}
.field-row {
display: flex;
align-items: center;
gap: 8px;
}
.field-row input[type="text"] {
flex: 1 1 auto;
min-width: 0;
}
.options-container input[type="text"],
.options-container input[type="button"].narrow {
height: 34px;
box-sizing: border-box;
font: inherit;
border-radius: 6px;
}
.options-container input[type="text"] {
width: 100%;
padding: 0 10px;
color: #111827;
background: #fff;
border: 1px solid #d8dde5;
outline: none;
transition: border-color .15s ease, box-shadow .15s ease;
}
.options-container input[type="text"]:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, .12);
}
.options-container input[type="button"].narrow {
flex: 0 0 60px;
width: 60px;
color: #fff;
border: 1px solid #2563eb;
background: #2563eb;
cursor: pointer;
}
.options-container input[type="button"].narrow:hover:not(:disabled) {
background: #1d4ed8;
}
.options-container input:disabled {
color: #8d969e;
border-color: #d9dee3;
background: #eef1f4;
cursor: not-allowed;
}
.check-field {
display: flex;
gap: 10px;
align-items: flex-start;
padding: 10px 0;
cursor: pointer;
}
.check-field input {
width: 16px;
height: 16px;
margin: 2px 0 0;
accent-color: #2563eb;
flex: 0 0 auto;
}
.check-field span {
display: grid;
gap: 3px;
}
.check-field strong {
color: #1f2933;
font-size: 13px;
font-weight: 650;
line-height: 1.35;
}
.range-field input[type="range"] {
flex: 1 1 auto;
min-width: 0;
margin: 0;
accent-color: #2563eb;
}
.opacity-value {
flex: 0 0 auto;
min-width: 38px;
padding: 4px 7px;
color: #2f4f6f;
text-align: center;
border-radius: 6px;
background: #e9f1fb;
font-size: 13px;
line-height: 1.4;
}
@media (max-width: 760px) {
.sample-tutorial {
flex-direction: column;
}
.sample-spreadsheets {
min-height: 55%;
}
.options-container {
flex: 0 0 auto;
width: 100%;
height: 45%;
border-top: 1px solid #e5e7eb;
border-left: 0;
}
}
</style>
<!DOCTYPE html>
<html style="height:100%;font-size:14px;">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>SpreadJS VUE</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css"
href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script>
<script src="./systemjs.config.js"></script>
<script src="./compiler.js" type="module"></script>
<script>
var System = SystemJS;
System.import("./src/app.js");
System.import('$DEMOROOT$/en/lib/vue3/license.js');
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
(function (global) {
SystemJS.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true
},
paths: {
// paths serve as alias
'npm:': 'node_modules/',
'cdn:': 'https://cdn.mescius.io/demoapps/packages/spreadjs/19.2.2-master-2026-09-02-2133/'
},
packageConfigPaths: [
'./node_modules/*/package.json',
"./node_modules/@mescius/*/package.json",
"./node_modules/@babel/*/package.json",
"./node_modules/@vue/*/package.json"
],
map: {
'vue': "npm:vue/dist/vue.esm-browser.js",
'tiny-emitter': 'npm:tiny-emitter/index.js',
'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js',
"systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js",
'@mescius/spread-sheets': 'cdn:@mescius/spread-sheets/index.js',
'@mescius/spread-sheets-shapes': 'cdn:@mescius/spread-sheets-shapes/index.js',
'@mescius/spread-sheets-slicers': 'cdn:@mescius/spread-sheets-slicers/index.js',
'@mescius/spread-sheets-charts': 'cdn:@mescius/spread-sheets-charts/index.js',
'@mescius/spread-sheets-vue': 'cdn:@mescius/spread-sheets-vue/index.js',
},
meta: {
'*.css': { loader: 'systemjs-plugin-css' },
'*.vue': { loader: "../plugin-vue/index.js" }
}
});
})(this);