CSS网格响应式布局,具有偶数个项目的自动调整和最小最大值

时间:2019-01-14 20:36:05

标签: html css responsive-design css-grid minmax

我要完成的工作:

有4个网格项。在最大的屏幕尺寸下,我希望将这些项目排成一行:

item_1 item_2 item_3 item_4

随着屏幕宽度的缩小,我希望这些项目像这样包装到下一行:

item_1 item_2

item_3 item_4

然后终于在最窄处,我希望时代成为一栏

item_1

item_2

item_3

item_4

我找到了一个执行此操作的示例,但仅在可能的情况下包装下一项– https://labs.jensimmons.com/2017/03-009.html

基于示例模型,我尝试使用嵌套的网格容器构建

grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));

HTML

<div class="outer_grid">
  <div class="grid">
    <div class="item">item 1</div>
    <div class="item">item 2</div>
  </div>
  <div class="grid">
    <div class="item">item 3</div>
    <div class="item">item 4</div>
  </div>
</div>

CSS

.outer_grid {
  display:grid;
  grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));
  grid-template-row:1fr 1fr;
  grid-gap:1em;
  border:5px solid blue;
}

.grid {
  display:grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-template-row:1fr 1fr;
  grid-gap:1em;
  border:5px solid green;
  height:200px;
}

.item {
  border:2px solid red;
}

它几乎可以工作(下面的代码笔),但是我不确定这是正确的方法还是有更好的方法来实现。我也尝试过使用Flexbox,但由于具有网格间隙功能,因此选择了CSS Grid。另外,我知道这是可以做到的,但是我正在尝试不使用媒体查询的情况。

https://codepen.io/anon/pen/LMqWEr?editors=1100

2 个答案:

答案 0 :(得分:0)

因此,据我了解,您实际上是在缩小时寻找一行要转换为一列或多列的项目,而无需使用媒体查询。

考虑到这一点,最好的方法是使用 Flexbox ,因为它是 1维

CSS网格也很强大,但仅当您想使用二维 布局(因此行和列)时才如此。

也很高兴知道 Flexbox 内容优先,而 CSS网格布局优先 >。

Codepen

.flex-container {
    display: flex;
    width: 100%;
    flex-wrap: wrap;
    justify-content: center;
}

.flex-container .flex-item {
    display: flex;
    min-width: 10rem;
    width: calc((100% - 1rem * 8 * 2) / 8);
    height: 10rem;
    padding: 1rem;
    margin: 1rem;
    align-items: center;
    justify-content: center;
    background: #1d1d1d;
    color: #fff;
    font-size: 2rem;
    font-weight: 500;
    text-align: center;
}
<div class="flex-container">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    <div class="flex-item">7</div>
    <div class="flex-item">8</div>
</div>

答案 1 :(得分:0)

import React, { Component } from 'react';
import { View, Text, FlatList, Image, ImageBackground, PixelRatio, Platform, UIManager, TouchableOpacity, LayoutAnimation } from 'react-native';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'
import DropDownItem from 'react-native-drop-down-item';


export default class App extends Component {

    constructor (props) {
    super(props)
    this.state ={

        users: [{

            uses1: '- Bottles',
            uses2: '- Cans',
            uses3: '- Jars',
            expanded: false
        },
        {
            uses1: '- Grays',
            uses2: '- Lines',
            uses3: '- Interior',
            expanded: false
        },
        {
            uses1: '- Live',
            uses2: '- Cutter',
            uses3: '- Riser',
            expanded: false
        },
    ]

    }
    if (Platform.OS === 'android') {
      UIManager.setLayoutAnimationEnabledExperimental(true);
    }

      }


      changeLayout =  ({index}) => {
        LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);

     this.setState(({ users }) => ({
        users: users.map((s, idx) => 
          idx === index ? {...s, expanded: !this.state.users[index].expanded} : {...s, expanded: false})
      }));
      console.log(this.state.users[index].expanded)



      };
//if uses1 + uses1.left + uses2 + uses2.left + uses3 + use3.left <=x then stay up or uses 3 go down

      getUses2style(index){
        if(this.state.users[index].uses1.length<=12)
        {return{ 
          fontSize: 17,
          left:100,
          top:-125,
          color: 'white',
          padding: 10}}
          else if(12<this.state.users[index].uses1.length<=22)
          {return{ 
            fontSize: 17,
            left:200,
            top:-125,
            color: 'white',
            padding: 10}}
      }

       render() {

//create an expand state for all materials in this.state
    return (
      // Remain Category image and CSS
      // add search bar
      <View
      style={{
        backgroundColor:'#262A2C',
        flex:1
      }}>
      <FlatList
     style={{marginTop:80,}}
        data={this.state.users}
        renderItem={({ item, index }) => (
       <View>

          <ImageBackground

          source={require('./Icons/error.png')} 
        //pay FlatIcon or design personal one
          style={{ 

            resizeMode: 'contain',

          position:'relative',

          width: wp('100%'), 
          left: wp('0%'),
          borderBottomWidth: 1,
          borderBottomColor: 'grey',
          padding: hp('6%'),
          }}
        >
       <View
            style={{
              flex:1,
             height:hp('19%'),
             width: wp('100%'),
             //height:hp('21%'),

              borderBottomColor: 'grey',

            }}>




              <Text 
              style={{ fontWeight: 'bold',
               fontSize: 22, 
               left:item.name.length<=5 ? wp('32.5%'):wp('27.5%'),
               top:hp('-9.5%'),


               }}>
               Stands
               </Text>
              <Text
              style={{
                fontWeight: 'bold',
                fontSize: 25, 
                top: hp('-25%'),
                left:wp('80%')

              }}>
              History
              </Text>


          </View>





   </ImageBackground>
   <TouchableOpacity activeOpacity={0.8}  
   onPress={() => {

             this.changeLayout({index})

              }} 

    style={{ padding: 10,

    backgroundColor:'black',

    left:wp('-10.9%'),
    top:hp('0%'),
    width: wp('120%'),
    height:hp('5%')}}>
   <Image
               style={{
               width:wp('9%'),
               height:hp('4.5%'),
              tintColor:'white',
              left:250,
              top:-10
               //tintColor:'#81F018'
               }}
               source={item.expanded ? require('./Icons/arrowDown.png') : require('./Icons/arrowUp.png') }/>
</TouchableOpacity>
<View style={{ height: item.expanded ? null : 0, overflow: 'hidden', backgroundColor:'black' }}>
            <Text 
            style={{
               fontSize: 17,
               left:150,
               top:-10,
               color: 'turquoise',
               padding: 10}}>
          Specs
            </Text>
            <View>

            </View>
            <Text 
            style={{
               fontSize: 17,
               left:125,
               top:-90,
               color: 'turquoise',
               padding: 10}}>
          Common uses
            </Text>
            <Text
             style={{
              fontSize: 17,
              left:0,
              top:-85,
              color: 'white',
              padding: 10}}>
{item.uses1}
            </Text>
            <Text
             style={
              this.getUses2style(index)}>
{item.uses2}
            </Text>
          </View>  
    </View>
        )}
      />
      </View>
    );
  }
}