Zapobieganie „podwójnym” ramkom w CSS


87

Powiedzmy, że mam dwa elementy div obok siebie ( jako odniesienie wybierz https://chrome.google.com/webstore/category/home ) z obramowaniem.

Czy istnieje sposób (najlepiej sztuczka CSS), aby zapobiec pojawianiu się moich elementów div tak, jakby miały podwójne obramowanie? Spójrz na ten obraz, aby lepiej zrozumieć, o co mi chodzi:

Ramka „podwójna”

Możesz zobaczyć, że tam, gdzie spotykają się dwa elementy div, wygląda na to, że mają podwójne obramowanie.


nie, używam tego z izotopem, więc nie mogę użyć stołu. elementy div mają różne rozmiary
john smith

Czy jest to problem tylko dla Ciebie od lewej do prawej, czy też musisz się tym martwić od góry do dołu?
VictorKilo,

Chciałbym, żeby było lepsze rozwiązanie tego w CSS. :-(
richardstelmach

Odpowiedzi:


19

#divNumberOne { border-right: 0; }


11
To jedyny prawdziwy sposób na zrobienie tego, który nie psuje innych rzeczy. Jeśli potrzebujesz zrobić wiele elementów, do diabła, powiedzmy 100 div, możesz zrobić, div { border-right: none; } div:last-child { border-right: 1px solid black; }co da ci zamierzony efekt
Andy

tak, zawsze można to zrobić w ten sposób, ale zastanawiałem się, czy można to zrobić w czystym CSS, bez konieczności używania więcej niż jednej klasy (będę miał więcej wierszy i kolumn)
john smith

3
To jest czysty css, użyłem pseudoklasy (ostatnie dziecko), więc i tak nie modyfikowałem html, jest wiele pseudoklas i powiedziałbym, że idź tą drogą, bo nie sądzę, że jest alternatywa
Andy

Zajrzyj do Nth Child, możesz to zrobić w ten sposób, używając nieparzystych i parzystych lub w zależności od układu możesz obliczyć to tak, jak chcesz.
MaxwellLynn

1
Dlaczego ta odpowiedź została zaakceptowana jako poprawna? Naprawdę nie sądzę, żeby tego szukał. Z pewnością nie jest to również rozwiązanie skalowalne.
Kevin Behan

78

Jeśli mówimy o elementach, których nie można zagwarantować, że pojawią się w określonej kolejności (może 3 elementy w jednym wierszu, a następnie wiersz z 2 elementami itp.), Potrzebujesz czegoś, co można umieścić na każdym elemencie w kolekcji . To rozwiązanie powinno obejmować:

.collection {
    /* these styles are optional here, you might not need/want them */
    margin-top: -1px;
    margin-left: -1px;
}

.collection .child {
    outline: 1px solid; /* use instead of border */
    margin-top: 1px;
    margin-left: 1px;
}

Pamiętaj, że konspekt nie działa w starszych przeglądarkach (IE7 i starsze).

Alternatywnie możesz trzymać się granic i używać ujemnych marginesów:

.collection .child {
    margin-top: -1px;
    margin-left: -1px;
}

1
Dziękuję za udostępnienie tego. Dosłownie pracowałem nad tym godzinami, idąc ścieżką graniczną (zamiast wytyczoną). To działało pięknie!
Jessy Houle

To naprawdę sprytna technika. Twoje zdrowie!
5

2
Bardzo użyteczne. Dodam też position: relative;left: 1px;, żeby cofnąć ujemną marżę.
Bartosz Walicki

1
To jest naprawdę sprytne !. Myślę, że to powinna być odpowiedź.
Rejoy

To o wiele lepsze niż odpowiedź
CH4B

20

HTML:

<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>

CSS:

div {
    border: 1px solid #000;
    float: left;
}

div:nth-child(n+2) {
    margin-left: -1px;
}

Próbny

Dołącz ie9.js do obsługi IE8 (jest to bardzo przydatne dla wszystkich selektorów / pseudoelementów CSS).


jeśli masz więcej niż jeden wiersz, pierwszy element div w drugim rzędzie nie ma lewej krawędzi i dzięki tej sztuczce wyrównanie elementów div idź w lewo o 1 piksel
Afshin

Czy nie było bardziej skomplikowanej wersji? A co z elementami z większym right-margin?
feeela

@afshin, jeśli nie widzę jego układu, jak mogę udzielić konkretnej odpowiedzi?
Giona

@feeela myślę, że to dość proste. W każdym razie right-marginnie ma wpływu left-margin: jsfiddle.net/gionaf/D6tHK/1
Giona

1
To rozwiązuje boczne podwójne granice, ale nie pionowe; obramowania na dole / na górze są nadal podwajane. Jakieś wskazówki?
delphirules

15

Innym rozwiązaniem, które można rozważyć, jest użycie selektora sąsiadującego rodzeństwa CSS .

CSS

div {
    border: 1px solid black;
}

div + div {
    border-left: 0;
}

jsFiddle


Niezła sztuczka, dzięki! Okazało się, że mam lepsze wyniki, używając w border-left: none;przeciwnym razie mam małą przerwę w lewym górnym rogu div !? (Firefox).
IanB

Możesz skorzystaćdiv + div { border-left: 0; }
Sergey Stadnik

6

Aby to osiągnąć, możesz użyć dziwnego selektora

.child{
   width:50%;
   float:left;
   box-sizing:border-box;
   text-align:center;
   padding:10px;
   border:1px solid black;
   border-bottom:none;
}
.child:nth-child(odd){
   border-right:none;
}
.child:nth-last-child(2),
.child:nth-last-child(2) ~ .child{
   border-bottom:1px solid black
}
<div>
    <div class="child" >1</div>
    <div class="child" >2</div>
    <div class="child" >3</div>
    <div class="child" >4</div>
    <div class="child" >5</div>
    <div class="child" >6</div>
    <div class="child" >7</div>
    <div class="child" >8</div>
</div>

wprowadź opis obrazu tutaj


czy nie byłoby lepiej zrobić nth-child (even) {border-left: none;}? W ten sposób może być nieparzysta liczba kolumn ...
pixelearth

5

Jeśli wszystkie elementy DIV mają tę samą nazwę klasy:

div.things {
    border: 1px solid black;
    border-left: none;
}

div.things:first-child {
    border-right: 1px solid black;
}

Jest tutaj demo JSFiddle .


+1 Jedna z nielicznych pseudoklas, które są rozpoznawane przez IE 7 + 8…
feeela

Nie jest dobrze, jeśli twój DIV jest w 2 rzędach: masz podwójne obramowanie między 2 rzędami ..
Didier68

@ Didier68 To nie było jednak pytanie.
Roddy of the Frozen Peas

Pytanie brzmi „zapobieganie podwójnemu obramowaniu”… ale bez określania, czy jest to poprzeczne czy pionowe… Twoje rozwiązanie jest dobre na przykład dla <TD>, ale nie dla DIV. Daję tę samą uwagę ryczącym Stephanowi!
Didier68

Nie mam pojęcia, o czym mówisz. Pytanie dotyczy div, odpowiedź dotyczy div, skrzypce używają div. Skąd bierzesz TD's?
Roddy of the Frozen Peas,

5

Spóźniłem się na przedstawienie, ale spróbuj użyć właściwości outline, na przykład:

.item {
  outline: 1px solid black;
}

Kontury w CSS nie zajmują miejsca fizycznego i dlatego będą się nakładać, aby zapobiec podwójnemu obramowaniu.


działa również, gdy wiersz dzieli się na więcej wierszy na mniejszych ekranach - wszystkie inne odpowiedzi nie działają, gdy elementy div mogą się podzielić na nowe wiersze. masz wtedy co najmniej jeden element DIV z bokiem bez obramowania. dzięki za udostępnienie - upvoted
DigitalJedi

O wiele lepiej mieć rozwiązanie niż włamanie. Dziękuję Ci.
forrest

1

Dodaj następujący kod CSS do elementu div po prawej stronie:

position: relative;
left: -1px; /* your border-width times -1 */

Lub po prostu usuń jedną z granic.


1

Po prostu używam

border-collapse: collapse;

w elemencie nadrzędnym


1

Używając Flexboksa, konieczne było dodanie drugiego pojemnika podrzędnego, aby poprawnie zachodziły na siebie kontury ...

<div class="grid__container">
    <div class="grid__item">
        <div class="grid__item-outline">
              <!-- content -->
        </div>
    </div>
</div>

SCSS

.grid__container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    margin: 0 1px 0 0; // margin-right 1px to give the correct width to the container
}

.grid__item {
    flex: 0 1 25%; // grid of 4
    margin: 0 0 1px; // margin-bottom to prevent double lines
}

.grid__item-outline {
    margin: 0 0 0 1px; // margin-left to prevent double lines
    outline: 1px solid #dedede;
}

0
  <div class="one"></div>
  <div class="two"></div>
  <div class="two"></div>
  <div class="two"></div>
  <div class="two"></div>

CSS:

  .one{
    width:100px;
    height:100px;
    border:thin red solid;
    float:left;
  }
.two{
    width:100px;
    height:100px;
    border-style: solid solid solid none;

    border-color:red;
    border-width:1px;
    float:left;
}

jsFiddle


0

Mój przypadek użycia dotyczył pudełek w jednym rzędzie, gdzie wiedziałem, jaki będzie ostatni element.

.boxes {
  border: solid 1px black  // this could be whatever border you need
  border-right: none;
}

.furthest-right-box {
  border-right: solid 1px black !important;
}

0

Wiem, że to późna reakcja, ale chciałem po prostu zrzucić swoje 2 centy, ponieważ mojego sposobu na zrobienie tego nie ma tutaj.

Widzisz, naprawdę nie lubię bawić się marżami, zwłaszcza ujemnymi . Wydaje się, że każda przeglądarka radzi sobie z tym trochę inaczej, a na marginesy łatwo wpływa wiele sytuacji.

Mój sposób na upewnienie się, że mam ładną tabelę z elementami div, polega najpierw na utworzeniu dobrej struktury html , a następnie zastosowaniu css.

Przykład jak to robię:

 <div class="tableWrap">
   <div class="tableRow tableHeaders">
     <div class="tableCell first">header1</div>
     <div class="tableCell">header2</div>
     <div class="tableCell">header3</div>
     <div class="tableCell last">header4</div>
   </div>
   <div class="tableRow">
     <div class="tableCell first">stuff</div>
     <div class="tableCell">stuff</div>
     <div class="tableCell">stuff</div>
     <div class="tableCell last">stuff</div>
   </div>
</div>

Teraz, w przypadku css, po prostu używam struktury wierszy, aby upewnić się, że krawędzie są tylko tam, gdzie powinny, co nie powoduje żadnych marginesów;

.tableWrap {
  display: table;
  }

.tableRow {
  display: table-row;
  }

.tableWrap .tableRow:first-child .tableCell {
  border-top: 1px solid #777777;
  }

.tableCell {
  display: table-cell;
  border: 1px solid #777777;
  border-left: 0;
  border-top: 0;
  padding: 5px;
  }

.tableRow .tableCell:first-child {
  border-left: 1px solid #777777;
  }

Et voila, idealny stół. Oczywiście spowodowałoby to, że twoje DIV miałyby różnice w szerokości 1px (szczególnie pierwszy), ale dla mnie to nigdy nie spowodowało żadnego problemu. Jeśli tak jest w twojej sytuacji, myślę, że byłbyś wtedy bardziej zależny od marż.


0

Udało mi się to osiągnąć za pomocą tego kodu:

td.highlight {
    outline: 1px solid yellow !important;
    box-shadow: inset 0px 0px 0px 3px yellow;
    border-bottom: 1px solid transparent !important;
}

0

Bardzo stare pytanie, ale był to pierwszy wynik w Google, więc dla każdego, kto się z tym spotka i nie chce mieć zapytań o media, aby ponownie dodać obramowanie po prawej / lewej stronie elementu na telefonie komórkowym itp.

Rozwiązanie, którego używam to:

.element {
    border: 1px solid black;
    box-shadow: 0 0 0 1px black;
}

To działa, ponieważ wokół elementu utworzonego z obramowania i cienia zobaczysz ramkę o wielkości 2 pikseli. Jednak tam, gdzie elementy się spotykają, cień zachodzi na siebie, dzięki czemu jest szeroki na 2 piksele;


-1

A co z margin:1px;dodawaniem dookoła swojego div.

<html>
<style>
.brd{width:100px;height:100px;background:#c0c0c0;border:1px solid red;float:left;margin:1px;}
</style>
<body>
    <div class="brd"></div>
    <div class="brd"></div>
    <div class="brd"></div>
</body>
</html>

PRÓBNY


-3

Wolę użyć innego div za nimi jako tła i usunąć wszystkie obramowania. Musisz tylko obliczyć rozmiar elementu div tła i położenie elementów div pierwszego planu.


Myślę, że moje rozwiązanie jest najlepsze, mimo krytyków. To ta sama zasada, co przy rysowaniu tabeli 1px:
dobrze7m
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.