[英]Align single list item in center CSS
我正在用四個元素在Reactjs中創建一個導航欄。 這些項目是一個簡單的無序列表,其中有些CSS使用flexbox將它們水平對齊。
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<ul/>
我要實現的是:選擇一個列表項后,將所選列表項對齊到中心。 我添加了一張專業圖片進行說明。 稍后將對該更改進行動畫處理,以實現平滑的過渡,例如輪播。
以下是<ul>
標記的css。
ul {
list-style-type: none;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
}
我試過的是使用align-self: center
以<li>
項之一為align-self: center
,但是沒有運氣。
有人有做類似事情的經驗嗎? 我願意接受所有類型的解決方案,甚至不使用flexbox的解決方案。
謝謝!
列表元素是否有固定的,您知道有多少個項目嗎? 如果是這樣,您可以計算列表的中心,項目偏移量,並添加CSS轉換。
例:
如果列表是動態的(關於列表長度和項目寬度),則可以使用Element.getBoundingClientRect()查找元素的尺寸,並使用與上述相同的計算。
Codepen: https ://codepen.io/anon/pen/vjJMVL
HTML:
<ul class="selected-2">
<li>1</li>
<li class="selected">2</li>
<li>3</li>
<li>4</li>
</ul>
<ul class="selected-4">
<li>1</li>
<li>2</li>
<li>3</li>
<li class="selected">4</li>
</ul>
CSS:
ul {
display: flex;
justify-content: center;
list-style: none;
}
li {
width: 80px;
height: 80px;
background-color: #eee;
margin: 10px;
}
.selected {
background-color: #ccc;
}
.selected-2 {
transform: translateX(50px)
}
.selected-4 {
transform: translateX(-150px)
}
通過使用Element.getBoundingClientRect()
計算單擊的<MenuItem>
中心,以得到它的left
和width
,並將其傳遞給父對象( <Menu>
)。 在父使用<ul>
S REF以獲得它的left
和寬度與Element.getBoundingClientRect()
計算moveTo
狀態,並更新<ul>
的樣式transform: translateX()
:
const { Component } = React; const items = ['One', 'Two', 'Three', 'Four']; class MenuItem extends Component { clickHandler = (e) => { const { left, width } = e.target.getBoundingClientRect(); const itemCenter = left + width / 2; this.props.updateCenter(itemCenter); } render() { const { children } = this.props; return ( <li onClick={this.clickHandler}>{children}</li> ); } } class Menu extends Component { state = { moveTo: 0 }; updateCenter = (itemCenter) => { const { left, width } = this.ul.getBoundingClientRect(); //this.ul.style.transform = `translateX(${center}px)`; this.setState(() => ({ moveTo: left + width / 2 - itemCenter })); }; render() { const { items } = this.props; const { moveTo } = this.state; return ( <nav> <ul ref={(ul) => this.ul = ul} style={{ transform: `translateX(${moveTo}px)` }}> { items.map((text) => ( <MenuItem key={text} updateCenter={this.updateCenter}> {text} </MenuItem> )) } </ul> </nav> ); } } ReactDOM.render( <Menu items={items} />, demo );
/** demo only - display the center **/ body::before { position: absolute; left: 50%; height: 100vh; border-right: 1px solid black; content: ''; } nav { overflow: hidden; } ul { list-style-type: none; display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: center; transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); } li { padding: 1em; border: 1px solid black; cursor: pointer; } ul li:not(:last-child) { margin: 0 1em 0 0; }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="demo"></div>
由於我沒有完全得到想要的東西,因此這是我能想到的最好的選擇,將絕對定位應用於所選的位置,並使它與其他具有z-index的位置重疊
document.querySelectorAll('li').forEach(function(li){ li.addEventListener('click',function(e){ document.querySelectorAll('li').forEach(function(obj){ obj.classList.remove('selected'); }); e.target.classList.add("selected"); }); });
ul { list-style-type: none; display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: center; } li{ border:1px solid; padding:10px; cursor:pointer; position:relative; transition:all ease 1s; margin:0 20px; } .selected{ transform:scale(2.1); background:white; box-shadow:0px 0px 55px black; position:absolute; z-index:5; }
<ul> <li>One</li> <li>Two</li> <li>Three</li> <li>Four</li> </ul>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.