This is an automated email from the ASF dual-hosted git repository.
yao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new ef72a6bf7b7f [SPARK-55775][UI] Replace inline styles with Bootstrap 5
utility classes
ef72a6bf7b7f is described below
commit ef72a6bf7b7fd0b48cd64c920fb1c8bd6de38b3a
Author: Kent Yao <[email protected]>
AuthorDate: Wed Mar 4 21:50:00 2026 +0800
[SPARK-55775][UI] Replace inline styles with Bootstrap 5 utility classes
### What changes were proposed in this pull request?
Replaces inline CSS styles with Bootstrap 5 utility classes across Spark
Web UI Scala files, producing cleaner markup and smaller HTML output.
**Conversions (10 files):**
| Inline Style | BS5 Utility |
|---|---|
| `display: flex; align-items: center` | `d-flex align-items-center` |
| `display: inline-block` / `inline` | `d-inline-block` / `d-inline` |
| `vertical-align: bottom` / `middle` | `align-bottom` / `align-middle` |
| `text-decoration: none` | `text-decoration-none` |
| `white-space: nowrap` | `text-nowrap` |
| `margin-right: 15px` | `me-3` |
| `margin-bottom: 0` | `mb-0` |
| `padding-right: 4px` | `pe-1` |
| `overflow: auto; padding: 5px` | `overflow-auto p-1` |
| `overflow: hidden; text-overflow: ellipsis` | `overflow-hidden
text-truncate` |
| `cursor: pointer` | `cursor-pointer` (new utility) |
Styles with no BS5 equivalent (e.g., `width: 60px`, `height: 80vh`) are
retained as inline styles.
### Why are the changes needed?
Consistent use of BS5 utilities instead of inline styles aligns with the
Bootstrap 5 migration (SPARK-55760). This makes the HTML cleaner, reduces
inline style declarations, and makes visibility/layout inspectable via CSS
classes.
### Does this PR introduce _any_ user-facing change?
No. Visual appearance is identical.
### How was this patch tested?
- `scalastyle` passes
- `UIUtilsSuite` (8 tests) passes
- Compilation verified for core and streaming modules
### Was this patch authored or co-authored using generative AI tooling?
Yes, co-authored with GitHub Copilot.
Closes #54614 from yaooqinn/SPARK-55775.
Authored-by: Kent Yao <[email protected]>
Signed-off-by: Kent Yao <[email protected]>
---
.../src/main/resources/org/apache/spark/ui/static/webui.css | 3 +++
.../scala/org/apache/spark/deploy/history/LogPage.scala | 2 +-
.../scala/org/apache/spark/deploy/master/ui/LogPage.scala | 2 +-
.../org/apache/spark/deploy/master/ui/MasterPage.scala | 4 ++--
.../scala/org/apache/spark/deploy/worker/ui/LogPage.scala | 2 +-
core/src/main/scala/org/apache/spark/ui/DriverLogPage.scala | 2 +-
core/src/main/scala/org/apache/spark/ui/PagedTable.scala | 13 ++++++-------
core/src/main/scala/org/apache/spark/ui/UIUtils.scala | 10 ++++------
.../org/apache/spark/ui/exec/ExecutorThreadDumpPage.scala | 4 ++--
.../src/main/scala/org/apache/spark/ui/jobs/StagePage.scala | 3 +--
.../spark/sql/connect/ui/SparkConnectServerPageSuite.scala | 4 ++--
.../sql/hive/thriftserver/ui/ThriftServerPageSuite.scala | 4 ++--
12 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/core/src/main/resources/org/apache/spark/ui/static/webui.css
b/core/src/main/resources/org/apache/spark/ui/static/webui.css
index 6f61389dc59e..86623e1dfbe4 100755
--- a/core/src/main/resources/org/apache/spark/ui/static/webui.css
+++ b/core/src/main/resources/org/apache/spark/ui/static/webui.css
@@ -15,6 +15,9 @@
* limitations under the License.
*/
+/* Utility: cursor pointer (not in BS5) */
+.cursor-pointer { cursor: pointer; }
+
html {
font-size: 14px;
}
diff --git a/core/src/main/scala/org/apache/spark/deploy/history/LogPage.scala
b/core/src/main/scala/org/apache/spark/deploy/history/LogPage.scala
index f5762abd26ac..1b809b80ee32 100644
--- a/core/src/main/scala/org/apache/spark/deploy/history/LogPage.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/history/LogPage.scala
@@ -65,7 +65,7 @@ private[history] class LogPage(conf: SparkConf) extends
WebUIPage("logPage") wit
<div>
<p><a href="/">Back to Main page</a></p>
{range}
- <div class="log-content" style="height:80vh; overflow:auto;
padding:5px;">
+ <div class="log-content overflow-auto p-1" style="height:80vh;">
<div>{moreButton}</div>
<pre>{logText}</pre>
{alert}
diff --git
a/core/src/main/scala/org/apache/spark/deploy/master/ui/LogPage.scala
b/core/src/main/scala/org/apache/spark/deploy/master/ui/LogPage.scala
index 1969888504d8..780f8a2b6c53 100644
--- a/core/src/main/scala/org/apache/spark/deploy/master/ui/LogPage.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/master/ui/LogPage.scala
@@ -64,7 +64,7 @@ private[ui] class LogPage(parent: MasterWebUI) extends
WebUIPage("logPage") with
<div>
<p><a href="/">Back to Master</a></p>
{range}
- <div class="log-content" style="height:80vh; overflow:auto;
padding:5px;">
+ <div class="log-content overflow-auto p-1" style="height:80vh;">
<div>{moreButton}</div>
<pre>{logText}</pre>
{alert}
diff --git
a/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala
b/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala
index c1ac892fe891..d751775bc33f 100644
--- a/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala
@@ -314,7 +314,7 @@ private[ui] class MasterPage(parent: MasterWebUI) extends
WebUIPage("") {
private def appRow(app: ApplicationInfo): Seq[Node] = {
val killLink = if (parent.killEnabled &&
(app.state == ApplicationState.RUNNING || app.state ==
ApplicationState.WAITING)) {
- <form action="app/kill/" method="POST" style="display:inline">
+ <form action="app/kill/" method="POST" class="d-inline">
<input type="hidden" name="id" value={app.id}/>
<input type="hidden" name="terminate" value="true"/>
<a href="#"
@@ -363,7 +363,7 @@ private[ui] class MasterPage(parent: MasterWebUI) extends
WebUIPage("") {
val killLink = if (parent.killEnabled &&
(driver.state == DriverState.RUNNING ||
driver.state == DriverState.SUBMITTED)) {
- <form action="driver/kill/" method="POST" style="display:inline">
+ <form action="driver/kill/" method="POST" class="d-inline">
<input type="hidden" name="id" value={driver.id}/>
<input type="hidden" name="terminate" value="true"/>
<a href="#"
diff --git
a/core/src/main/scala/org/apache/spark/deploy/worker/ui/LogPage.scala
b/core/src/main/scala/org/apache/spark/deploy/worker/ui/LogPage.scala
index 48213d04ddb5..adfe9670f371 100644
--- a/core/src/main/scala/org/apache/spark/deploy/worker/ui/LogPage.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/worker/ui/LogPage.scala
@@ -114,7 +114,7 @@ private[ui] class LogPage(parent: WorkerWebUI) extends
WebUIPage("logPage") with
<div>
{linkToMaster}
{range}
- <div class="log-content" style="height:80vh; overflow:auto;
padding:5px;">
+ <div class="log-content overflow-auto p-1" style="height:80vh;">
<div>{moreButton}</div>
<pre>{logText}</pre>
{alert}
diff --git a/core/src/main/scala/org/apache/spark/ui/DriverLogPage.scala
b/core/src/main/scala/org/apache/spark/ui/DriverLogPage.scala
index b563d0c49232..7b427cffcc5e 100644
--- a/core/src/main/scala/org/apache/spark/ui/DriverLogPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/DriverLogPage.scala
@@ -79,7 +79,7 @@ private[ui] class DriverLogPage(
<div>
Logs at {logDir}
{range}
- <div class="log-content" style="height:80vh; overflow:auto;
padding:5px;">
+ <div class="log-content overflow-auto p-1" style="height:80vh;">
<div>{moreButton}</div>
<pre>{logText}</pre>
{alert}
diff --git a/core/src/main/scala/org/apache/spark/ui/PagedTable.scala
b/core/src/main/scala/org/apache/spark/ui/PagedTable.scala
index 726c79edab86..847d3ffff630 100644
--- a/core/src/main/scala/org/apache/spark/ui/PagedTable.scala
+++ b/core/src/main/scala/org/apache/spark/ui/PagedTable.scala
@@ -220,8 +220,8 @@ private[spark] trait PagedTable[T] {
<div class="d-flex justify-content-between align-items-center">
<div class="d-flex align-items-center">
- <span style="padding-right: 4px;">Page: </span>
- <ul class="pagination" style="margin-bottom: 0;">
+ <span class="pe-1">Page: </span>
+ <ul class="pagination mb-0">
{if (currentGroup > firstGroup) {
<li class="page-item">
<a href={Unparsed(pageLink(startPage - groupSize))}
class="page-link"
@@ -265,10 +265,9 @@ private[spark] trait PagedTable[T] {
<form id={s"form-$navigationId-page"}
method="get"
action={Unparsed(goButtonFormPath)}
- class="d-flex align-items-center gap-1"
- style="margin-bottom: 0px;">
+ class="d-flex align-items-center gap-1 mb-0">
{hiddenFormFields}
- <label style="white-space: nowrap;">{totalPages} Pages. Jump
to</label>
+ <label class="text-nowrap">{totalPages} Pages. Jump to</label>
<input type="text"
name={pageNumberFormField}
id={s"form-$navigationId-page-no"}
@@ -276,14 +275,14 @@ private[spark] trait PagedTable[T] {
class="form-control form-control-sm"
style="width: 60px;" />
- <label style="white-space: nowrap;">. Show </label>
+ <label class="text-nowrap">. Show </label>
<input type="text"
id={s"form-$navigationId-page-size"}
name={pageSizeFormField}
value={pageSize.toString}
class="form-control form-control-sm"
style="width: 60px;" />
- <label style="white-space: nowrap;">items in a page.</label>
+ <label class="text-nowrap">items in a page.</label>
<button type="submit" class="btn btn-outline-secondary
btn-sm">Go</button>
</form>
diff --git a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
index da8733222c4a..3fedea6d6378 100644
--- a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
+++ b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
@@ -317,8 +317,7 @@ private[spark] object UIUtils extends Logging {
<div class="container-fluid">
<div class="row">
<div class="col-12">
- <h3 style="vertical-align: bottom; white-space: nowrap;
overflow: hidden;
- text-overflow: ellipsis;">
+ <h3 class="align-bottom text-nowrap overflow-hidden
text-truncate">
{title}
{helpButton}
</h3>
@@ -352,12 +351,11 @@ private[spark] object UIUtils extends Logging {
<div class="container-fluid">
<div class="row">
<div class="col-12">
- <h3 style="vertical-align: middle; display: inline-block;">
- <a style="text-decoration: none" href={prependBaseUri(request,
"/")}>
+ <h3 class="align-middle d-inline-block">
+ <a class="text-decoration-none" href={prependBaseUri(request,
"/")}>
<img src={prependBaseUri(request, "/static/spark-logo.svg")}
alt="Spark Logo" height="36" />
- <span class="version"
- style="margin-right:
15px;">{org.apache.spark.SPARK_VERSION}</span>
+ <span class="version
me-3">{org.apache.spark.SPARK_VERSION}</span>
</a>
{title}
</h3>
diff --git
a/core/src/main/scala/org/apache/spark/ui/exec/ExecutorThreadDumpPage.scala
b/core/src/main/scala/org/apache/spark/ui/exec/ExecutorThreadDumpPage.scala
index fb971b2078ad..0f6c8cacd420 100644
--- a/core/src/main/scala/org/apache/spark/ui/exec/ExecutorThreadDumpPage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/exec/ExecutorThreadDumpPage.scala
@@ -94,7 +94,7 @@ private[ui] class ExecutorThreadDumpPage(
<div class="collapsible-table collapse show"
id="thead-stack-trace-table">
{
// scalastyle:off
- <div class="thead-stack-trace-table-button" style="display: flex;
align-items: center;">
+ <div class="thead-stack-trace-table-button d-flex
align-items-center">
<a class="expandbutton"
data-action="expandAllThreadStackTrace">Expand All</a>
<a class="expandbutton d-none"
data-action="collapseAllThreadStackTrace">Collapse All</a>
<a class="downloadbutton" href={"data:text/plain;charset=utf-8," +
threadDump.map(_.toString).mkString} download={"threaddump_" + executorId +
".txt"}>Download</a>
@@ -140,7 +140,7 @@ private[ui] class ExecutorThreadDumpPage(
|""".stripMargin
<div>
<div>
- <span id="executor-flamegraph-header" style="cursor: pointer;">
+ <span id="executor-flamegraph-header" class="cursor-pointer">
<h4>
<span id="executor-flamegraph-arrow" class="arrow-open"></span>
<a>Flame Graph</a>
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
index 9e411415c375..d40ba9b1446c 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
@@ -422,8 +422,7 @@ private[ui] class StagePage(parent: StagesTab, store:
AppStatusStore) extends We
<form id={"form-event-timeline-page"}
method="get"
action=""
- class="d-flex float-end justify-content-end align-items-center
gap-1"
- style="margin-bottom: 0px;">
+ class="d-flex float-end justify-content-end align-items-center
gap-1 mb-0">
<label>Tasks: {totalTasks}. {totalPages} Pages. Jump to</label>
<input type="hidden" name="id" value={stageId.toString} />
<input type="hidden" name="attempt"
value={stageAttemptId.toString} />
diff --git
a/sql/connect/server/src/test/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPageSuite.scala
b/sql/connect/server/src/test/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPageSuite.scala
index 3c8786a42cd4..61d416328d0e 100644
---
a/sql/connect/server/src/test/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPageSuite.scala
+++
b/sql/connect/server/src/test/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPageSuite.scala
@@ -97,7 +97,7 @@ class SparkConnectServerPageSuite
assert(html.contains("dummy query"))
// Pagination support
- assert(html.contains("<label style=\"white-space: nowrap;\">1 pages. jump
to</label>"))
+ assert(html.contains("<label class=\"text-nowrap\">1 pages. jump
to</label>"))
// Hiding table support
assert(
@@ -124,7 +124,7 @@ class SparkConnectServerPageSuite
assert(html.contains("jobtag"))
// Pagination support
- assert(html.contains("<label style=\"white-space: nowrap;\">1 pages. jump
to</label>"))
+ assert(html.contains("<label class=\"text-nowrap\">1 pages. jump
to</label>"))
// Hiding table support
assert(
diff --git
a/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPageSuite.scala
b/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPageSuite.scala
index 580cac17b68c..c8972a812c62 100644
---
a/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPageSuite.scala
+++
b/sql/hive-thriftserver/src/test/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPageSuite.scala
@@ -98,7 +98,7 @@ class ThriftServerPageSuite extends SparkFunSuite with
BeforeAndAfter {
assert(html.contains("dummy plan"))
// Pagination support
- assert(html.contains("<label style=\"white-space: nowrap;\">1 pages. jump
to</label>"))
+ assert(html.contains("<label class=\"text-nowrap\">1 pages. jump
to</label>"))
// Hiding table support
assert(html.contains("class=\"collapse-table\"
data-bs-toggle=\"collapse\"" +
@@ -124,7 +124,7 @@ class ThriftServerPageSuite extends SparkFunSuite with
BeforeAndAfter {
assert(html.contains("groupid"))
// Pagination support
- assert(html.contains("<label style=\"white-space: nowrap;\">1 pages. jump
to</label>"))
+ assert(html.contains("<label class=\"text-nowrap\">1 pages. jump
to</label>"))
// Hiding table support
assert(html.contains("collapse-table\" data-bs-toggle=\"collapse\"" +
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]