解决 Flex 子元素居中,溢出滚动后被裁切的问题

本文探讨了在CSS布局中遇到的Flex居中对齐导致内容被裁切的问题,以及如何通过设置`margin:auto`和`width:max-content`结合`max-width:100%`来实现内容居中且在手机端出现滚动条的解决方案。同时提到了使用`margin-left:auto`和`margin-right:auto`作为替代方法,确保内容不溢出。

晚上修改了 小窝 页面右侧目录树的定位,并且修改了二级导航栏的布局。其原有的设计采用的是 display: flex + justify-content: center 进行居中的,但这样也遇到了一个问题。如果我使用 white-space: nowrap 禁止文字换行(Flex 默认也是不换行,但是并不会溢出,而是会使得子元素宽度变窄导致文字被换行),并结合 overflow: auto 来使得内容出现滚动条,则会出现左侧被“裁切”掉的效果。

上网搜索了一番,出现这个效果的原因,主要是因为 Flex 居中对齐的特性造成的。当内容被强制不换行后,无论是否设定 overflow: auto,左侧区域由于居中的原因就变成“溢出”区域了,又由于设定了 overflow: auto 的缘故,右侧就还是正常显示的。

为了解决这个问题,我试了一个方案,就是万能的 margin: auto。它可以让任何内容横向居中对齐。但问题来了,Flex 占用了 100% 的宽度,有没有什么宽度可以让它根据内容自动调整?width: max-content 这个属性就迎刃而解,它就可以实现这样的效果!再加上 max-width: 100% 约束最大宽度,就会在手机上出现滚动条而不会溢出了!

.navigation{
    margin: auto;
    display: flex;
    overflow: auto;
    max-width: 100%;
    width: max-content;
    white-space: nowrap;
    margin-bottom: 2.5em;
}

max-content.jpg

你可能会问,这完全不就是多此一举吗?把子元素全部 display: inline-block,父元素 text-align: center 不就好了 🐎 ?没错,这招确实可以,但是如果 HTML 在编写的时候内容存在换行,则会出现间距不统一的问题,因此 Flex 才是更好的实践!

手机上则是横向滚动.jpg

如果你担心 max-content 的兼容性,那么试试这一招?把 Flex 的 width 定义取消,里面的第一个子元素设置成 margin-left: auto,最后一个子元素设置成 margin-right: auto 也可以实现居中且不影响滚动的效果!

.navigation{
    display: flex;
    overflow: auto;
    max-width: 100%;
    white-space: nowrap;
    margin-bottom: 2.5em;
}

.navigation a:first-child{
    margin-left: auto;
}

.navigation a:last-child{
    margin-right: auto;
}
.card{ /* 相对定位 */ position: relative; width: 300px; height: 450px; margin: 20px; background-color: #758a99; border-radius: 20px; /* 溢出隐藏 */ overflow: hidden; /* 弹性布局 */ display: flex; /* 元素纵向排列 */ flex-direction: column; /* 居中 */ align-items: center; color: #fff; /* 阴影 */ box-shadow: 0 0 30px rgba(0, 0, 0, 0.5); /* 不让其他被挤压 */ flex-shrink: 0; } .card .photo img{ width: 100%; height: 100%; /* 保持原有尺寸比例,裁切长边 */ object-fit: cover; } /* 默认大图 */ .card .photo{ /* 绝对定位 */ position: absolute; top: 0; width: 100%; height: 100%; border-radius: 0%; overflow: hidden; /* 动画过渡 */ transition: 0.5s; } /* 鼠标移入变小图 */ .card:hover .photo{ top: 30px; width: 120px; height: 120px; border-radius: 50%; box-shadow: 0 0 20px rgba(0, 0, 0, 0.8); } /* 这里加个黑色到透明的渐变背景,可以更好的看清楚名字 */ .card .photo::before{ content: ""; position: absolute; width: 100%; height: 100%; background: linear-gradient(to bottom,transparent 50%,#222); } .card h1{ position: absolute; top: 370px; transition: 0.5s; } .card:hover h1{ top: 170px; } .card h2{ margin-top: 220px; width: 80%; border-bottom: 1px solid rgba(255, 255, 255, 0.3); font-size: 20px; text-align: center; margin-bottom: 20px; padding-bottom: 20px; } .card p { width: 90%; text-indent: 32px; font-size: 16px; margin-bottom: 15px; line-height: 30px; } .card a{ font-size: 14px; color: rgba(255, 255, 255, 0.8); text-decoration: none; border: 1px solid rgba(255, 255, 255, 0.5); padding: 8px 32px; border-radius: 8px; } .card a:hover{ color: #fff; background-color: rgba(255, 255, 255, 0.2); }这部分css代码帮我用jQuery代替
06-07
<template> <view class="container"> <view class="content-center"> <!-- 左边:时间与Value控制区 --> <view class="center-left"> <view class="left-top uni-row"> <view class="rotundity" @click="decreaseTime"> <image src="/static/minus.png" class="rotundityImage" mode="widthFix"></image> </view> <view class="whiteInput"><text class="time">{{ formatTime(state.countdownTime) }}</text> </view> <view class="rotundity" @click="increaseTime"> <image src="/static/add.png" class="rotundityImage" mode="widthFix"></image> </view> </view> <view class="left-bottom uni-row"> <view class="rotundity" @click="decreaseValue"> <image src="/static/right.png" class="rotundityImage1" mode="widthFix"></image> </view> <view class="yuan"> <image src="/static/yuan.webp" class="yuanImage" mode="widthFix"></image> <text class="yuanText">{{ state.value }}</text> </view> <view class="rotundity" @click="increaseValue"> <image src="/static/left.png" class="rotundityImage2" mode="widthFix"></image> </view> </view> </view> <!-- 右边:Realtime与进度条控制区 --> <view class="center-right uni-column"> <view class="uni-column"> <text class="time2">Realtime</text> <view class="whiteInput1"> <text class="time1">{{ state.realtimeValue }}</text> <text class="en">EN</text> </view> </view> <!-- 第一个进度条 --> <view class="rightItem uni-row"> <view class="wendu-item"> <image src="/static/wendu.png" mode="widthFix" class="wendu"></image> </view> <view class="progress-item" ref="progressBar"> <!-- 添加了触摸事件的进度条圆点 --> <view class="progress-dot" @touchstart="onDotTouchStart" @touchmove="onDotTouchMove" @touchend="onDotTouchEnd" :style="{ left: (state.temp1 / 50) * 100 + '%' }"></view> <progress class="progress" :stroke-width="20" :percent="Math.round((state.temp1 / 50) * 100)" :border-radius="20" :backgroundColor="state.bgColor" :activeColor="state.activeColor"></progress> </view> <view class="rightValue"> <text class="valueTitle">{{ state.temp1 }}℃</text> </view> </view> <!-- 第一个进度条温度加减按钮 --> <view class="progress-btn uni-row"> <view class="btnItem" @click="decreaseTemp1"> <text class="btnText">—</text> </view> <view class="btnItem" @click="increaseTemp1"> <text class="btnText">+</text> </view> </view> <!-- 第二个进度条 --> <view class="rightItem uni-row"> <view class="wendu-item"> <image src="/static/wendu.png" mode="widthFix" class="wendu"></image> <text class="real">real</text> </view> <view class="progress-item"> <view class="progress-dot"></view> <progress class="progress" :stroke-width="20" :percent="state.progress" :border-radius="20" :backgroundColor="state.bgColor" :activeColor="state.activeColor"></progress> </view> <view class="rightValue"> <text class="valueTitle">50℃</text> </view> </view> <!-- 启动/暂停图片 --> <image :src="state.isRunning ? '/static/stop.png' : '/static/start.png'" mode="widthFix" class="switch" @click="toggleStartStop"></image> </view> </view> <!-- 底部模式切换按钮 --> <view class="content-bottom uni-row"> <button class="bottom-button" :class="isActiveTab('A-Mode') ? 'bottom-button-active' : ''" @click="setActiveTab('A-Mode')"> <text class="tab-text" :class="isActiveTab('A-Mode') ? 'tab-text-active' : ''">A-Mode</text> </button> <button class="bottom-button" :class="isActiveTab('B-Mode') ? 'bottom-button-active' : ''" @click="setActiveTab('B-Mode')"> <text class="tab-text" :class="isActiveTab('B-Mode') ? 'tab-text-active' : ''">B-Mode</text> </button> <button class="bottom-button" :class="isActiveTab('Private') ? 'bottom-button-active' : ''" @click="setActiveTab('Private')"> <text class="tab-text" :class="isActiveTab('Private') ? 'tab-text-active' : ''">Private</text> </button> </view> </view> </template> <script setup lang="uts"> import { reactive, onMounted, onUnmounted, onLoad, ref } from 'vue' import type { OnLoadOptions } from '@dcloudio/uni-app' // 状态类型定义 type State = { activeTab : string time : number value : number progress : number realtimeValue : number bgColor : string activeColor : string temp1 : number isRunning : boolean countdownTime : number startX : number // 拖拽起始X坐标 startTemp : number // 拖拽起始温度 } // 状态初始化 const state = reactive<State>({ activeTab: 'A-Mode', time: 30, value: 5, progress: 5, realtimeValue: 30, bgColor: '#93848B', activeColor: '#E38223', temp1: 33, isRunning: false, countdownTime: 30 * 60, startX: 0, startTemp: 0 }) // 进度条元素引用 const progressBar = ref<Element | null>(null) const isDragging = ref(false) // 定时器变量 let timer : number | null = null // 启动/暂停切换与倒计时逻辑 function toggleStartStop() : void { if (state.isRunning) { const currentTimer = timer if (currentTimer !== null) { clearInterval(currentTimer) } state.isRunning = false timer = null } else { state.isRunning = true timer = setInterval(() => { if (state.countdownTime > 0) { state.countdownTime -= 1 } else { const currentTimer = timer if (currentTimer !== null) { clearInterval(currentTimer) } state.isRunning = false timer = null } }, 1000) } } // 时间格式化 function formatTime(seconds : number) : string { const mins = Math.floor(seconds / 60) const secs = seconds % 60 return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}` } // 时间调整 function increaseTime() : void { if (state.time < 30) { state.time += 1 state.countdownTime = state.time * 60 } } function decreaseTime() : void { if (state.time > 0) { state.time -= 1 state.countdownTime = state.time * 60 } } // Value控制 function isActiveTab(tabName : string) : boolean { return state.activeTab === tabName } function setActiveTab(tabName : string) : void { state.activeTab = tabName } function updateProgress() : void { state.progress = state.value } function increaseValue() : void { if (state.value < 100) { state.value += 5 updateProgress() } } function decreaseValue() : void { if (state.value > 0) { state.value -= 5 updateProgress() } } // 温度控制(按钮加减) function increaseTemp1() : void { if (state.temp1 < 50) state.temp1 += 1 } function decreaseTemp1() : void { if (state.temp1 > 0) state.temp1 -= 1 } // 进度条圆点拖拽事件(优化布尔比较方式) function onDotTouchStart(e : TouchEvent) : void { isDragging.value = true state.startTemp = state.temp1 // 获取触摸起始X坐标 const touch = e.touches[0] as Touch state.startX = touch.clientX } function onDotTouchMove(e : TouchEvent) : void { if (isDragging.value == false || progressBar.value == null) { return } e.stopPropagation() e.preventDefault() // 必须加,阻止页面滚动干扰 const touch = e.touches[0] as Touch const currentX = touch.clientX const deltaX = currentX - state.startX const rect = progressBar.value.getBoundingClientRect() const barWidth = rect.width // 关键:直接用容器总宽度(含内边距),与left的百分比基准一致 // 基于总宽度计算温度变化(与left的百分比逻辑匹配) const tempDelta = Math.round((deltaX / barWidth) * 50) let newTemp = state.startTemp + tempDelta newTemp = Math.max(0, Math.min(newTemp, 50)) // 限制在0-50℃ state.temp1 = newTemp } function onDotTouchEnd() : void { isDragging.value = false } // Realtime更新 function updateRealtimeValue(newValue : number) : void { state.realtimeValue = Math.min(Math.max(newValue, 0), 100) } // 生命周期函数 onLoad((options : OnLoadOptions) : void => { }) onMounted(() => { console.log('组件挂载完成:基础功能已初始化') }) onUnmounted(() => { const currentTimer = timer if (currentTimer !== null) { clearInterval(currentTimer) } }) </script> <style scoped> .container { width: 100%; height: 100%; overflow: hidden; display: flex; flex-direction: column; } .content-center { flex: 1; display: flex; flex-direction: row; align-items: center; background-color: #48546A; } .content-bottom { width: 100%; height: 50rpx; background-color: #E38223; justify-content: space-around; padding: 5rpx 0; } .bottom-button { height: 40rpx; line-height: 40rpx; font-size: 22rpx; padding: 0 10rpx; border: 1px solid #fff; color: #fff; background-color: transparent; } .bottom-button-active { background-color: #fff; color: #E38223; } .tab-text { font-size: 22rpx; color: #fff; } .tab-text-active { font-size: 22rpx; color: #E38223; } .center-left { padding: 20rpx 0; width: 50%; display: flex; align-items: center; justify-content: center; flex-direction: column; } .center-right { padding: 20rpx 0; width: 50%; display: flex; align-items: center; justify-content: center; } .left-top {} .left-bottom { align-items: center; justify-content: center; margin-top: 30rpx; } .rotundity { width: 50rpx; height: 50rpx; border-radius: 100rpx; display: flex; align-items: center; justify-content: center; background-color: #fff; } .rotundityImage { width: 40rpx; } .rotundityImage1 { width: 20rpx; margin-right: 5rpx; } .rotundityImage2 { width: 20rpx; margin-left: 5rpx; } .whiteInput { width: 200rpx; height: 50rpx; border-radius: 25rpx; background-color: #93848B; margin: 0 20rpx; } .whiteInput1 { width: 180rpx; height: 50rpx; border-radius: 25rpx; background-color: #93848B; margin: 0 20rpx; position: relative; } .en { position: absolute; right: 5rpx; top: 8rpx; color: #fff; font-size: 30rpx; } .time { width: 100%; text-align: center; font-size: 30rpx; line-height: 50rpx; color: #fff; } .time1 { width: 100%; text-align: center; font-size: 30rpx; line-height: 50rpx; color: #fff; } .time2 { width: 100%; text-align: center; font-size: 24rpx; line-height: 30rpx; color: #fff; } .yuan { width: 240rpx; height: 240rpx; position: relative; display: flex; align-items: center; justify-content: center; } .yuanText { color: #fff; font-size: 60rpx; margin-right: 40rpx; z-index: 1; position: relative; } .yuanImage { width: 100%; height: 100%; position: absolute; top: 0; left: 0; } .bottom-tab { border: 1px solid #fff; border-radius: 16rpx; } .rightItem { width: 100%; margin-top: 10rpx; align-items: center; justify-content: center; position: relative; } .wendu-item { /* position: relative; */ } .wendu { width: 20rpx; } .real { position: absolute; right: 20rpx; top: 0; color: #fff; z-index: 999; font-size: 12rpx; } .rightValue { width: 50rpx; height: 30rpx; border-radius: 6rpx; background-color: #93848B; display: flex; align-items: center; justify-content: center; } .progress-item { position: relative; /* 新增:让圆点的绝对定位基于进度条 */ width: 60%; margin: 0 10rpx; padding: 0 10rpx; box-sizing: border-box; } .progress-dot { position: absolute; top: 50%; transform: translateY(-50%) translateX(-50%); /* 水平居中对齐进度条位置 */ z-index: 999; width: 25rpx; height: 25rpx; border-radius: 200rpx; background-color: #fff; /* 增加触摸热区 */ padding: 5rpx; margin-left: 12.5rpx; /* 补偿translateX(-50%)的偏移,确保边缘不溢出 */ } .progress { width: 100%; padding: 10rpx 0; } .valueTitle { color: #fff; font-size: 20rpx; } .progress-btn { width: 100%; justify-content: center; align-items: center; margin-top: 5rpx; } .btnItem { width: 30rpx; height: 30rpx; border-radius: 50rpx; border: 1px solid #93848B; display: flex; align-items: center; justify-content: center; margin: 0 10rpx; } .btnText { color: #fff; font-size: 30rpx; } .switch { width: 200rpx; } </style>这个是uniappX的代码,现在是可以运行的,但是第一个进度条的白点,拖到最右边的时候,超出了进度条的宽度,我希望白色圆点只能停到进度条的最右边,不能超过
最新发布
10-24
<template> <div class="tug-of-war-container"> <!-- 背景图片铺满全屏 --> <img :src="background" class="background-image" alt="背景"/> <!-- 问题图片 --> <div class="question-container"> <img :src='questionImg' class="question-image" alt="图片不存在"/> </div> <el-select v-model="questionValue" placeholder="请选择" class="select-question"> <el-option v-for="item in allQuestions" :key="item.id" :label="item.questionNumber" :value="item.id" @click="handleClick(item)"> </el-option> </el-select> <Edit/> <!-- 移动图片(按比例放大) --> <div class="move-container"> <img :src="character" class="move-image" :style="{ transform: `translateX(${imagePosition}px)` }" alt="移动对象" /> </div> <!-- 选项按钮 --> <div class="options-container"> <button class="option-btn left-option" :disabled="answered" @click="checkAnswer(question.resultLeft,'left')" > {{ question.optionOne }} </button> <button class="option-btn right-option" :disabled="answered" @click="checkAnswer(question.resultRight,'right')" > {{ question.optionTwo }} </button> </div> <!-- 提示图片 --> <transition name="fade"> <img v-show="showCorrectLeft" :src="correctImg" class="feedback-image correct-feedback-left" alt="正确提示" /> </transition> <transition name="fade"> <img v-show="showCorrectRight" :src="correctImg" class="feedback-image correct-feedback-right" alt="正确提示" /> </transition> <transition name="fade"> <img v-show="showIncorrectLeft" :src="incorrectImg" class="feedback-image incorrect-feedback-left" alt="错误提示" /> </transition> <transition name="fade"> <img v-show="showIncorrectRight" :src="incorrectImg" class="feedback-image incorrect-feedback-right" alt="错误提示" /> </transition> </div> </template> <script setup lang="ts"> import {onMounted, onUnmounted, ref} from 'vue'; import {getQuestionAll, getQuestionImg} from '@/api/modules/tug.of.war' import Edit from './Edit.vue'; // 导入所有需要的图片 import questionImgOld from '@/image/1.jpg'; import background from '@/image/background.jpg' import character from '@/image/character.png' import correctImg from '@/image/correct.png'; import incorrectImg from '@/image/incorrect.png'; import {TugOfWar} from "@/types/api/tugOfWar"; // 定义选项 const questionImg = ref<string>(); questionImg.value = questionImgOld // 定义奖项配置 const question = ref( {optionOne: "", optionTwo: "", resultLeft: 1, resultRight: 0} ) //所有问题 const allQuestions = ref<TugOfWar[]>([]); const questionValue = ref<string>(); // 图片位置状态 const imagePosition = ref<number>(0); const initialPosition = ref<number>(0); // 答题状态 const answered = ref<boolean>(false); const showCorrectLeft = ref<boolean>(false); const showCorrectRight = ref<boolean>(false); const showIncorrectLeft = ref<boolean>(false); const showIncorrectRight = ref<boolean>(false); // 检查答案 const checkAnswer = (optionIndex: number, direction: String) => { if (answered.value) return; answered.value = true; if (optionIndex === 1) { if ("left" === direction) { showCorrectLeft.value = true; // 向左移动图片 imagePosition.value = -250; } if ("right" === direction) { showCorrectRight.value = true; imagePosition.value = 250; } } if (optionIndex === 0) { if ("left" === direction) { showIncorrectLeft.value = true; // 向右移动图片 imagePosition.value = 250; } if ("right" === direction) { showIncorrectRight.value = true; imagePosition.value = -250; } } // 3秒后重置状态 setTimeout(resetGame, 3000); }; // 重置游戏状态 const resetGame = () => { answered.value = false; showCorrectLeft.value = false; showCorrectRight.value = false; showIncorrectLeft.value = false; showIncorrectRight.value = false; imagePosition.value = 0; }; // 响应式调整布局 const handleResize = () => { // 在实际应用中,这里可以添加响应式布局调整逻辑 }; // 定义响应类型 interface ApiResponse { data: ArrayBuffer headers: { 'content-type': "image/jpeg" } } const handleClick = async (questionOne: TugOfWar) => { try { console.log(questionOne.id); const response = await getQuestionImg({id: questionOne.id}); console.log(response); // 转换为 Blob(指定 MIME 类型) const blob = new Blob([response], {type: "image/jpeg"}); console.log(blob); // 创建 Blob 对象 // 创建临时 URL questionImg.value = URL.createObjectURL(blob); // 生成临时 URL } catch (error) { console.error('Error loading image:', error) // 可以在此处添加错误处理逻辑 questionImg.value = questionImgOld } question.value.optionOne = questionOne.optionOne; question.value.optionTwo = questionOne.optionTwo; question.value.resultRight = questionOne.resultRight question.value.resultLeft = questionOne.resultLeft } onMounted(async () => { window.addEventListener('resize', handleResize); allQuestions.value = await getQuestionAll() console.log(allQuestions.value) }); onUnmounted(() => { window.removeEventListener('resize', handleResize); }); </script> <style scoped> /* 基础样式重置 */ * { margin: 0; padding: 0; box-sizing: border-box; } .tug-of-war-container { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c); } /* 背景图片铺满全屏 */ .background-image { position: absolute; top: 0; left: 56px; width: 93%; height: 100%; object-fit: cover; z-index: 1; opacity: 0.8; } /* 问题容器 */ .question-container { position: relative; z-index: 2; display: flex; justify-content: center; padding-top: 0px; } .question-image { width: 80%; max-width: 400px; height: 180px; object-fit: contain; border: 4px solid #ffd700; border-radius: 15px; background: rgba(255, 255, 255, 0.9); box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5); } /* 移动图片容器 */ .move-container { position: relative; z-index: 3; display: flex; left: 52px; justify-content: center; align-items: center; height: 300px; margin: 20px 0; } .move-image { width: 1200px; /* 放大移动图片 */ height: 1200px; object-fit: contain; transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.5)); z-index: 4; } /* 选项按钮容器 */ .options-container { position: relative; z-index: 5; display: flex; justify-content: space-between; padding: 0 30%; margin-bottom: 30px; } .option-btn { padding: 20px 50px; font-size: 24px; font-weight: bold; border: none; border-radius: 60px; cursor: pointer; transition: all 0.4s ease; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); position: relative; overflow: hidden; z-index: 6; } .left-option { background: linear-gradient(145deg, #ff416c, #ff4b2b); color: white; } .right-option { background: linear-gradient(145deg, #38ef7d, #11998e); color: white; } .option-btn:hover:not(:disabled) { transform: translateY(-8px) scale(1.05); box-shadow: 0 12px 25px rgba(0, 0, 0, 0.4); } .option-btn:active:not(:disabled) { transform: translateY(2px); } .option-btn:disabled { opacity: 0.7; cursor: not-allowed; } /* 添加发光效果 */ .option-btn::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.1); border-radius: 60px; transform: scale(0); transition: transform 0.5s ease; } .option-btn:hover:not(:disabled)::after { transform: scale(1.5); opacity: 0; } /* 反馈图片样式 */ .feedback-image { position: absolute; transform: translate(-50%, -50%); width: 250px; height: 250px; object-fit: contain; z-index: 10; } .correct-feedback-left { top: 85%; left: 20%; animation: popIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .correct-feedback-right { top: 85%; left: 80%; animation: popIn 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .incorrect-feedback-left { top: 85%; left: 20%; animation: shake 0.8s cubic-bezier(0.36, 0.07, 0.19, 0.97); } .incorrect-feedback-right { top: 85%; left: 80%; animation: shake 0.8s cubic-bezier(0.36, 0.07, 0.19, 0.97); } /* 动画效果 */ @keyframes popIn { 0% { transform: translate(-50%, -50%) scale(0.5); opacity: 0; } 70% { transform: translate(-50%, -50%) scale(1.1); opacity: 1; } 100% { transform: translate(-50%, -50%) scale(1); } } @keyframes shake { 0%, 100% { transform: translate(-50%, -50%); } 10%, 30%, 50%, 70%, 90% { transform: translate(-52%, -50%); } 20%, 40%, 60%, 80% { transform: translate(-48%, -50%); } } .fade-enter-active, .fade-leave-active { transition: opacity 0.5s; } .fade-enter-from, .fade-leave-to { opacity: 0; } /* 响应式设计 */ @media (max-width: 768px) { .question-image { width: 90%; height: 150px; } .move-image { width: 120px; height: 120px; } .option-btn { padding: 15px 30px; font-size: 18px; } } @media (max-width: 480px) { .question-container { padding-top: 20px; } .question-image { height: 120px; } .move-image { width: 100px; height: 100px; } .option-btn { padding: 12px 25px; font-size: 16px; } .feedback-image { width: 180px; height: 180px; } .example-showcase .el-dropdown + .el-dropdown { margin-left: 15px; } .example-showcase .el-dropdown-link { cursor: pointer; color: var(--el-color-primary); display: flex; align-items: center; } } .select-question{ width: 100px; padding-left: 0px; } </style> 调整合适的比例放在一个页面上展示
08-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值