Navbar с логотипом и некоторыми элементами в середине и одним предметом на правой стороне [дубликат]

Используйте getopt() или, возможно, getopt_long() .

int iflag = 0;
enum { WORD_MODE, LINE_MODE } op_mode = WORD_MODE;  // Default set
int opt;

while ((opt = getopt(argc, argv, "ilw") != -1)
{
    switch (opt)
    {
    case 'i':
        iflag = 1;
        break;
    case 'l':
        op_mode = LINE_MODE;
        break;
    case 'w':
        op_mode = WORD_MODE;
        break;
    default:
        fprintf(stderr, "Usage: %s [-ilw] [file ...]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
}

/* Process file names or stdin */
if (optind >= argc)
    process(stdin, "(standard input)", op_mode);
else
{
    int i;
    for (i = optind; i < argc; i++)
    {
        FILE *fp = fopen(argv[i], "r");
        if (fp == 0)
            fprintf(stderr, "%s: failed to open %s (%d %s)\n",
                    argv[0], argv[i], errno, strerror(errno));
        else
        {
            process(fp, argv[i], op_mode);
            fclose(fp);
        }
    }
 }

Обратите внимание, что вам нужно определить, какие заголовки должны включать (I сделайте 4, которые требуются), и способ, которым я написал тип op_mode, означает, что у вас есть проблема в функции process() - вы не можете получить доступ к перечислению там. Лучше всего переместить перечисление вне функции; вы можете даже сделать op_mode переменную с файлом без внешней привязки (причудливый способ сказать static), чтобы избежать передачи ее функции. Этот код не обрабатывает - как синоним стандартного ввода, другое упражнение для читателя. Обратите внимание, что getopt() автоматически выполняет --, чтобы отметить конец опций для вас.

Я не запускал какую-либо версию ввода выше компилятора; в нем могут быть ошибки.


Для дополнительного кредита напишите функцию (библиотека):

int filter(int argc, char **argv, int idx, int (*function)(FILE *fp, const char *fn));

, которая инкапсулирует логику для обработки параметров имени файла после getopt(). Он должен обрабатывать - в качестве стандартного ввода. Обратите внимание, что использование этого будет означать, что op_mode должно быть переменной статического файла. Функция filter() принимает argc, argv, optind и указатель на функцию обработки. Он должен вернуть 0 (EXIT_SUCCESS), если он смог открыть все файлы и все вызовы функции 0, иначе 1 (или EXIT_FAILURE). Наличие такой функции упрощает запись программ «фильтра» в стиле Unix, которые читают файлы, указанные в командной строке или стандартном вводе.

43
задан Michael_B 5 September 2016 в 18:45
поделиться

2 ответа

Ниже приведены пять вариантов достижения этого макета:

  • Позиционирование CSS
  • Flexbox с невидимым элементом DOM
  • Flexbox с невидимым псевдоэлементом
  • Flexbox с flex: 1
  • CSS Grid Layout

Метод # 1: Свойства позиционирования CSS

Применить position: relative к контейнеру гибкого диска.

Применить position: absolute к пункту D.

Теперь этот элемент абсолютно расположен внутри контейнера flex.

Подробнее , элемент D удаляется из потока документов, но остается в пределах ближайшего расположенного предка .

Используйте свойства смещения CSS top и right для перемещения этого элемента в положение

li:last-child {
  position: absolute;
  top: 0;
  right: 0;
  background: #ddd;
}
ul {
  position: relative;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p {
  text-align: center;
  margin-top: 0;
}
span {
  background-color: aqua;
}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>true center</span></p>

Одно из предостережений в этом методе состоит в том, что некоторые браузеры могут не полностью удалить абсолютно позиционированный элемент гибкости из нормальный поток. Это изменяет выравнивание нестандартным, неожиданным способом. Подробнее: Абсолютно позиционированный элемент гибкости не удаляется из нормального потока в IE11


Метод №2: Flex Auto Margins & amp; Invisible Flex Item (элемент DOM)

С комбинацией полей auto и нового невидимого элемента гибкости макет может быть достигнут.

новый элемент гибкости идентичен элементу D и расположен на противоположном конце (левый край).

Более конкретно, поскольку выравнивание гибкости основано на распределении свободного места, новый элемент является необходимым противовесом для сохранения трех средних квадратов по горизонтали. Новый элемент должен иметь ту же ширину, что и существующий элемент D, или средние поля не будут точно центрированы.

Новый элемент удаляется из представления с помощью visibility: hidden.

Короче:

  • Создайте дубликат элемента D.
  • Поместите его в начало списка.
  • Используйте flex auto, чтобы сохранить A, B и C в центре, причем оба элемента D создают одинаковый баланс с обоих концов.
  • Примените visibility: hidden к дубликату D

li:first-child {
  margin-right: auto;
  visibility: hidden;
}
li:last-child {
  margin-left: auto;
  background: #ddd;
}
ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
  <li>D</li><!-- new; invisible spacer item -->
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>true center</span></p>


Способ №3: Автоматические поля Flex и amp; Invisible Flex Item (псевдоэлемент)

Этот метод аналогичен # 2, за исключением того, что он очищен семантически, и ширина D должна быть известна.

  • Создайте псевдо-элемент с той же шириной, что и D.
  • Поместите его в начале контейнера с помощью ::before.
  • Используйте поля flex auto, чтобы сохранить A , B и C идеально центрированы, причем элементы псевдо и D создают одинаковый баланс с обоих концов.

ul::before {
  content:"D";
  margin: 1px auto 1px 1px;
  visibility: hidden;
  padding: 5px;
  background: #ddd;
}
li:last-child {
  margin-left: auto;
  background: #ddd;
}
ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>true center</span></p>


Способ №4: Добавить flex: 1 в левый и правый элементы

Начиная с метода № 2 или № 3 выше, вместо того, чтобы беспокоиться о равной ширине для левой и правой правильные элементы для поддержания равного баланса, просто дайте каждому flex: 1. Это заставит их обоих потреблять свободное пространство, центрируя средний элемент.

Затем вы можете добавить display: flex к отдельным элементам, чтобы выровнять их содержимое.

ПРИМЕЧАНИЕ об использовании этого метода с min-height: В настоящее время в Chrome, Firefox, Edge и, возможно, в других браузерах правило сокращения flex: 1 ломается до этого:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

Этот процентный блок (%) в flex-basis вызывает это метод прерывания, когда min-height используется в контейнере. Это связано с тем, что, как правило, в процентах высоты для детей требуется явное свойство свойства height для родителя.

Это старое правило CSS, относящееся к 1998 году ( CSS Level 2 ), который по-прежнему действует во многих браузерах в той или иной степени. Подробнее см. Здесь здесь и здесь .

Вот иллюстрация проблемы, опубликованной в комментариях пользователя user2651804 :

#flex-container {
  display: flex;
  flex-direction: column;
  background: teal;
  width: 150px;
  min-height: 80vh;
  justify-content: space-between;
}

#flex-container>div {
  background: orange;
  margin: 5px;
}

#flex-container>div:first-child {
  flex: 1;
}

#flex-container::after {
  content: "";
  flex: 1;
}
<div id="flex-container">
  <div>very long annoying text that will add on top of the height of its parent</div>
  <div>center</div>
</div>

Решение состоит в том, чтобы не использовать процентную единицу. Попробуйте px или просто ничего (, что действительно рекомендует спецификация , несмотря на то, что по крайней мере некоторые из основных браузеров приложили процентную единицу по любой причине).

#flex-container {
  display: flex;
  flex-direction: column;
  background: teal;
  width: 150px;
  min-height: 80vh;
  justify-content: space-between;
}

#flex-container > div {
  background: orange;
  margin: 5px;
}


/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */

#flex-container > div:first-child {
  flex: 1;
  flex-basis: 0;
}

#flex-container::after {
  content: "";
  flex: 1;
  flex-basis: 0;
}


/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY

#flex-container > div:first-child {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

#flex-container::after {
  content: "";
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}
 */
<div id="flex-container">
  <div>very long annoying text that will add on top of the height of its parent</div>
  <div>center</div>
</div>


Метод №5: Макет сетки CSS

Это может быть самый чистый и эффективный метод. Нет необходимости в абсолютном позиционировании, поддельных элементах или других хакерах.

Просто создайте сетку с несколькими столбцами. Затем разместите свои позиции в середине и в конце столбцов. В принципе, просто оставьте первый столбец пустым.

ul {
  display: grid;
  grid-template-columns: 1fr repeat(3, auto) 1fr;
  grid-column-gap: 5px;
  justify-items: center;
}

li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p  { text-align: center; }
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>| true center |</span></p>

70
ответ дан Michael_B 15 August 2018 в 22:26
поделиться
  • 1
    отличный ответ! Протестировано все 5 решений, и каждый из них жизнеспособен! – Mobiletainment 14 January 2018 в 19:15
  • 2
    У меня проблема с методом 4 при использовании min-width/min-height для моего гибкого контейнера. Дети flex: 1 такого родителя не получают равную ширину / высоту. В любом случае? – user2651804 26 March 2018 в 09:45
  • 3
    @ user2651804, я обновил свой ответ с обзором проблемы. См. Способ №4. – Michael_B 26 March 2018 в 22:09
  • 4
    Очень приятно, спасибо за объяснение! Я думаю, что недавно добавленные фрагменты кода выиграют от сокращения текста примера, поскольку на выходе не видно, что контент центрирован / не центрирован из-за небольшого окна просмотра. Только я? – user2651804 26 March 2018 в 22:30
  • 5
    Представление снизу по умолчанию несколько мало. Но в правом верхнем углу находится «Полный экран», который может быть полезен. Я думаю, что все в порядке, но не стесняйтесь редактировать, если хотите. @ user2651804 – Michael_B 26 March 2018 в 22:33
  • 6
    – small mammal 27 May 2018 в 22:35
  • 7

Очень четкий вопрос. Я не мог не опубликовать ответ после нескольких часов рытья. Мы могли бы решить это с помощью таблиц, табличных ячеек, абсолютных позиций, преобразований, но нам просто нужно было сделать это с помощью flexbox:)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/ ручка / BLorgd

2
ответ дан rgfx 15 August 2018 в 22:26
поделиться
  • 1
    Это не по-настоящему центрирует средние элементы, потому что это только влияет на оставшееся пространство, а не на цельное пространство. codepen.io/anon/pen/QKGrRk – Michael_B 20 September 2016 в 23:35
  • 2
    @Michael_B, ваше право не замечало этого, мое плохое. Вернемся к использованию абсолютных позиций :( Может быть, с вашим высоким репутацией вы должны установить щедрость, чтобы это разрешилось навсегда. Я бы сделал, но у меня очень низкий уровень репутации, даже ниже, теперь пытаюсь помочь вам. – rgfx 22 September 2016 в 18:29
  • 3
    Никакая щедрость не добавит нового поведения в модель flexbox, by Michael_B, данный ответ так же хорош, как сегодня .... – LGSon 16 May 2017 в 12:07