文章列表

文章资讯列表 - 左右布局响应式设计 开箱即用

设计特点

这个文章资讯列表页面具有以下特点:

  1. 左右布局
  2. PC端采用左侧文章列表、右侧分类和推荐文章的布局
  3. 响应式设计,在移动端自动调整为上下布局
  1. 文章展示多样化
  2. 有图片文章:左侧图片,右侧内容
  3. 无图片文章:纯文本展示
  4. 每篇文章都包含标题、描述、时间和浏览次数
  1. 新鲜感设计元素
  2. 文章卡片悬停效果(轻微上浮+阴影增强)
  3. 图片放大过渡效果
  4. 渐入动画效果(文章卡片依次显示)
  5. 右侧边栏功能
  6. 分类列表(带图标和文章数量)
  7. 搜索框
  8. 推荐阅读(带缩略图)
  1. 响应式设计
  2. 桌面端:左右布局
  3. 平板端:调整图片大小,保持左右布局
  4. 移动端:转为上下布局,图片占满宽度

这个设计既美观又实用,适合各种类型的内容网站和博客。文章卡片的设计既有视觉冲击力,又保持了良好的可读性和信息层次。

截图展示

代码

<main class="main-content">
    <section class="max-container">
        <style>
            .header-a{margin-bottom:30px;padding-bottom:20px;border-bottom:1px solid #eaeaea}
            .header-a h1{font-size:28px;font-weight:700;color:#1e293b}
            .header-a p{color:#64748b;margin-top:5px}
            .main-content-a{display:flex;gap:30px}
            .article-as-section{flex:1}
            .section-title{font-size:20px;font-weight:600;margin-bottom:20px;color:#1e293b;display:flex;align-items:center}
            .section-title::after{content:'';flex:1;height:1px;background:#e2e8f0;margin-left:15px}
            .article-a-list{display:flex;flex-direction:column;gap:25px}
            .article-a-card{background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 4px 6px rgba(0,0,0,.03),0 1px 3px rgba(0,0,0,.05);transition:transform .2s,box-shadow .2s}
            .article-a-card:hover{transform:translateY(-3px);box-shadow:0 10px 15px rgba(0,0,0,.05),0 4px 6px rgba(0,0,0,.03)}
            .article-a-with-image{display:flex;flex-direction:row}
            .article-a-image{width:280px;min-width:280px;height:180px;overflow:hidden}
            .article-a-image img{width:100%;height:100%;object-fit:cover;transition:transform .3s}
            .article-a-card:hover .article-a-image img{transform:scale(1.05)}
            .article-a-content{padding:20px;display:flex;flex-direction:column}
            .article-a-title{font-size:18px;font-weight:600;margin-bottom:10px;line-height:1.4}
            .article-a-description{color:#64748b;font-size:14px;margin-bottom:15px;flex:1;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
            .article-a-meta{display:flex;align-items:center;color:#94a3b8;font-size:13px}
            .article-a-date{display:flex;align-items:center;margin-right:15px}
            .article-a-views{display:flex;align-items:center}
            .meta-icon{margin-right:5px;opacity:.7}
            .article-a-without-image .article-a-content{padding:20px}
            .article-a-tag{display:inline-block;padding:3px 8px;background-color:#eff6ff;color:#3b82f6;border-radius:4px;font-size:12px;font-weight:500;margin-bottom:10px}
            .sidebar-a{width:300px;min-width:300px}
            .sidebar-a-section{background:#fff;border-radius:12px;padding:20px;margin-bottom:25px;box-shadow:0 4px 6px rgba(0,0,0,.03),0 1px 3px rgba(0,0,0,.05)}
            .sidebar-a-title{font-size:18px;font-weight:600;margin-bottom:15px;color:#1e293b;display:flex;align-items:center}
            .sidebar-a-title .icon{margin-right:8px}
            .category-list{list-style:none}
            .category-item{padding:10px 0;border-bottom:1px solid #f1f5f9;display:flex;align-items:center;justify-content:space-between}
            .category-item:last-child{border-bottom:none}
            .category-name{display:flex;align-items:center}
            .category-icon{margin-right:10px;color:#64748b}
            .category-count{background-color:#f1f5f9;color:#64748b;padding:2px 8px;border-radius:10px;font-size:12px}
            .recommended-list{display:flex;flex-direction:column;gap:15px}
            .recommended-item{display:flex;gap:12px}
            .recommended-image{width:80px;height:60px;border-radius:6px;overflow:hidden;flex-shrink:0}
            .recommended-image img{width:100%;height:100%;object-fit:cover}
            .recommended-content{display:flex;flex-direction:column}
            .recommended-title{font-size:14px;font-weight:500;line-height:1.4;margin-bottom:5px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
            .recommended-meta{color:#94a3b8;font-size:12px}
            .search-a-container{display:flex;box-shadow:0 4px 8px rgba(0,0,0,.1);border-radius:25px;overflow:hidden}
            .search-a-container form{display:flex}
            .search-a-container .search-a-input{flex:1;padding:12px 20px;border:none;outline:0;font-size:16px;background-color:#fff;width:calc(100% - 80px)}
            .search-a-container .search-a-button{padding:12px 25px;border:none;background-color:#007bff;color:#fff;font-size:16px;cursor:pointer;transition:background-color .3s ease}
            .search-a-container .search-a-button:hover{background-color:#0056b3}

            @media (max-width:1024px){.article-a-image{width:220px;min-width:220px;height:160px}
            }
            @media (max-width:900px){.main-content-a{flex-direction:column}
            .sidebar-a{width:100%;min-width:100%}
            }
            @media (max-width:768px){.article-a-with-image{flex-direction:column}
            .article-a-image{width:100%;min-width:100%;height:200px}
            .header-a h1{font-size:24px}
            }
            @media (max-width:480px){.article-a-meta{flex-direction:column;align-items:flex-start;gap:5px}
            .article-a-title{font-size:16px}
            .article-a-description{-webkit-line-clamp:2}
            }
            .fresh-badge{position:absolute;top:15px;left:15px;background:rgba(59,130,246,.9);color:#fff;padding:3px 8px;border-radius:4px;font-size:12px;font-weight:500;z-index:1;backdrop-filter:blur(4px)}
            .article-a-card{position:relative}
            .article-a-highlight{border-left:3px solid #3b82f6}
            @keyframes fadeIn{from{opacity:0;transform:translateY(10px)}
            to{opacity:1;transform:translateY(0)}
            }
            .article-a-card{animation:fadeIn .5s ease forwards}
            .article-a-card:nth-child(2){animation-delay:.1s}
            .article-a-card:nth-child(3){animation-delay:.2s}
            .article-a-card:nth-child(4){animation-delay:.3s}
            .article-a-card:nth-child(5){animation-delay:.4s}
            
        </style>
        <?php 
            if($c['id']){
                $web = Db::name('article')->where(['open'=>1,'tid'=>$c['id']])->order('settop desc,id desc')->paginate([
                    'list_rows'=> 10,
                    'var_page' => 'page',
                    'query'=>request()->param()
                ]);
            }else{
                $web = Db::name('article')->where(['open'=>1])->where('title', 'like', '%' . input('ks') . '%')->order('settop desc,id desc')->paginate([
                    'list_rows'=> 10,
                    'var_page' => 'page',
                    'query'=>request()->param()
                ]);
            }
        ?>
        <div class="container">
            <header class="header-a">
                <h1>文章资讯</h1>
                <p>发现最新、最热门的科技、生活、文化资讯</p>
            </header>
            
            <div class="main-content-a">
                <!-- 左侧文章列表 -->
                <section class="article-as-section">
                    <h2 class="section-title">{if input('ks')}搜索“{:input('ks')}”{else/}{:dingyi($c.name,'文章资讯')}{/if}</h2>
                    
                    <div class="article-a-list">
                
                        {volist name="$web" id="vo" empty="<div class='empty'><img src='/public/static/img/empty.png'><p>暂无数据</p></div>"}
                            <?php $pic = pic(makeHtml($vo['content']),'1');?>
                            <!-- 无图片的文章 -->
                            <article-a class="article-a-card {if $pic != 1}article-a-with-image{else/}article-a-without-image{/if}">
                                {if $pic != 1}
                                <div class="article-a-image">
                                    <img src="{$pic}?imageView2/2/w/400/h/400/format/webp/q/90" alt="{$vo.title}">
                                </div>
                                {/if}
                                <div class="article-a-content">
                                    <h3 class="article-a-title">
                                        <a href="{:url('index/detail',['id'=>$vo.id])}">{$vo.title}</a>
                                    </h3>
                                    <p class="article-a-description">
                                        {:cut($vo.content,100)}
                                    </p>
                                    <div class="article-a-meta">
                                        <span class="article-a-date">
                                            <svg class="meta-icon" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                                <circle cx="12" cy="12" r="10"></circle>
                                                <polyline points="12 6 12 12 16 14"></polyline>
                                            </svg>
                                            {$t.times|times}
                                        </span>
                                        <span class="article-a-views">
                                            <svg class="meta-icon" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                                <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
                                                <circle cx="12" cy="12" r="3"></circle>
                                            </svg>
                                            {$vo.view} 次阅读
                                        </span>
                                    </div>
                                </div>
                            </article-a>
                        {/volist}
                    </div>
                    <div class="pagination">
                        {$web|raw}
                    </div>
                </section>
                
                <!-- 右侧边栏 -->
                <aside class="sidebar-a">
                     
                    <!-- 分类部分 -->
                    <div class="sidebar-a-section">
                        <h3 class="sidebar-a-title">
                            <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <line x1="8" y1="6" x2="21" y2="6"></line>
                                <line x1="8" y1="12" x2="21" y2="12"></line>
                                <line x1="8" y1="18" x2="21" y2="18"></line>
                                <line x1="3" y1="6" x2="3.01" y2="6"></line>
                                <line x1="3" y1="12" x2="3.01" y2="12"></line>
                                <line x1="3" y1="18" x2="3.01" y2="18"></line>
                            </svg>
                            文章分类
                        </h3>
                        <ul class="category-list">
                            <a href="{:url('index/article')}" {if !$c.id}style="color: red;"{/if}>
                                <li class="category-item">
                                    <span class="category-name">
                                        <svg class="category-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                            <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path>
                                            <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path>
                                        </svg>
                                        全部
                                    </span>
                                    <span class="category-count">{:db_count('article',['open'=>1])}</span>
                                </li>
                            </a>
                            {volist name=":db_select('article_cate',['open'=>1],'20','px desc')" id="vo"}
                            <a href="{:url('index/article',['id'=>$vo.id])}" {if $c.id == $vo.id}style="color: red;"{/if}>
                                <li class="category-item">
                                    <span class="category-name">
                                        <svg class="category-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                            <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path>
                                            <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path>
                                        </svg>
                                        {$vo.name}
                                    </span>
                                    <span class="category-count">{:db_count('article',['tid'=>$vo.id,'open'=>1])}</span>
                                </li>
                            </a>
                            {/volist}
                        </ul>
                    </div>
                    <div class="sidebar-a-section">
                        <div class="search-a-container">
                            <form action="{:url('index/article')}" method="get">
                                <input type="text" class="search-a-input" placeholder="请输入搜索内容..." name="ks" value="{:input('ks')}">
                                <button type="submit" class="search-a-button">搜索</button>
                            </form>
                        </div>
                    </div>
                    <!-- 推荐文章部分 -->
                    <div class="sidebar-a-section">
                        <h3 class="sidebar-a-title">
                            <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
                            </svg>
                            推荐阅读
                        </h3>
                        <div class="recommended-list">
                            {volist name=":db_select('article',['open'=>1],'15','view desc')" id="vo"}
                            <a href="{:url('index/article',['id'=>$vo.id])}" class="recommended-item">
                                <div class="recommended-image">
                                    <img src="{:pic(makeHtml($vo['content']))}?imageView2/2/w/400/h/400/format/webp/q/90" alt="{$vo.title}">
                                </div>
                                <div class="recommended-content">
                                    <h4 class="recommended-title">{$vo.title}</h4>
                                    <div class="recommended-meta">{$vo.view} 次阅读</div>
                                </div>
                            </a>
                            {/volist}
                        </div>
                    </div>
                </aside>
            </div>
        </div>
    </section>
</main>
目录
设置
主题设置
深色模式
字体设置
字体大小
16