使用Transition/CSS3滚动到锚点

use*_*490 40 html5 css3

我有一系列使用锚机制的链接:

<div class="header">
    <p class="menu"><a href="#S1">Section1</a></p>
    <p class="menu"><a href="#S2">Section2</a></p>
    ...
</div>
<div style="width: 100%;">
<a name="S1" class="test">&nbsp;</a>
<div class="curtain">
Lots of text
</div>

<a name="S2" class="test">&nbsp;</a>
<div class="curtain">
lots of text
</div>
...
</div>
Run Code Online (Sandbox Code Playgroud)

我使用以下CSS:

.test
{
    position:relative; 
    margin: 0; 
    padding: 0; 
    float: left;
    display: inline-block;
    margin-top: -100px; /* whatever offset this needs to be */
}
Run Code Online (Sandbox Code Playgroud)

它工作正常.但是当然,当我们点击链接时,它会从一个部分跳到另一个部分.所以我希望有一个平滑的过渡,使用某种滚动到选定部分的开头.

我想我在Stackoverflow上读到这对CSS3来说是不可能的,但是我想要一个确认,而且我想知道什么'可能'是解决方案.我很高兴使用JS,但我不能使用jQuery.我尝试在链接上使用on click功能,检索需要显示的div的"垂直位置",但是我没有成功.我还在学习JS,并且不太了解它以便提出我自己的解决方案.

任何帮助/想法将不胜感激.

Ale*_*rny 30

您可以在以下页面找到问题的答案:

/sf/answers/1234375901/

这是给出的JSFiddle:

http://jsfiddle.net/YYPKM/3/

请注意CSS末尾的滚动部分,特别是:

/*
 *Styling
 */

html,body {
    width: 100%;
    height: 100%;
    position: relative; 
}
body {
overflow: hidden;
}

header {
background: #fff; 
position: fixed; 
left: 0; top: 0; 
width:100%;
height: 3.5rem;
z-index: 10; 
}

nav {
width: 100%;
padding-top: 0.5rem;
}

nav ul {
list-style: none;
width: inherit; 
margin: 0; 
}


ul li:nth-child( 3n + 1), #main .panel:nth-child( 3n + 1) {
background: rgb( 0, 180, 255 );
}

ul li:nth-child( 3n + 2), #main .panel:nth-child( 3n + 2) {
background: rgb( 255, 65, 180 );
}

ul li:nth-child( 3n + 3), #main .panel:nth-child( 3n + 3) {
background: rgb( 0, 255, 180 );
}

ul li {
display: inline-block; 
margin: 0 8px;
margin: 0 0.5rem;
padding: 5px 8px;
padding: 0.3rem 0.5rem;
border-radius: 2px; 
line-height: 1.5;
}

ul li a {
color: #fff;
text-decoration: none;
}

.panel {
width: 100%;
height: 500px;
z-index:0; 
-webkit-transform: translateZ( 0 );
transform: translateZ( 0 );
-webkit-transition: -webkit-transform 0.6s ease-in-out;
transition: transform 0.6s ease-in-out;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;

}

.panel h1 {
font-family: sans-serif;
font-size: 64px;
font-size: 4rem;
color: #fff;
position:relative;
line-height: 200px;
top: 33%;
text-align: center;
margin: 0;
}

/*
 *Scrolling
 */

a[ id= "servicios" ]:target ~ #main article.panel {
-webkit-transform: translateY( 0px);
transform: translateY( 0px );
}

a[ id= "galeria" ]:target ~ #main article.panel {
-webkit-transform: translateY( -500px );
transform: translateY( -500px );
}
a[ id= "contacto" ]:target ~ #main article.panel {
-webkit-transform: translateY( -1000px );
transform: translateY( -1000px );
}
Run Code Online (Sandbox Code Playgroud)
<a id="servicios"></a>
<a id="galeria"></a>
<a id="contacto"></a>
<header class="nav">
<nav>
    <ul>
        <li><a href="#servicios"> Servicios </a> </li>
        <li><a href="#galeria"> Galeria </a> </li>
        <li><a href="#contacto">Contacta  nos </a> </li>
    </ul>
</nav>
</header>

<section id="main">
<article class="panel" id="servicios">
    <h1> Nuestros Servicios</h1>
</article>

<article class="panel" id="galeria">
    <h1> Mustra de nuestro trabajos</h1>
</article>

<article class="panel" id="contacto">
    <h1> Pongamonos en contacto</h1>
</article>
</section>
Run Code Online (Sandbox Code Playgroud)


vsy*_*ync 24

使用scroll-behaviorCSS属性:

(现代浏览器支持但不支持Edge):

a {
  display: inline-block;
  padding: 5px 7%;
  text-decoration: none;
}

nav, section {
  display: block;
  margin: 0 auto;
  text-align: center;
}

nav {
  width: 350px;
  padding: 5px;
}

section {
  width: 350px;
  height: 130px;
  overflow-y: scroll;
  border: 1px solid black;
  font-size: 0; 
  scroll-behavior: smooth;    /* <----- THE SECRET ---- */
}

section div{
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 8vw;
}
Run Code Online (Sandbox Code Playgroud)
<nav>
  <a href="#page-1">1</a>
  <a href="#page-2">2</a>
  <a href="#page-3">3</a>
</nav>
<section>
  <div id="page-1">1</div>
  <div id="page-2">2</div>
  <div id="page-3">3</div>
</section>
Run Code Online (Sandbox Code Playgroud)

  • 你的答案很棒,希望将来是最简单的方法.但是,对于想要使用上述内容的任何人,请注意此时与任何版本的IE或Safari都没有兼容性.至少在Safari上,这种行为是"跳跃"的旧行为. (4认同)
  • 我这样使用它 *{ scroll-behavior: smooth; } (2认同)

use*_*490 20

虽然一些答案非常有用且信息丰富,但我想我会写下我想出的答案.Alex的答案非常好,但是在div的高度需要在CSS中进行硬编码的意义上是有限的.

所以我提出的解决方案使用JS(没有jQuery),实际上是一个简化版本(几乎是最小)的解决方案来解决我在Statckoverflow上发现的类似问题:

HTML

<div class="header">
    <p class="menu"><a href="#S1" onclick="test('S1'); return false;">S1</a></p>
    <p class="menu"><a href="#S2" onclick="test('S2'); return false;">S2</a></p>
    <p class="menu"><a href="#S3" onclick="test('S3'); return false;">S3</a></p>
    <p class="menu"><a href="#S4" onclick="test('S4'); return false;">S3</a></p>
</div>
<div style="width: 100%;">
    <div id="S1" class="curtain">
    blabla
    </div>
    <div id="S2" class="curtain">
    blabla
    </div>
    <div id="S3" class="curtain">
    blabla
    </div>
    <div id="S4" class="curtain">
    blabla
    </div>
 </div>
Run Code Online (Sandbox Code Playgroud)

注意"返回错误"; 在点击通话中.如果您想避免让浏览器跳转到链接本身(并让效果由您的JS管理),这一点很重要.

JS代码:

<script>
function scrollTo(to, duration) {
    if (document.body.scrollTop == to) return;
    var diff = to - document.body.scrollTop;
    var scrollStep = Math.PI / (duration / 10);
    var count = 0, currPos;
    start = element.scrollTop;
    scrollInterval = setInterval(function(){
        if (document.body.scrollTop != to) {
            count = count + 1;
            currPos = start + diff * (0.5 - 0.5 * Math.cos(count * scrollStep));
            document.body.scrollTop = currPos;
        }
        else { clearInterval(scrollInterval); }
    },10);
}

function test(elID)
{
    var dest = document.getElementById(elID);
    scrollTo(dest.offsetTop, 500);
}
</script>
Run Code Online (Sandbox Code Playgroud)

这非常简单.它使用其唯一ID(在函数测试中)查找文档中div的垂直位置.然后它调用scrollTo函数传递起始位置(document.body.scrollTop)和目标位置(dest.offsetTop).它使用某种易于进入的曲线执行转换.

谢谢大家的帮助.

了解一些编码可以帮助您避免(有时很重)库,并为您(程序员)提供更多控制.

  • 这会产生错误`element is undefined`.所以请改用`start = window.pageYOffset;`. (4认同)
  • @ymz - 我知道我参加聚会的时间有点晚了,但我只是想加入进来.Alex的解决方案与这个问题相差无几的原因是Alex的解决方案不是动态的.Alex的解决方案要求您对CSS中的位置进行硬编码(无论您是否使用%,您仍然是硬编码).然而,这个答案创建了一个解决方案,在向页面添加元素时不需要添加新的CSS规则.它只是简单的工作. (3认同)
  • 我必须通知大家,Alex的解决方案似乎是最佳的……我更改并将值固定为百分比(%),并获得了理想的效果。小提琴:http://jsfiddle.net/YYPKM/1676/当“ panel”类的高度为100%且具有绝对位置时,它也可以正常工作(以便节省时间。.这是该小提琴的另一个版本:http ://jsfiddle.net/YYPKM/1677/) (2认同)

小智 13

只需使用此一行代码将滚动行为应用于所有元素:

*{
scroll-behavior: smooth !important;
}
Run Code Online (Sandbox Code Playgroud)


Rei*_*.85 6

只有mozzila在css中实现了一个简单的属性:http://caniuse.com/#search=scroll-behavior

你必须至少使用JS.

我个人使用这个因为它易于使用(使用JQ但我可以调整它我猜):

/*Scroll transition to anchor*/
$("a.toscroll").on('click',function(e) {
    var url = e.target.href;
    var hash = url.substring(url.indexOf("#")+1);
    $('html, body').animate({
        scrollTop: $('#'+hash).offset().top
    }, 500);
    return false;
});
Run Code Online (Sandbox Code Playgroud)

只需将class toscroll添加到您的标签中