有关正确使用表格或表格的问题。 HTML / CSS最佳做法问题

时间:2019-06-10 16:45:21

标签: html css

在尝试创建“服务计划”时遇到了一些问题,基本上我只希望页面具有一个表(但我希望所有人都在“网格”中),因为我发现了拥有“网格”表比实际使用真实表要容易得多。

但是,从本质上讲,我的“网格容器”是我的网格,我想知道这样做是否不好?我该如何解决。等等。我知道我的代码很可能还会出现其他错误,例如对于可能是一个类的7个唯一ID。

我遇到的1个问题是将“表”的顶部(实际上是网格容器(真正)标记为一个月,而将“表头”标记为它)。

我尝试在网格元素表中创建一个网格元素表。使用网格时,应该将所有内容都变成网格元素吗?

https://jsfiddle.net/9dm51zgr/1/

<html>
<body>
    <div class="main">
        <table class="main-table">
            <div class="month"> July </div>

            <table class="installer">
                <tr>
                    <th>Installers </th>
                </tr>
                <!-- Installer header -->
                <tr id="installer-row-1">
                    <td id="installer-name-1"> Installer </td=>
                </tr>
                <!-- Inst #1 -->
                <tr id="installer-row-2">
                    <td id="installer-name-2"> Installer </td>
                </tr>
                <!-- Inst #2 -->
                <tr id="installer-row-3">
                    <td id="installer-name-3"> Installer </td>
                </tr>
                <!-- Inst #3 -->
                <tr id="installer-row-4">
                    <td id="installer-name-4"> Installer </td>
                </tr>
                <!-- Inst #4 -->
                <tr id="installer-row-5">
                    <td id="installer-name-5"> Installer </td>
                </tr>
                <!-- Inst #5 -->
                <tr id="installer-row-6">
                    <td id="installer-name-6"> Installer </td>
                </tr>
                <!-- Inst #6 -->
                <tr id="installer-row-7">
                    <td id="installer-name-7"> Installer </td>
                </tr>
                <!-- Inst #7 -->
            </table>

            <div class="jobs"></div>
        </table>
    </div>
</body>
</html>

2 个答案:

答案 0 :(得分:3)

从技术上讲,<table>的唯一“正确”用法是显示表格数据时。

这意味着您将显示一组具有相似(或相同)结构的元素,以使它们的每个属性都显示在另一个下方,从而使表特定的任务更易于执行(或遵循),例如:计算列的总数或根据每个元素的特定属性的值对行进行重新排序。

实际上,<table>元素的作用(以及在大多数情况下应避免使用的原因)是:它跟踪每个单元格的内容(因此大小),确保所有单元格都对齐双向。

从渲染过程的角度来看,这是非常昂贵的。如此昂贵,以至于像Microsoft和Google这样的大公司,在开发其电子表格产品的在线版本(Excel和Google Sheets)时,也没有使用<table>元素来显示表格。他们使用<div>元素放置在绝对位置,同时通过JavaScript启用了您希望从表中获得的所有功能。
对于可能认为这无关紧要的任何人,请考虑到这两家公司都对渲染过程及其优化有深入的了解。然而,两者都得出结论,与使用<div>元素进行处理一样,将单元处理为<table>并将其渲染为<div>更为有效。

注意::当我说<table><div>时,我不一定指的是 se (作为display:table可以有<table>,而display:block可以有<table>)。我的意思是块/弹性/网格模型显示机制与表模型显示机制。

这应该使您了解渲染<table>的实际成本以及为什么每个人都坚持认为绝不应该将其用于布局。


总结:我并不是说您不应该使用display:grid。但是我是说,如果整体页面性能很重要,则不应该使用它们,即:

  • 如果您必须渲染大量表(超过10张)
  • 如果您打算在每个单元格上执行任何DOM操作,导致单元格被调整大小。由于每个单元格都会触发整个表的大小重新计算,因此降级速度非常快。从100个单元开始,性能明显下降。

在您的特定情况下,渲染日历,正确的解决方案是使用display:flex<table>。 但是,同样,如果您只想渲染一个月,而使用display:table花费较少的时间,请使用一个。

最后,当Web开发不妨碍及时完成任务并且不使用它不会使其他将来的(和必需的)任务涉及到Web开发时,应遵循最佳实践。代码不可能或非常昂贵。


根据您的问题,目前尚不清楚您是要渲染一年中的几个月,几周或几天,一个月中的某几天或几周还是一周中的某几天。
如果您在特定情况下需要更多帮助,请更新问题的详细信息,其中包括挑战的内容,为解决该问题所尝试的方法以及指向说明您尝试的方法应该起作用的任何文档的链接。

为证明日历中不需要Vue.config.productionTip = false; Vue.config.devtools = false; new Vue({ el: '#calendar', data: () => ({ months: moment.months(), year: moment().year(), fontSize: 14, }), methods: { daysInMonth(month, year) { year = year || this.year; return moment([year, month, 1]).daysInMonth(); }, getWeekday(day, month, year) { year = year || this.year; month = month || moment().month(); return moment([year, month, day]).day(); } } }),这里有一个快速的原型(〜1小时)。故意地,我没有使用模型/示例,因此我对它们的标记没有偏见。
我确实使用了Vue(臭名昭著的快速原型制作工具)和moment.js,这是处理JavaScript,恕我直言的时间所必需的:

.month-days {
  width: 13em;
  display: flex;
  align-items: flex-start;
  justify-content: space-evenly;
  flex-wrap: wrap;
}
.month-days:after {
  content: '';
  flex-grow: 1;
}
.month-days > span {
  flex: 0 0 calc(13em / 7);
  text-align: right;
  padding-right: .3em;
  box-sizing: border-box;
}
.today {
  color: red;
  font-weight: bold;
}
.calendar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-evenly;
  max-width: 60em;
  margin: 0 auto;
}
.title {
  text-align: center;
  background-color: #f5f5f5;
  padding: .2em 0;
}
.month {
  padding: .75em;
}
.year {
  max-width: 60em;
  margin: 0 auto;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
.year input {
  width: 6em;
  margin: 1rem;
}
.year input[type="number"] {
  margin: 0;
  width: 3.3rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>

<div id="calendar">
  <template>
    <div>
      <div class="year">
        font-size ({{fontSize}}px): <input type="range" v-model="fontSize" max="24" min="8">
        year (<input type="number" v-model="year" max="1e4" min="-1e4">): <input type="range" v-model="year" max="1e4" min="-1e4">
      </div>
      <div class="calendar" :style="{ fontSize: `${fontSize}px` }">
        <div v-for="(month, m) in months" :key="m" class="month">
          <div class="title" v-text="month"></div>
          <div class="month-days">
            <span v-for="e in getWeekday(1, m, year)" :key="`empty-${e}`"></span>
            <span v-for="d in daysInMonth(m, year)" :key="`day-${d}`" v-text="d"></span>
          </div>
        </div>
      </div>
    </div>
  </template>
</div>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://org.apache.axis2/xsd" xmlns:xsd1="http://dto.mgt.metadata.claim.identity.carbon.wso2.org/xsd">
   <soapenv:Header/>
   <soapenv:Body>
      <xsd:addLocalClaim>
         <!--Optional:-->
         <xsd:localClaim>
            <!--Zero or more repetitions:-->
            <xsd1:attributeMappings>
               <!--Optional:-->
               <xsd1:attributeName>email</xsd1:attributeName>
               <!--Optional:-->
               <xsd1:userStoreDomain>primary</xsd1:userStoreDomain>
            </xsd1:attributeMappings>
            <!--Zero or more repetitions:-->

               <xsd1:claimProperties>
                 <!--Optional:-->
                 <xsd1:propertyName>DisplayName</xsd1:propertyName>
                 <!--Optional:-->
                 <xsd1:propertyValue>email2</xsd1:propertyValue>
              </xsd1:claimProperties>
               <xsd1:claimProperties>
                 <!--Optional:-->
                 <xsd1:propertyName>Description</xsd1:propertyName>
                 <!--Optional:-->
                 <xsd1:propertyValue>email2 local cliam</xsd1:propertyValue>
              </xsd1:claimProperties>
               <xsd1:claimProperties>
                 <!--Optional:-->
                 <xsd1:propertyName>SupportedByDefault</xsd1:propertyName>
                 <!--Optional:-->
                 <xsd1:propertyValue>true</xsd1:propertyValue>
              </xsd1:claimProperties>
               <xsd1:claimProperties>
                 <!--Optional:-->
                 <xsd1:propertyName>Required</xsd1:propertyName>
                 <!--Optional:-->
                 <xsd1:propertyValue>true</xsd1:propertyValue>
              </xsd1:claimProperties>
               <xsd1:claimProperties>
                 <!--Optional:-->
                 <xsd1:propertyName>Required</xsd1:propertyName>
                 <!--Optional:-->
                 <xsd1:propertyValue>true</xsd1:propertyValue>
              </xsd1:claimProperties>
               <xsd1:claimProperties>
                 <!--Optional:-->
                 <xsd1:propertyName>ReadOnly</xsd1:propertyName>
                 <!--Optional:-->
                 <xsd1:propertyValue>true</xsd1:propertyValue>
              </xsd1:claimProperties>

            <!--Optional:-->
            <xsd1:localClaimURI>http://example.org/email</xsd1:localClaimURI>
         </xsd:localClaim>
      </xsd:addLocalClaim>
   </soapenv:Body>
</soapenv:Envelope>

答案 1 :(得分:0)

目前,您正在将一个<table>嵌套在另一个<table>中。

我建议这是次优的方法,当然也不是最佳的演示方法。

按照偏好,我将尝试以下操作:

  1. CSS网格
  2. CSS表
  3. CSS Flexbox(使用flex-wrap: wrap
  4. HTML <table>(使用rowspancolspan属性以避免嵌套)