html-css-display: flex 完整使用说明

display: flex 完整使用说明
一、基础概念
display: flex 给父容器设置,开启弹性布局;子元素自动成为弹性项 (flex-item)。
注意:样式写在父盒子上,不要写在子元素!
css
.box { display: flex; /* 开启弹性布局 */}
二、父容器(flex 容器)常用属性
1. flex-direction:主轴方向
css
flex-direction: row; /* 默认,水平从左→右 */
flex-direction: row-reverse; /* 水平 右→左 */
flex-direction: column; /* 垂直 上→下 */
flex-direction: column-reverse;/* 垂直 下→上 */

2. flex-wrap:是否换行
css
flex-wrap: nowrap; /* 默认,不换行,子元素压缩挤在一行 */
flex-wrap: wrap; /* 空间不足自动换行 */
flex-wrap: wrap-reverse; /* 换行,行顺序反转 */

3. flex-flow 简写 = flex-direction + flex-wrap
css
flex-flow: row wrap;
4. justify-content:主轴对齐(水平默认主轴)
css
justify-content: flex-start; /* 默认,靠起点 */
justify-content: flex-end; /* 靠终点 */
justify-content: center; /* 居中 */
justify-content: space-between; /* 两端对齐,子元素之间均分空隙 */
justify-content: space-around; /* 每个元素左右都有同等空隙 */
justify-content: space-evenly; /* 所有间隙完全相等 */

5. align-items:单行交叉轴对齐(垂直方向)
css
align-items: stretch; /* 默认,拉伸填满容器高度 */
align-items: flex-start; /* 顶部对齐 */
align-items: flex-end; /* 底部对齐 */
align-items: center; /* 垂直居中 */
align-items: baseline; /* 按文字基线对齐 */

6. align-content:多行弹性项交叉轴对齐(只有开启 wrap 换行才生效)
css
align-content: stretch;
align-content: center;
align-content: flex-start;
align-content: flex-end;
align-content: space-between;
align-content: space-around;

三、子元素(flex-item)属性
1. flex-grow:剩余空间分配(放大比例)
默认 0,不放大;数值越大分得越多空白区域
css
.item { flex-grow: 1; /* 所有子元素均分剩余宽度 */ }
2. flex-shrink:空间不足时缩小比例
默认 1,空间不够会自动缩小;设为 0 禁止缩小
css
flex-shrink: 0;
3. flex-basis:弹性项基准尺寸
相当于弹性布局下的初始宽 / 高,优先级高于 width
css
flex-basis: 200px;
4. flex 简写:flex: grow shrink basis
css
flex: 1; /* 等价 flex:1 1 0%; 均分空间,最常用 */
flex: 0 1 auto;/* 默认值 */
flex: 0 0 150px; /* 固定尺寸,不放大不缩小 */

5. align-self:单独控制某个子元素交叉轴对齐
覆盖父容器 align-items
css
align-self: center | flex-start | flex-end | stretch;
6. order:控制子元素排序
默认 0,数值越小越靠前,可以负数
css
order: -1; /* 跑到最前面 */
四、高频实用示例
示例 1:水平垂直居中(最常用)
css
.box {
width: 400px;
height: 300px;
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}

示例 2:导航栏,均匀分布、自动换行
css
.nav { display: flex; flex-wrap: wrap; justify-content: space-between; }
示例 3:左右固定,中间自适应布局
html
预览

<div class="wrap">
  <div class="left">左</div>
  <div class="main">自适应中间</div>
  <div class="right">右</div>
</div>

css

.wrap {  display: flex;}
.left,.right {  flex: 0 0 120px; /* 固定宽度,不缩放 */}
.main {  flex: 1; /* 自动占满剩余空间 */}

五、常见坑点
浮动 float、vertical-align 对 flex-item 失效
弹性子元素默认不会文字自动换行,长文本需要手动加 word-break:break-all
align-content 多行才生效,单行无效,别和 align-items 搞混
flex-basis > width;如果设置 flex-basis,width 可能失效
弹性容器内的文本节点也会被当作弹性项

如何完全静态编译GO

Go 语言天生支持跨平台编译,并且其标准库几乎不依赖系统动态库,所以在大多数场景下,它编译出来的二进制文件几乎可以直接丢到任何机器运行

但实际开发中,我们经常遇到两个问题:

  1. 如何完全静态编译?
    • 确保 ldd 显示 not a dynamic executable,不依赖宿主机动态库。
  2. 如何交叉编译到不同平台?
    • 例如 Mac 上编译 Linux/Windows/ARM64 的二进制。

这篇文章会从基础概念讲起,逐步深入,并附带一个一键多平台静态编译脚本,让我们少踩坑。

1. 基础概念

  • 静态编译 = 把所有依赖库都编进一个二进制,丢到任何机器都能跑
  • 动态编译 = 程序运行时还需要宿主机的动态库(如 libc.so.6)
  • 交叉编译 = 在 A 平台上编译 B 平台的程序(比如 Mac 编译 Linux 版)

Go 天生适合静态编译,因为:

• 纯 Go 代码不依赖外部 libc
• 关闭 CGO 后编译结果天然是静态的

只有当项目用了 CGO(如 sqlite、openssl)才会出现动态依赖,需要额外处理。

2. 完全静态编译

纯 Go 项目(最简单)

CGO_ENABLED=0 go build -ldflags="-s -w" -o app .
CGO_ENABLED=0 关闭 C 依赖 → 天然静态
• -ldflags="-s -w" 去掉符号表,减小体积

验证:

ldd app  # not a dynamic executable ✅

有 CGO 依赖(sqlite、openssl 等)

默认会动态链接 glibc,要用 musl 完全静态化:

CC=musl-gcc CGO_ENABLED=1 go build -ldflags="-linkmode external -extldflags -static" -o app .
• musl-gcc 是轻量 libc,适合静态链接
• -extldflags -static 让外部链接器打包所有依赖

验证:

ldd app  # not a dynamic executable ✅

3. 交叉编译(跨平台 + 静态)

Go 内置交叉编译能力,只需 GOOS/GOARCH:


# Linux AMD64
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o app-linux-amd64 .

# Linux ARM64(树莓派)
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o app-linux-arm64 .

# Windows
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o app-windows-amd64.exe

# macOS ARM64
GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -o app-mac-arm64

⚠️ 如果必须用 CGO,交叉编译就需要额外交叉工具链(如 aarch64-linux-musl-gcc)。

4. Docker 结合静态编译

•	动态编译的程序 → 容器镜像必须带 libc(debian、alpine)
•	静态编译的程序 → 直接放 FROM scratch,镜像只有几 MB

推荐:

FROM golang:1.22-alpine AS builder
RUN apk add --no-cache build-base musl-dev
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /out/app .

FROM scratch
COPY --from=builder /out/app /app
ENTRYPOINT ["/app"]

5. 一键多平台静态编译脚本

#!/usr/bin/env bash
set -e

APP="myapp"            # 你的程序名
OUT="dist"             # 输出目录
PLATFORMS=("linux/amd64" "linux/arm64" "darwin/arm64" "windows/amd64")

# 是否启用 CGO(0=纯Go,1=需要C依赖)
USE_CGO=${USE_CGO:-0}

echo "📦 Building $APP for: ${PLATFORMS[*]}"
echo "🔧 CGO Mode: ${USE_CGO}"

rm -rf "$OUT" && mkdir -p "$OUT"

for p in "${PLATFORMS[@]}"; do
  GOOS=${p%/*}
  GOARCH=${p#*/}

  BIN="$OUT/$APP-$GOOS-$GOARCH"
  [[ $GOOS == "windows" ]] && BIN="$BIN.exe"

  echo -e "\n==> 🚀 Building for $GOOS/$GOARCH ..."

  if [[ "$USE_CGO" == "1" ]]; then
    if [[ "$GOOS" == "linux" ]]; then
      echo "🔗 Linux CGO enabled + musl static build"
      CC=musl-gcc \
      CGO_ENABLED=1 \
      GOOS=$GOOS GOARCH=$GOARCH \
      go build -ldflags="-linkmode external -extldflags -static -s -w" -o "$BIN" .

    elif [[ "$GOOS" == "windows" ]]; then
      echo "🔗 Windows CGO static build (MinGW-w64 required)"
      CC=x86_64-w64-mingw32-gcc \
      CGO_ENABLED=1 \
      GOOS=$GOOS GOARCH=$GOARCH \
      go build -ldflags="-extldflags=-static -s -w" -o "$BIN" .

    else
      echo " ⚠️  CGO cross-compile for $GOOS not supported, falling back to pure Go"
      CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH \
      go build -ldflags="-s -w" -o "$BIN" .
    fi

  else
    echo "✅ Pure Go build (CGO disabled)"
    CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH \
    go build -ldflags="-s -w" -o "$BIN" .
  fi

  # ✅ 验证是否静态(仅 Linux / Windows)
  if [[ "$GOOS" == "linux" && -x "$BIN" ]]; then
    echo "🔍 Checking binary type (ldd):"
    if command -v ldd >/dev/null; then
      ldd "$BIN" || echo "✅ Not a dynamic executable"
    fi
  fi

  if [[ "$GOOS" == "windows" && -x "$BIN" ]]; then
    echo "🔍 Checking Windows deps (objdump):"
    if command -v x86_64-w64-mingw32-objdump >/dev/null; then
      x86_64-w64-mingw32-objdump -p "$BIN" | grep DLL || echo "✅ No extra DLL deps"
    else
      echo "(no objdump, skip check)"
    fi
  fi

  echo "✅ $BIN built."
done

echo -e "\n🎉 All binaries are in $OUT/"

执行:

chmod +x build-all.sh 
./build-all.sh # or USE_CGO=1 ./build-all.sh

最终你会得到:

dist/
  ├── myapp-linux-amd64
  ├── myapp-linux-arm64
  ├── myapp-darwin-amd64
  ├── myapp-darwin-arm64
  ├── myapp-windows-amd64.exe

可以分发给对应的二进制平台即可

其他:

musl 是 一个轻量的 C 标准库实现,主要用来替代传统的 glibc。

Go 编译器在用 CGO 时,需要链接 C 运行库(libc),默认是 glibc,但 glibc 的动态库在不同 Linux 发行版版本不同,容易产生兼容性问题。

musl 的特点是:

•	体积小(适合嵌入式和容器)
•	设计简洁、依赖少
•	支持完整静态链接,方便做“丢哪都能跑”的程序
•	常用在 Alpine Linux 这种极简系统中

所以,如果你想让一个含 CGO 的 Go 程序 完全静态,就得用 musl-gcc 替代 gcc,这样 libc 也能被编进二进制里。

glibc vs musl 直观对比

项目glibcmusl
体积
兼容性最通用,几乎所有 Linux 默认用轻量,偏向容器/嵌入式
默认是否动态链接
是否易做静态编译❌ 麻烦✅ 非常容易
适用场景桌面、服务器Alpine、scratch 镜像、IoT

 

转载自https://juejin.cn/post/7529434797891436582

 

whisper-live

 docker run -d   --name whisper-live -p 9089:8080  -p 9090:9090   hwdsl2/whisper-live-server
 docker logs whisper-live
WhisperLive Docker - https://github.com/hwdsl2/docker-whisper-live

Starting WhisperLive real-time speech-to-text server...
  Model:          base
  Language:       auto
  WebSocket port: 9090
  REST API port:  8000
  Max clients:    4
  VAD:            true

Note: Model 'base' not found in cache. It will be downloaded
      from HuggingFace on first client connection. This may take several minutes.

The cache for model files in Transformers v4.22.0 has been updated. Migrating your old cache. This is a one-time only operation. You can interrupt this and resume the migration later on by calling `transformers.utils.move_cache()`.
0it [00:00, ?it/s]
INFO:root:✅ OpenAI-Compatible API started on http://0.0.0.0:8000
INFO:     Started server process [90]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:33366 - "GET /docs HTTP/1.1" 200 OK

===========================================================
 WhisperLive real-time transcription server is ready
===========================================================
 Model:          base
 WebSocket:      ws://x.x.x.x:9090
 REST API:       http://x.x.x.x:8000
===========================================================

Connect a client (WebSocket streaming):
  ws://x.x.x.x:9090

Transcribe a file (REST API):
  curl http://x.x.x.x:8000/v1/audio/transcriptions \
    -F file=@audio.mp3 -F model=whisper-1

Interactive API docs: http://x.x.x.x:8000/docs

To set up HTTPS, see: Using a reverse proxy
  https://github.com/hwdsl2/docker-whisper-live#using-a-reverse-proxy

Setup complete.