Html 如何使用 transform:translateX 在父元素上水平移动子元素 100%
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21557476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use transform:translateX to move a child element horizontally 100% across the parent
提问by mattstuehler
All,
全部,
I'd like to be able to use translateX
to animate a child element 100% of the way across it's parent (i.e., from the left edge to the right edge).
我希望能够使用translateX
它的父元素(即,从左边缘到右边缘)的 100% 动画子元素。
The challenge is that percentages in translateX
refer to the element itself, not the parent.
挑战在于百分比是translateX
指元素本身,而不是父元素。
So, for example, if my html looks like this:
因此,例如,如果我的 html 如下所示:
<div id="parent">
<div id="child">
</div>
And my CSS like this (vendor-prefixes omitted):
我的 CSS 是这样的(省略了供应商前缀):
#parent {
position: relative;
width: 300px;
height: 100px;
background-color: black;
}
#child {
position: absolute;
width: 20px;
height: 100px;
background-color:red;
transform: translateX(100%);
}
This doesn't work - the child only moves 20px (100% of itself), not all the way across the parent. (You can see this on jsfiddle):
这不起作用 - 子项仅移动 20px(自身的 100%),而不是一直移动到父项。(你可以在jsfiddle上看到这个):
I can do this:
我可以做这个:
#child {
position: absolute;
width: 20px;
height: 100px;
background-color:red;
-webkit-transform: translateX(300px) translateX(-100%);
transform: translateX(300px) translateX(-100%);
}
This works (seen here again on jsfiddle), because it first moves the child 300px (the full width of the parent), minus 20px (the width of the child). However, this depends on the parent having a fixed, known pixel dimension.
这有效( 再次在 jsfiddle 上看到),因为它首先将子级移动 300px(父级的全宽),减去 20px(子级的宽度)。然而,这取决于具有固定、已知像素尺寸的父级。
However, in my responsive design - I don't know the width of the parent, and it will change.
但是,在我的响应式设计中 - 我不知道父级的宽度,它会改变。
I know that I can use left:0
and right:0
, but the animation performance of left/right is much worse than translateX (Thanks Paul Irish!).
我知道我可以使用left:0
and right:0
,但是左/右的动画性能比 translateX 差很多(感谢 Paul Irish!)。
Is there a way to do this?
有没有办法做到这一点?
Thanks in advance.
提前致谢。
采纳答案by vals
I didn't post my idea originally, because it involves creating an additional HTML layer, and expected better solutions to come.
我最初没有发表我的想法,因为它涉及创建一个额外的 HTML 层,并且预计会有更好的解决方案出现。
Since that hasn't happened, I explain my comment. What I meant was this:
由于这还没有发生,我解释了我的评论。我的意思是这样的:
#parent {
position: relative;
width: 300px;
height: 100px;
background-color: black;
}
#wrapper {
position: absolute;
width: 100%;
height: 100px;
border: solid 1px green;
transition: all 1s;
}
#wrapper:hover {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
#child {
position: absolute;
width: 20px;
height: 100px;
background-color:red;
}
#wrapper:hover #child {
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
Since the wrapper is 100% width of the parent, translating it 100% works as expected.
由于包装器是父级的 100% 宽度,因此按预期翻译它 100%。
Note that the wrapper is being translated 100% as you stated. However, seems that what you really want is to move the element 100% - width. To achieve this, you have to translate the child also 100% (now this applies to the child width) in the opposite direction.
请注意,包装器正在按您所说的 100% 进行翻译。但是,似乎您真正想要的是将元素移动 100% - 宽度。要实现这一点,您还必须在相反方向上 100%(现在这适用于子宽度)平移子项。
Correction: the child should share the transition property of the wrapper:
更正:孩子应该共享包装器的过渡属性:
#parent {
position: relative;
width: 300px;
height: 100px;
background-color: black;
}
#wrapper {
position: absolute;
width: 100%;
height: 100px;
border: solid 1px green;
transition: all 5s;
}
#wrapper:hover {
transform: translateX(100%);
}
#child {
position: absolute;
width: 50px;
height: 100px;
background-color:red;
transition: inherit;
}
#wrapper:hover #child {
transform: translateX(-100%);
}
<div id="parent">
<div id="wrapper">
<div id="child"></div>
</div>
</div>
回答by Brady Lambert
There's a pretty cool solution to this problem using Flexbox. The key is to take advantage of the flex-growproperty.
使用 Flexbox 有一个非常酷的解决方案来解决这个问题。关键是要利用flex-grow属性。
Say you have some HTML that looks like this:
假设您有一些如下所示的 HTML:
<div class="flex-container">
<div class="flex-spacer"></div>
<div class="slider"></div>
</div>
First, give .flex-container the basic display: flexproperty, and set its flex-directionto row. Set the positioning of the child elements to relative, so they will sit next to each other inside .flex-container.
首先,给 .flex-container 提供基本的display: flex属性,并将其flex-direction设置为row。将子元素的定位设置为relative,这样它们将在 .flex-container 中彼此相邻。
By default, the flex-growproperty is set to 0, which is exactly what we want at the beginning. This means that .flex-spacer and .slider will only have their normal dimensions to begin with. We simply keep .flex-spacer empty, and it will have a widthof 0.
默认情况下,flex-grow属性设置为0,这正是我们一开始想要的。这意味着 .flex-spacer 和 .slider 将只有它们的正常尺寸开始。我们只是保持 .flex-spacer 为空,它的宽度为0。
Now for the animation. We only need two CSS rules to make it work: add a transitionto .flex-spacer and set flex-growto 1on .flex-spacer during some event. The second rule gives all of the unused widthinside .flex-container to the widthof .flex-spacer, and the first rule animates the change in width. The .slider element gets pushed along to the edge of .flex-container.
现在是动画。我们只需要两个 CSS 规则就可以使它工作:在某些事件期间向 .flex-spacer添加过渡并在 .flex-spacer 上将flex-grow设置为1。第二条规则将.flex-container 内所有未使用的宽度赋予.flex-spacer的宽度,第一条规则动画化宽度的变化。.slider 元素被推到 .flex-container 的边缘。
The CSS looks something like this - I added a background to .flex-spacer to make its presence a little more obvious, and set flex-growto 1when the user hovers over .flex-container:
CSS 看起来是这样的——我给 .flex-spacer 添加了一个背景,让它的存在更明显一点,当用户将鼠标悬停在 .flex-container 上时,将flex-grow设置为1:
body * {
box-sizing: border-box;
}
.flex-container {
cursor: pointer;
display: flex;
flex-flow: row nowrap;
width: 100%;
border: 2px solid #444;
border-radius: 3px;
}
.flex-spacer,
.slider {
flex-grow: 0;
position: relative;
}
.slider {
padding: 25px;
background-color: #0DD;
}
.flex-spacer {
background-color: #DDD;
transition: all .4s ease-out;
}
.flex-container:hover .flex-spacer {
flex-grow: 1;
}
<div class="flex-container">
<div class="flex-spacer"></div>
<div class="slider"></div>
</div>
Flexbox makes this pretty configurable, too. For example, say we want .slider to move from right to left, instead. All we have to do is switch the flex-directionproperty in .flex-container to row-reverse, and we're done!
Flexbox 也使这非常可配置。例如,假设我们希望 .slider 从右向左移动。我们所要做的就是将.flex-container 中的flex-direction属性切换为row-reverse,我们就完成了!
Feel free to play with it in this pen.
随意在这支笔中使用它。
Keep in mind that things can get a little trickier if we want animations for different types of events. For example, I came across this issue when trying to animate a label when a user types in an input element. A little more HTML and CSS is needed to make it work (I used some JS, as well), but the concept is the same.
请记住,如果我们想要针对不同类型事件的动画,事情会变得有点棘手。例如,当用户在输入元素中键入时,我在尝试为标签设置动画时遇到了这个问题。需要更多的 HTML 和 CSS 才能使其工作(我也使用了一些 JS),但概念是相同的。
Here's another pen, this time in the context of a form with input.
这是另一个pen,这次是在带有输入的表单的上下文中。