Colspan HTML w CSS

251

Próbuję zbudować układ podobny do następującego:

+---+---+---+
|   |   |   |
+---+---+---+
|           |
+-----------+

gdzie dno wypełnia przestrzeń górnego rzędu.

Gdyby to był prawdziwy stół, mógłbym to łatwo osiągnąć <td colspan="3">, ale ponieważ tworzę układ podobny do tabeli , nie mogę używać <table>znaczników. Czy jest to możliwe przy użyciu CSS?

Wieża
źródło
8
Najlepsze rozwiązanie naprawdę zależy od tego, co trafi do stołu. Jeśli są to dane (coś, co należy do tabeli), użyj tabeli. Jeśli używasz tabeli do kontrolowania układu strony, wówczas jedno z poniższych rozwiązań HTML + CSS jest lepsze.
mwcz
Dodaj znaczniki dla obu przypadków, a następnie wyświetlaj tylko jeden na raz za pomocą klasy CSS zapytania Media.
DigitalDesignDj
2
Zapomnij o CSS. Jeśli wyświetlasz dane tabelaryczne, z pewnością wiedziałbyś, ile kolumn by to obejmowało. Użyj colspanatrybutu
Tihomir Mitkov
Zrobiłbym to przez bootstrap lub niestandardową siatkę z bootstrap
Arun Prasad ES
Jeśli używasz CSS3, możesz użyć columnSpan. W przeciwieństwie do <td colspan = "#">, nie masz możliwości ustawienia liczby kolumn, ale możesz objąć wszystkie kolumny. w3schools.com/cssref/css3_pr_column-span.asp
MistyDawn

Odpowiedzi:

407

Nie ma prostego, eleganckiego analogu CSS colspan.

Wyszukiwania tego właśnie zagadnienia zwrócą różnorodne rozwiązania, które obejmują szereg alternatyw, w tym bezwzględne pozycjonowanie, określanie wielkości, a także podobną różnorodność ostrzeżeń dotyczących konkretnej przeglądarki i okoliczności. Przeczytaj i podejmij najlepszą świadomą decyzję na podstawie tego, co znajdziesz.

David
źródło
10
Tabele są elementami strukturalnymi i tylko dlatego, że użycie colspan zmienia jego wygląd, nie znaczy, że nie jest. CSS służy do stylizowania elementów, a nie zmiany struktury. W3C omawia tutaj strukturę tabeli: w3.org/TR/html401/struct/tables.html#h-11.2
Rob
88
Rob, zrozum swoje stanowisko, ale spójrz na rekomendacje W3C - szczególnie dotyczące całego paradygmatu stołu - a przekonasz się, że częścią ich rozważań była z pewnością prezentacja tabel. Pomysł, że stoły zostały stworzone wyłącznie jako struktura, jest współczesną fikcją. Myślę, że lepiej byłoby, gdybyśmy przestali się rozprzestrzeniać. Chodzi o to, że musimy przestać być dogmatycznymi o stołach. Błędem byłoby dla mnie twierdzenie, że zawsze są one prezentacją, i równie błędne jest twierdzenie, że zawsze mają strukturę. Rzeczywistość po prostu nie jest taka wycięta i wysuszona.
David
4
Wygląda na to, że twoja odpowiedź jest popularną odpowiedzią. :) Z radością dowiaduję się, że dogmat anty-stołowy (do którego się kupiłem) jest zbyt surowy. Podtrzymuję swoją odpowiedź tylko o tyle, o ile nadal uważam, że colspanjest to właściwe narzędzie do pracy. Moja odpowiedź była w 75% słuszna, a twoja w 100% słuszna. Powinieneś wrócić do SO.
mwcz
71
Po 2 latach przeszukałem to i chciałem zagłosować na autora, ale powiedział: „nie mogę głosować na swój post” i zdałem sobie sprawę, że to ja, lol. Zdecydowałem się zmienić przyjęte rozwiązanie na to, ponieważ uważam, że ma ono lepsze informacje.
Wieża
14
To jest mini-esej na temat innych (nieokreślonych) odpowiedzi, a nie odpowiedzi na zadane pytanie.
Jukka K. Korpela
56

O ile wiem, w css nie ma colspan, ale column-spanw niedalekiej przyszłości będzie dostępny układ wielu kolumn, ale ponieważ jest to tylko szkic w CSS3, możesz to sprawdzić tutaj . W każdym razie możesz obejść to za pomocą divi spanz wyświetlaniem podobnym do tabeli.

Byłby to HTML:

<div class="table">
  <div class="row">
    <span class="cell red first"></span>
    <span class="cell blue fill"></span>
    <span class="cell green last"></span>
  </div>
</div>
<div class="table">
  <div class="row">
    <span class="cell black"></span>
  </div>
</div>

A to będzie css:

  /* this is to reproduce table-like structure
     for the sake of table-less layout. */
  .table { display:table; table-layout:fixed; width:100px; }
  .row { display:table-row; height:10px; }
  .cell { display:table-cell; }

  /* this is where the colspan tricks works. */
  span { width:100%; }

  /* below is for visual recognition test purposes only. */
  .red { background:red; }
  .blue { background:blue; }
  .green { background:green; }
  .black { background:black; }

  /* this is the benefit of using table display, it is able 
     to set the width of it's child object to fill the rest of 
     the parent width as in table */
  .first { width: 20px; }
  .last { width: 30px; }
  .fill { width: 100%; }

Jedynym powodem, dla którego warto skorzystać z tej sztuczki, jest czerpanie korzyści z table-layoutzachowania, używam jej dużo, jeśli tylko ustawienie div i rozpiętości rozpiętości do określonego procentu nie spełniło naszych wymagań projektowych.

Ale jeśli nie musisz czerpać korzyści z tego table-layoutzachowania, odpowiedź durilai wystarczyłaby ci.

Hendra Uzia
źródło
4
Tak, ale mała poprawka: zamiast .span { ...tego powinno być span { ....
Slavik Meltser,
2
Używanie divtagów do wyświetlania danych tabelarycznych jest równie złe, jak używanie tables do kontrolowania układu strony
Tihomir Mitkov
1
@TichomirMitkov zależy od tego, czy używasz responsywnego projektu do zmiany układu - w takim przypadku czasami może to działać całkiem dobrze.
Simon_Weaver,
4
To tak naprawdę nie odpowiada na pytanie, ponieważ w zasadzie podałeś dwa tabele jeden za drugim. (Ietwo divs z klasą „table”)
Zima
21

Inną sugestią jest użycie Flexboksa zamiast tabel. To oczywiście „nowoczesna przeglądarka”, ale daj spokój, to 2016;)

Przynajmniej może to być alternatywne rozwiązanie dla osób szukających odpowiedzi na to pytanie, ponieważ oryginalny post pochodzi z 2010 roku.

Oto świetny przewodnik: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

.table {
  border: 1px solid red;
  padding: 2px;
  max-width: 300px;
  display: flex;
  flex-flow: row wrap;
}
.table-cell {
  border: 1px solid blue;
  flex: 1 30%;
}
.colspan-3 {
  border: 1px solid green;
  flex: 1 100%;
}
<div class="table">
  <div class="table-cell">
    row 1 - cell 1
  </div>
  <div class="table-cell">
    row 1 - cell 2
  </div>
  <div class="table-cell">
    row 1 - cell 3
  </div>
  <div class="table-cell colspan-3">
    row 2 - cell 1 (spans 3 columns)
  </div>
</div>

Zimowy
źródło
8
<div style="width: 100%;">
    <div style="float: left; width: 33%;">Row 1 - Cell 1</div>
    <div style="float: left; width: 34%;">Row 1 - Cell 2</div>
    <div style="float: left; width: 33%;">Row 1 - Cell 3</div>
</div>
<div style="clear: left; width: 100%;">
Row 2 - Cell 1
</div>
Dustin Laine
źródło
Nie znam szerokości komórek.
Wieża
1
Więc nie umieszczaj szerokości. To nie powinno mieć znaczenia. Ale jeśli chcesz, aby obejmowały tę samą szerokość, wówczas dwa główne div muszą mieć tę samą szerokość.
Dustin Laine,
1
Możesz użyć width: calc (100% / 3), co zrobi trochę lepiej niż dając środkowi 1% więcej
ii iml0sto1
5

To nie jest częścią kompetencji CSS. colspanopisuje strukturę zawartości strony lub nadaje znaczenie danym w tabeli, która jest zadaniem HTML.

mwcz
źródło
OP wyraźnie wspomina o „tworzeniu układu podobnego do tabeli ”, bez znaczenia strukturalnego. Czy nie jest to celem tabel CSS? Nie ma obiektywnego powodu, aby traktować właściwość colspan inaczej niż całą tabelę, jeśli istnieje element tabeli CSS tylko do projektowania, to dlaczego nie własność colspan tylko do projektowania…
Skippy le Grand Gourou 25.04.16
2
Sprawdź najczęściej głosowaną odpowiedź na to pytanie. Twój sentyment jest już tam omawiany i jestem skłonny się z tym zgodzić. Moja opinia na ten temat zdecydowanie zmieniła się w ciągu pięciu lat, odkąd napisałem tę odpowiedź.
mwcz
4

Aby udzielić aktualnej odpowiedzi: Najlepszym sposobem na zrobienie tego dzisiaj jest użycie układu siatki css w następujący sposób:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto;
  grid-template-areas: 
    "top-left top-middle top-right"
    "bottom bottom bottom"
}

.item-a {
  grid-area: top-left;
}
.item-b {
  grid-area: top-middle;
}
.item-c {
  grid-area: top-right;
}
.item-d {
  grid-area: bottom;
}

i HTML

<div class="item-a">1</div>
<div class="item-b">2</div>
<div class="item-c">3</div>
<div class="item-d">123</div>
Toby 1 Kenobi
źródło
3

Możesz spróbować użyć systemu siatki, takiego jak http://960.gs/

Twój kod wyglądałby mniej więcej tak, zakładając, że używasz układu „12 kolumn”:

<div class="container_12">
<div class="grid_4">1</div><div class="grid_4">2</div><div class="grid_4">3</div>
<div class="clear"></div>
<div class="grid_12">123</div>
</div>
Jeff
źródło
3

Spróbuj dodać display: table-cell; width: 1%;do elementu komórki tabeli.

Ismail Farooq
źródło
jak to pomoże? Podstawową koncepcją tabeli jest to, że każdy wiersz ma identyczne komórki. Jeśli jeden z wierszy ma komórkę, która z powodzeniem implementuje „szerokość: 1%”, wówczas wszystkie wiersze będą miały tę kolumnę jako „szerokość: 1%”. Celem „colspan” jest pobranie 2 (lub więcej) kolumn o stałej szerokości i połączenie ich w celu uzyskania łącznej szerokości.
IAM_AL_X
3

Odniosłem pewien sukces, chociaż działa on w oparciu o kilka właściwości:

table-layout: fixed border-collapse: separate

oraz „szerokości” komórek, które łatwo dzielą / rozpinają, tj. 4 x komórki o szerokości 25%:

.div-table-cell,
* {
  box-sizing: border-box;
}

.div-table {
  display: table;
  border: solid 1px #ccc;
  border-left: none;
  border-bottom: none;
  table-layout: fixed;
  margin: 10px auto;
  width: 50%;
  border-collapse: separate;
  background: #eee;
}

.div-table-row {
  display: table-row;
}

.div-table-cell {
  display: table-cell;
  padding: 15px;
  border-left: solid 1px #ccc;
  border-bottom: solid 1px #ccc;
  text-align: center;
  background: #ddd;
}

.colspan-3 {
  width: 300%;
  display: table;
  background: #eee;
}

.row-1 .div-table-cell:before {
  content: "row 1: ";
}

.row-2 .div-table-cell:before {
  content: "row 2: ";
}

.row-3 .div-table-cell:before {
  content: "row 3: ";
  font-weight: bold;
}

.div-table-row-at-the-top {
  display: table-header-group;
}
<div class="div-table">

  <div class="div-table-row row-1">

    <div class="div-table-cell">Cell 1</div>
    <div class="div-table-cell">Cell 2</div>
    <div class="div-table-cell">Cell 3</div>

  </div>

  <div class="div-table-row row-2">

    <div class="div-table-cell colspan-3">
      Cor blimey he's only gone and done it.
    </div>

  </div>

  <div class="div-table-row row-3">

    <div class="div-table-cell">Cell 1</div>
    <div class="div-table-cell">Cell 2</div>
    <div class="div-table-cell">Cell 3</div>

  </div>

</div>

https://jsfiddle.net/sfjw26rb/2/

Ponadto zastosowanie display: table-header-group lub table-footer-group to przydatny sposób przeskakiwania elementów „row” na górę / dół „table”.

użytkownik3464561
źródło
0

jeśli użyjesz div i span, zajmie on większy rozmiar kodu, gdy wiersz tabeli datagrid będzie miał więcej objętości. Poniższy kod jest sprawdzany we wszystkich przeglądarkach

HTML:

<div id="gridheading">
<h4>Sl.No</h4><h4 class="big">Name</h4><h4>Location</h4><h4>column</h4><h4>column</h4><h4>column</h4><h4>Amount(Rs)</h4><h4>View</h4><h4>Edit</h4><h4>Delete</h4> 
</div>
<div class="data"> 
<h4>01</h4><h4 class="big">test</h4><h4>TVM</h4><h4>A</h4><h4>I</h4><h4>4575</h4><h4>4575</h4></div>
<div class="data"> 
<h4>01</h4><h4 class="big">test</h4><h4>TVM</h4><h4>A</h4><h4>I</h4><h4>4575</h4><h4>4575</h4></div>

CSS:

#gridheading {
    background: #ccc;
    border-bottom: 1px dotted #BBBBBB;
    font-size: 12px;
    line-height: 30px;
    text-transform: capitalize;
}
.data {
    border-bottom: 1px dotted #BBBBBB;
    display: block;
    font-weight: normal;
    line-height: 20px;
    text-align: left;
    word-wrap: break-word;
}
 h4 {
    border-right: thin dotted #000000;
    display: table-cell;
    margin-right: 100px;
    text-align: center;
    width: 100px;
    word-wrap: break-word;
}
.data .big {
    margin-right: 150px;
    width: 200px;
}
Web Designer cum Promotor
źródło
0
column-span: all; /* W3C */
-webkit-column-span: all; /* Safari & Chrome */
-moz-column-span: all; /* Firefox */
-ms-column-span: all; /* Internet Explorer */
-o-column-span: all; /* Opera */

http://www.quackit.com/css/css3/properties/css_column-span.cfm

Adam Hunter Peck
źródło
nie wystarczy wsparcie ... IE8 jest niestety nadal przewlekły problem dla ewolucji
beauXjames
9
OP chce mieć table-cellwiele kolumn tabeli. column-spansłuży do sterowania układem kolumn. Pozwala to na przepływ tekstu przez kilka kolumn, tak jak robią to gazety.
Chris Wesseling
1
Rzeczywiście - podczas gdy byłoby to naprawdę dobre w użyciu na wyświetlaczu: komórka tabeli; elementy, to dotyczy tylko kolumn css: jsfiddle.net/mk0rrLc3/1
Mark
@ Znak - rozpiętość kolumn jest używana z właściwością liczenia kolumn zdefiniowaną w obiekcie nadrzędnym. Zmiana rodzaju wyświetlania nie jest konieczna. Ponadto rozpiętość kolumn może przyjmować tylko 1 lub wszystkie jako wartość, nie pozwala na frakcjonowanie, dlatego „rozpiętość kolumn: 2”, jak widać w skrzypcach, nie jest prawidłowym użyciem właściwości.
MistyDawn
0

Jeśli przyjedziesz tutaj, ponieważ musisz włączyć lub wyłączyć colspanatrybut (np. W przypadku układu mobilnego):

Zduplikuj <td>s i pokaż tylko te z pożądanymi colspan:

table.colspan--on td.single {
  display: none;
}

table.colspan--off td.both {
  display: none;
}
<!-- simple table -->
<table class="colspan--on">
  <thead>
    <th>col 1</th>
    <th>col 2</th>
  </thead>
  <tbody>
    <tr>
      <!-- normal row -->
      <td>a</td>
      <td>b</td>
    </tr>
    <tr>
      <!-- the <td> spanning both columns -->
      <td class="both" colspan="2">both</td>

      <!-- the two single-column <td>s -->
      <td class="single">A</td>
      <td class="single">B</td>
    </tr>
    <tr>
      <!-- normal row -->
      <td>a</td>
      <td>b</td>
    </tr>
  </tbody>
</table>
<!--
that's all
-->

 

<!--
stuff only needed for making this interactive example looking good:
-->
<br><br>
<button onclick="toggle()">Toggle colspan</button>
<script>/*toggle classes*/var tableClasses = document.querySelector('table').classList;
function toggle() {
  tableClasses.toggle('colspan--on');
  tableClasses.toggle('colspan--off');
}
</script>
<style>/* some not-needed styles to make this example more appealing */
td {text-align: center;}
table, td, th {border-collapse: collapse; border: 1px solid black;}</style>

luckydonald
źródło
0

Właściwości CSS „liczba kolumn”, „przerwa między kolumnami” i „rozpiętość kolumn” mogą to zrobić w taki sposób, aby wszystkie kolumny pseudo-tabeli znajdowały się w tym samym opakowaniu (HTML pozostaje miły i schludny).

Jedynym zastrzeżeniem jest to, że możesz zdefiniować tylko 1 kolumnę lub wszystkie kolumny, a rozpiętość kolumn nie działa jeszcze w Firefoksie, więc konieczne jest dodanie dodatkowego CSS, aby zapewnić prawidłowe wyświetlanie. https://www.w3schools.com/css/css3_multiple_columns.asp

.split-me {
  -webkit-column-count: 3;
  -webkit-column-gap: 0;
  -moz-column-count: 3;
  -moz-column-gap: 0;
  column-count: 3;
  column-gap: 0;
}

.cols {
  /* column-span is 1 by default */
  column-span: 1;
}

div.three-span {
  column-span: all !important;
}

/* alternate style for column-span in Firefox */
@-moz-document url-prefix(){
  .three-span {
    position: absolute;
    left: 8px;
    right: 8px;
    top: auto;
    width: auto;
  }
}


    
<p>The column width stays fully dynamic, just like flex-box, evenly scaling on resize.</p>

<div class='split-me'>
  <div class='col-1 cols'>Text inside Column 1 div.</div>
  <div class='col-2 cols'>Text inside Column 2 div.</div>
  <div class='col-3 cols'>Text inside Column 3 div.</div>
  <div class='three-span'>Text div spanning 3 columns.</div>
</div>



  <style>
/* Non-Essential Visual Styles */

html * { font-size: 12pt; font-family: Arial; text-align: center; }
.split-me>* { padding: 5px; } 
.cols { border: 2px dashed black; border-left: none; }
.col-1 { background-color: #ddffff; border-left: 2px dashed black; }
.col-2 { background-color: #ffddff; }
.col-3 { background-color: #ffffdd; }
.three-span {
  border: 2px dashed black; border-top: none;
  text-align: center; background-color: #ddffdd;
}
  </style>

MistyDawn
źródło
0

Przybyłem tutaj, ponieważ obecnie blok tabeli WordPress nie obsługuje parametru colspan i pomyślałem, że zastąpię go za pomocą CSS. To było moje rozwiązanie, zakładając, że kolumny mają tę samą szerokość:

table {
  width: 100%;
}

table td {
  width: 50%;
  background: #dbdbdb;
  text-align: center;
}

table tr:nth-child(2n+1) {
  position:relative;
  display:block;
  height:20px;
  background:green;
}

table tr:nth-child(2n+1) td {
  position:absolute;
  left:0;
  right:-100%;
  width: auto;
  top:0;
  bottom:0;
  background:red;
  text-align:center;
}
<table>
    <tr>
        <td>row</td>
    </tr>
    <tr>
        <td>cell</td>
        <td>cell</td>
    </tr>
    <tr>
        <td>row</td>
    </tr>
    <tr>
        <td>cell</td>
        <td>cell</td>
    </tr>
</table>

passatgt
źródło
-1

Zawsze position:absolute;możesz rzeczy i określić szerokości. Nie jest to zbyt płynny sposób, ale zadziałałoby.

doubleJ
źródło
Jest o wiele więcej sposobów na osiągnięcie tego niż użycie złych znaczników. Absolutne pozycjonowanie w celu wymuszenia układu zawsze było uważane za złą praktykę.
MistyDawn
-1

Stworzyłem to skrzypce:

wprowadź opis zdjęcia tutaj

http://jsfiddle.net/wo40ev18/3/

HTML

<div id="table">
<div class="caption">
    Center Caption
</div>
<div class="group">
      <div class="row">
            <div class="cell">Link 1t</div>
            <div class="cell"></div>
          <div class="cell"></div>
          <div class="cell"></div>
            <div class="cell"></div>
            <div class="cell ">Link 2</div>
      </div>
</div>

CSS

   #table {
    display:table;
}

.group {display: table-row-group; }

.row {
    display:table-row;
    height: 80px;
    line-height: 80px;
}

.cell {
    display:table-cell;
    width:1%;
    text-align: center;
    border:1px solid grey;
    height: 80px
        line-height: 80px;
}

.caption {
    border:1px solid red; caption-side: top; display: table-caption; text-align: center; 
    position: relative;
    top: 80px;
    height: 80px;
      height: 80px;
    line-height: 80px;

}
Layke
źródło
1
Ale myślę, że siatka bootstrap może to zrobić bardzo łatwo
Arun Prasad ES
Nie zapewnia to rozwiązania, którego szukał pytający. Po prostu tworzy wiersz komórek.
MistyDawn
-1

Klasy Media Query mogą być używane do osiągnięcia czegoś znośnego dzięki zdublowanym znacznikom. Oto moje podejście do bootstrap:

  <tr class="total">
    <td colspan="1" class="visible-xs"></td>
    <td colspan="5" class="hidden-xs"></td>
    <td class="focus">Total</td>
    <td class="focus" colspan="2"><%= number_to_currency @cart.total %></td>
  </tr>

colspan 1 dla urządzeń mobilnych, colspan 5 dla innych z CSS wykonującymi pracę.

DigitalDesignDj
źródło
Pytający wyraźnie stwierdził, że nie może używać elementów HTML <table>. Gdyby mógł, byłby to łatwy problem do rozwiązania.
MistyDawn