新聞中心
兩周前,Adobe 發(fā)布了Web版 Photoshop,它是使用 WebAssembly、web components、P3 顏色等 Web 技術(shù)構(gòu)建的。本文就來(lái)研究一下網(wǎng)頁(yè)版 Photoshop 上有趣又有用的 CSS 知識(shí)!

湖州ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書(shū)銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書(shū)合作)期待與您的合作!
Photoshop 舊 Logo
首先,在瀏覽器控制臺(tái)中使用了 Photoshop 的 Logo(1990-1991)。
這是如何實(shí)現(xiàn)的呢?這里是代碼:
console.info(
"%c %cAdobe %cPhotoshop Web%c %c2023.20.0.0%c %c1bba617e276",
"padding-left: 36px; line-height: 36px; background-image: url('data:image/gif;base64,R0lGODlhIAAgAPEBAAAAAPw==');"
)Body 元素
要讓像Photoshop這樣的應(yīng)用在Web上感覺(jué)像一個(gè)真正的應(yīng)用,第一件事是防止滾動(dòng)。為了實(shí)現(xiàn)這一點(diǎn),
元素具有position: fixed和overflow: hidden。body,
html {
height: 100%;
}
body {
font-family: adobe-clean, sans-serif;
margin: 0;
overflow: hidden;
position: fixed;
width: 100%;
}在
元素內(nèi)部,也有多個(gè)根元素。
最內(nèi)部有一個(gè)包含導(dǎo)航和文檔頁(yè)面的元素。
#appView {
background-color: var(--editor-background-color);
color: var(--spectrum-global-color-gray-800);
display: flex;
flex-direction: column;
}
* {
touch-action: manipulation;
}
:host {
position: relative;
}Flexbox 布局
在構(gòu)建現(xiàn)代的 Web 應(yīng)用時(shí),使用 Flex 布局具有很多好處。網(wǎng)頁(yè)版 Photoshop 就用到了很多 Flex 布局。
使用 Flexbox 使構(gòu)建組件變得更容易。下面來(lái)看幾個(gè)使用 Flexbox 的例子。
導(dǎo)航欄
我很喜歡這部分的元素類命名,它沒(méi)有使用 left、center、right,而是使用了start、center、end。
在應(yīng)用可以從左到右(LTR)或從右到左(RTL)工作時(shí),這種邏輯命名是正確的做法。
操作
在構(gòu)建像 Photoshop 這樣的復(fù)雜應(yīng)用時(shí),嵌套的 Flexbox 容器是很常見(jiàn)的。下圖顯示了操作欄中的兩個(gè)容器。
第一個(gè)容器用于縮放。第二個(gè)容器包含所有的操作和按鈕。
.container {
display: flex;
flex-wrap: nowrap;
align-items: center;
gap: var(--spectrum-global-dimension-size-50);
}- 使用gap屬性非常有助于定義間距,使用margin或padding來(lái)實(shí)現(xiàn)這個(gè)效果可能會(huì)變得混亂。
- .container這個(gè)類名太過(guò)通用了,但在這里非常適用,因?yàn)檫@是一個(gè)Web組件,所以所有的樣式都被封裝起來(lái)了。
圖層
圖層功能是Photoshop的重要組成部分,仔細(xì)觀察CSS,發(fā)現(xiàn)它們?nèi)慷际?Flexbox 布局。
下面是圖層組件的 HTML 結(jié)構(gòu):
這里使用 ID 是完全沒(méi)問(wèn)題的,因?yàn)檫@是一個(gè) Web 組件,因此 #first-column ID 在頁(yè)面上出現(xiàn)多少次并不重要。
#link元素是一個(gè) Flexbox 容器,#label元素也是一個(gè) Flexbox 容器。
Layer name
下面來(lái)舉一個(gè)例子說(shuō)明如何完成子層的縮進(jìn)。
- :host()表示圖層組件。
- 這感覺(jué)像是條件式 CSS。如果HTML屬性indent=1存在,那么就更改第一列的padding-right。
:host([dir="ltr"][indent="1"]) #first-column {
padding-right: var(--spectrum-global-dimension-size-200);
}如果縮進(jìn)是兩個(gè)級(jí)別,那么可以通過(guò)CSS的calc()函數(shù),將padding-right的值乘以 2。
:host([dir="ltr"][indent="2"]) #first-column {
padding-right: calc(2 * var(--spectrum-global-dimension-size-200));
}在瀏覽器中,嘗試嵌套到第 6 層:
而老牌的設(shè)計(jì)軟件 Figma 是使用間隔組件來(lái)增加嵌套層的間距的。
Grid 布局
新文件模式
在創(chuàng)建新的 Photoshop 文件時(shí),可以選擇預(yù)定義的尺寸列表。為了實(shí)現(xiàn)這一點(diǎn),有一個(gè)包含多個(gè)選項(xiàng)卡和一個(gè)活動(dòng)面板的布局。
HTML 如下所示:
在 CSS 中,有一個(gè) 1 列 2 行的主網(wǎng)格。其中,第一行的高度根據(jù)內(nèi)容自適應(yīng)調(diào)整行高,而第二行則占據(jù)了所有剩余可用空間。
:host {
display: grid;
grid-template-columns: 100%;
}
:host(:not([direction^="vertical"])) {
grid-template-rows: auto 1fr;
}這里有幾個(gè)要點(diǎn):
- 使用CSS的:not()選擇器。
- 使用[attr^=value]選擇器來(lái)排除具有以vertical開(kāi)頭的值的direction屬性的HTML元素。
這些都是條件式 CSS 技術(shù)。
嘗試將direction屬性更改為vertical,結(jié)果符合預(yù)期。
下面是基于屬性變化的CSS:
:host([direction^="vertical"]) {
grid-template-columns: auto 1fr;
}
:host([direction^="vertical-right"]) #list #selection-indicator,
:host([direction^="vertical"]) #list #selection-indicator {
inline-size: var(
--mod-tabs-divider-size,
var(--spectrum-tabs-divider-size)
);
inset-block-start: 0px;
inset-inline-start: 0px;
position: absolute;
}為了突出顯示哪個(gè)選項(xiàng)卡是活動(dòng)狀態(tài),有一個(gè)相對(duì)于選項(xiàng)卡列表定位的#selection-indicator元素。
圖層屬性
這部分的 CSS 網(wǎng)格用法很有趣,它適合解決對(duì)齊網(wǎng)格中許多元素的問(wèn)題。
深入研究 CSS:
.content {
position: relative;
display: grid;
grid-template-rows: [horizontal] min-content [vertical] min-content [transforms] min-content [end];
grid-template-columns: [size-labels] min-content [size-inputs] auto [size-locks] min-content [space] min-content [position-labels] min-content [position-inputs] auto [end];
row-gap: var(--spectrum-global-dimension-size-150);
}使用 Firfox 開(kāi)發(fā)者工具來(lái)調(diào)試這個(gè)網(wǎng)格,它會(huì)生成模擬的網(wǎng)格布局。當(dāng)突出顯示矩形時(shí),它將顯示放置在實(shí)際的網(wǎng)格中。
這里使用的技術(shù)就是命名網(wǎng)格線,其思想是給每個(gè)列或行指定一個(gè)名稱,然后定義其寬度。列和行的寬度可以是auto或min-content,這是創(chuàng)建動(dòng)態(tài)網(wǎng)格的一種很好的方法。
這樣,每個(gè)網(wǎng)格項(xiàng)都可以在網(wǎng)格內(nèi)部進(jìn)行定位:
.horizontal-size-label {
grid-area: horizontal / size-labels / horizontal / size-labels;
}
.vertical-position-input {
grid-area: vertical / position-inputs / vertical / position-inputs;
}
.horizontal-position-input {
grid-area: horizontal / position-inputs / horizontal /
position-inputs;
}還有一個(gè)細(xì)節(jié)是對(duì)網(wǎng)格項(xiàng)使用了position: absolute。鎖定按鈕位于網(wǎng)格的中心,但它需要略微從左邊和頂部位置進(jìn)行插入。
.lock-button {
grid-area: horizontal / size-locks / horizontal / size-locks;
position: absolute;
left: 8px;
top: 22px;
}輸入
下面來(lái)看看使用 CSS 網(wǎng)格來(lái)布局輸入字段的用例。
:host([editable]) {
display: grid;
grid-template-areas:
"label ."
"slider number";
grid-template-columns: 1fr auto;
}
:host([editable]) #label-container {
grid-area: label / label / label / label;
}
:host([editable]) #label-container + div {
grid-area: slider / slider / slider / slider;
}
:host([editable]) sp-number-field {
grid-area: number / number / number / number;
}在瀏覽器中檢查時(shí),可以看到網(wǎng)格線名稱或網(wǎng)格區(qū)域名稱。
- 網(wǎng)格區(qū)域名稱
- 網(wǎng)格線名稱
菜單項(xiàng)
在我看來(lái),在這里使用 CSS 網(wǎng)格有點(diǎn)大材小用了。
sp-menu-item {
display: grid;
grid-template-areas:
". chevronAreaCollapsible . iconArea sectionHeadingArea . . ."
"selectedArea chevronAreaCollapsible checkmarkArea iconArea labelArea valueArea actionsArea chevronAreaDrillIn"
". . . . descriptionArea . . ."
". . . . submenuArea . . .";
grid-template-columns: auto auto auto auto 1fr auto auto auto;
grid-template-rows: 1fr auto auto auto;
}這是一個(gè)包含 8列 4行的網(wǎng)格。這里似乎一次只能激活一個(gè)網(wǎng)格行,其他行將由于內(nèi)容為空或HTML元素的缺失而折疊。
有趣的是,上面的 CSS 是簡(jiǎn)化過(guò)的版本。原始版本看起來(lái)像這樣,使用了grid-template縮寫(xiě)。
下面是在應(yīng)用中找到的一些菜單項(xiàng):
CSS 網(wǎng)格是針對(duì)這個(gè)小組件的,感覺(jué)是有點(diǎn)多此一舉了。
.checkmark {
align-self: start;
grid-area: checkmarkArea / checkmarkArea / checkmarkArea /
checkmarkArea;
}
#label {
grid-area: labelArea / labelArea / labelArea / labelArea;
}
::slotted([slot="value"]) {
grid-area: valueArea / valueArea / valueArea / valueArea;
}注意,CSS 網(wǎng)格的暗部分處于非活動(dòng)狀態(tài)。它們折疊了,因?yàn)闆](méi)有內(nèi)容。對(duì)于這個(gè)例子,也可以這樣來(lái)實(shí)現(xiàn):
.checkmark {
align-self: start;
grid-area: checkmarkArea;
}
#label {
grid-area: labelArea;
}
::slotted([slot="value"]) {
grid-area: valueArea;
}當(dāng)每列和行的值相同時(shí),無(wú)需定義它們的開(kāi)始和結(jié)束位置。
CSS變量的廣泛使用
更改圖層縮略圖的大小
Photoshop 可以控制縮略圖大小。當(dāng)有很多圖層并且想要在更小的空間中查看更多圖層時(shí),這非常有用。
Adobe 團(tuán)隊(duì)的構(gòu)建方式很有趣。首先,圖層面板的主容器上有一個(gè) HTML 屬性large-thumbs。
在CSS中,有一個(gè):host([large-thumbs])選擇器,它分配了特定的CSS變量。
:host([large-thumbs]) {
--psw-custom-layer-thumbnail-size: var(
--spectrum-global-dimension-size-800
);
--psw-custom-layer-thumbnail-border-size: var(
--spectrum-global-dimension-size-50
);
}對(duì)于每個(gè)圖層,都有一個(gè)名為 psw-layer-thumbnail 的元素,這是將應(yīng)用CSS變量的地方。
這里,CSS 變量被分配給縮略圖。
:host {
--layer-thumbnail-size: var(
--psw-custom-layer-thumbnail-size,
var(--spectrum-global-dimension-size-400)
);
--layer-badge-size: var(--spectrum-global-dimension-size-200);
position: relative;
width: var(--layer-thumbnail-size);
min-width: var(--layer-thumbnail-size);
height: var(--layer-thumbnail-size);
}加載進(jìn)度
通過(guò)使用size屬性來(lái)管理組件的大小。CSS 變量會(huì)根據(jù)不同的 size 而變化。
:host([size="m"]) {
--spectrum-progressbar-size-default: var(
--spectrum-progressbar-size-2400
);
--spectrum-progressbar-font-size: var(--spectrum-font-size-75);
--spectrum-progressbar-thickness: var(
--spectrum-progress-bar-thickness-large
);
--spectrum-progressbar-spacing-top-to-text: var(
--spectrum-component-top-to-text-75
);
}圖像控制
如果 HTML 存在屬性quiet,則 UI 會(huì)更簡(jiǎn)單(沒(méi)有邊框)。
這也是通過(guò) CSS 變量完成的。
:host([quiet]) {
--spectrum-actionbutton-background-color-default: var(
--system-spectrum-actionbutton-quiet-background-color-default
);
--spectrum-actionbutton-background-color-hover: var(
--system-spectrum-actionbutton-quiet-background-color-hover
);
}單選按鈕
在這個(gè)例子中,使用 CSS 變量來(lái)根據(jù) HTML 的 size 屬性值來(lái)改變單選按鈕的大小。
:host([size="m"]) {
--spectrum-radio-height: var(--spectrum-component-height-100);
--spectrum-radio-button-control-size: var(
--spectrum-radio-button-control-size-medium
);
}菜單處于活動(dòng)狀態(tài)時(shí)鎖定頁(yè)面
當(dāng)主菜單處于活動(dòng)狀態(tài)時(shí),會(huì)有一個(gè)名為 holder 的元素填充整個(gè)屏幕(遮罩層),并位于菜單下方。
#actual[aria-hidden] + #holder {
display: flex;
}
#holder {
display: none;
align-items: center;
justify-content: center;
flex-flow: column;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}此元素是為了防止用戶單擊或?qū)⑹髽?biāo)懸停在頁(yè)面的其他部分,以確保用戶只能對(duì)菜單進(jìn)行操作,這可能是為了模仿桌面應(yīng)用而設(shè)置的。
混合模式菜單
這里使用了 CSS 視口單位?;旌夏J讲藛蔚淖畲蟾叨葹?nbsp;55vh(視口高度的55%)。
sp-menu {
max-height: 55vh;
--mod-menu-item-min-height: auto;
}
::slotted(*) {
overscroll-behavior: contain;
}這里還使用了 overscroll-behavior: contains,這是避免滾動(dòng)正文內(nèi)容的一個(gè)很棒的功能。
圖層縮略圖
在圖層面板中,縮略圖使用了object-fit: contain來(lái)避免變形。
網(wǎng)頁(yè)題目:深入研究了Web版Photoshop,發(fā)現(xiàn)了這些有趣又有用的CSS知識(shí)!
文章分享:http://www.5511xx.com/article/djgissg.html


咨詢
建站咨詢
